1.1 --- a/src/share/vm/prims/methodHandles.cpp Tue Sep 17 23:12:27 2013 +0200 1.2 +++ b/src/share/vm/prims/methodHandles.cpp Fri Sep 13 22:38:02 2013 -0400 1.3 @@ -127,25 +127,37 @@ 1.4 } 1.5 1.6 oop MethodHandles::init_MemberName(Handle mname, Handle target) { 1.7 + // This method is used from java.lang.invoke.MemberName constructors. 1.8 + // It fills in the new MemberName from a java.lang.reflect.Member. 1.9 Thread* thread = Thread::current(); 1.10 oop target_oop = target(); 1.11 Klass* target_klass = target_oop->klass(); 1.12 if (target_klass == SystemDictionary::reflect_Field_klass()) { 1.13 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() 1.14 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() 1.15 - int mods = java_lang_reflect_Field::modifiers(target_oop); 1.16 - oop type = java_lang_reflect_Field::type(target_oop); 1.17 - oop name = java_lang_reflect_Field::name(target_oop); 1.18 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.19 - intptr_t offset = InstanceKlass::cast(k())->field_offset(slot); 1.20 - return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset); 1.21 + if (!k.is_null() && k->oop_is_instance()) { 1.22 + fieldDescriptor fd(InstanceKlass::cast(k()), slot); 1.23 + oop mname2 = init_field_MemberName(mname, fd); 1.24 + if (mname2 != NULL) { 1.25 + // Since we have the reified name and type handy, add them to the result. 1.26 + if (java_lang_invoke_MemberName::name(mname2) == NULL) 1.27 + java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); 1.28 + if (java_lang_invoke_MemberName::type(mname2) == NULL) 1.29 + java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop)); 1.30 + } 1.31 + return mname2; 1.32 + } 1.33 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { 1.34 oop clazz = java_lang_reflect_Method::clazz(target_oop); 1.35 int slot = java_lang_reflect_Method::slot(target_oop); 1.36 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.37 if (!k.is_null() && k->oop_is_instance()) { 1.38 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); 1.39 - return init_method_MemberName(mname, m, true, k); 1.40 + if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) 1.41 + return NULL; // do not resolve unless there is a concrete signature 1.42 + CallInfo info(m, k()); 1.43 + return init_method_MemberName(mname, info); 1.44 } 1.45 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { 1.46 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); 1.47 @@ -153,65 +165,50 @@ 1.48 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.49 if (!k.is_null() && k->oop_is_instance()) { 1.50 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); 1.51 - return init_method_MemberName(mname, m, false, k); 1.52 - } 1.53 - } else if (target_klass == SystemDictionary::MemberName_klass()) { 1.54 - // Note: This only works if the MemberName has already been resolved. 1.55 - oop clazz = java_lang_invoke_MemberName::clazz(target_oop); 1.56 - int flags = java_lang_invoke_MemberName::flags(target_oop); 1.57 - Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop); 1.58 - intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop); 1.59 - KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.60 - int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; 1.61 - if (vmtarget == NULL) return NULL; // not resolved 1.62 - if ((flags & IS_FIELD) != 0) { 1.63 - assert(vmtarget->is_klass(), "field vmtarget is Klass*"); 1.64 - int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0); 1.65 - // FIXME: how does k (receiver_limit) contribute? 1.66 - KlassHandle k_vmtarget(thread, (Klass*)vmtarget); 1.67 - return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex); 1.68 - } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { 1.69 - assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); 1.70 - return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k); 1.71 - } else { 1.72 - return NULL; 1.73 + if (m == NULL) return NULL; 1.74 + CallInfo info(m, k()); 1.75 + return init_method_MemberName(mname, info); 1.76 } 1.77 } 1.78 return NULL; 1.79 } 1.80 1.81 -oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch, 1.82 - KlassHandle receiver_limit_h) { 1.83 - Klass* receiver_limit = receiver_limit_h(); 1.84 - AccessFlags mods = m->access_flags(); 1.85 - int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); 1.86 - int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch 1.87 - Klass* mklass = m->method_holder(); 1.88 - if (receiver_limit == NULL) 1.89 - receiver_limit = mklass; 1.90 - if (m->is_initializer()) { 1.91 - flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.92 - } else if (mods.is_static()) { 1.93 - flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); 1.94 - } else if (receiver_limit != mklass && 1.95 - !receiver_limit->is_subtype_of(mklass)) { 1.96 - return NULL; // bad receiver limit 1.97 - } else if (do_dispatch && receiver_limit->is_interface() && 1.98 - mklass->is_interface()) { 1.99 +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { 1.100 + assert(info.resolved_appendix().is_null(), "only normal methods here"); 1.101 + KlassHandle receiver_limit = info.resolved_klass(); 1.102 + methodHandle m = info.resolved_method(); 1.103 + int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); 1.104 + int vmindex = Method::invalid_vtable_index; 1.105 + 1.106 + switch (info.call_kind()) { 1.107 + case CallInfo::itable_call: 1.108 + vmindex = info.itable_index(); 1.109 + // More importantly, the itable index only works with the method holder. 1.110 + receiver_limit = m->method_holder(); 1.111 + assert(receiver_limit->verify_itable_index(vmindex), ""); 1.112 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); 1.113 - receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible 1.114 - vmindex = klassItable::compute_itable_index(m); 1.115 - } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) { 1.116 + break; 1.117 + 1.118 + case CallInfo::vtable_call: 1.119 + vmindex = info.vtable_index(); 1.120 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); 1.121 - // it is a miranda method, so m->vtable_index is not what we want 1.122 - ResourceMark rm; 1.123 - klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable(); 1.124 - vmindex = vt->index_of_miranda(m->name(), m->signature()); 1.125 - } else if (!do_dispatch || m->can_be_statically_bound()) { 1.126 - flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.127 - } else { 1.128 - flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); 1.129 - vmindex = m->vtable_index(); 1.130 + assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe"); 1.131 + break; 1.132 + 1.133 + case CallInfo::direct_call: 1.134 + vmindex = Method::nonvirtual_vtable_index; 1.135 + if (m->is_static()) { 1.136 + flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); 1.137 + } else if (m->is_initializer()) { 1.138 + flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.139 + assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed"); 1.140 + } else { 1.141 + flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.142 + assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe"); 1.143 + } 1.144 + break; 1.145 + 1.146 + default: assert(false, "bad CallInfo"); return NULL; 1.147 } 1.148 1.149 // @CallerSensitive annotation detected 1.150 @@ -221,7 +218,7 @@ 1.151 1.152 oop mname_oop = mname(); 1.153 java_lang_invoke_MemberName::set_flags( mname_oop, flags); 1.154 - java_lang_invoke_MemberName::set_vmtarget(mname_oop, m); 1.155 + java_lang_invoke_MemberName::set_vmtarget(mname_oop, m()); 1.156 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index 1.157 java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); 1.158 // Note: name and type can be lazily computed by resolve_MemberName, 1.159 @@ -237,59 +234,19 @@ 1.160 return mname(); 1.161 } 1.162 1.163 -Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) { 1.164 - Handle empty; 1.165 - if (info.resolved_appendix().not_null()) { 1.166 - // The resolved MemberName must not be accompanied by an appendix argument, 1.167 - // since there is no way to bind this value into the MemberName. 1.168 - // Caller is responsible to prevent this from happening. 1.169 - THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); 1.170 - } 1.171 - methodHandle m = info.resolved_method(); 1.172 - KlassHandle defc = info.resolved_klass(); 1.173 - int vmindex = Method::invalid_vtable_index; 1.174 - if (defc->is_interface() && m->method_holder()->is_interface()) { 1.175 - // static interface methods do not reference vtable or itable 1.176 - if (m->is_static()) { 1.177 - vmindex = Method::nonvirtual_vtable_index; 1.178 - } 1.179 - // interface methods invoked via invokespecial also 1.180 - // do not reference vtable or itable. 1.181 - int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >> 1.182 - REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK); 1.183 - if (ref_kind == JVM_REF_invokeSpecial) { 1.184 - vmindex = Method::nonvirtual_vtable_index; 1.185 - } 1.186 - // If neither m is static nor ref_kind is invokespecial, 1.187 - // set it to itable index. 1.188 - if (vmindex == Method::invalid_vtable_index) { 1.189 - // LinkResolver does not report itable indexes! (fix this?) 1.190 - vmindex = klassItable::compute_itable_index(m()); 1.191 - } 1.192 - } else if (m->can_be_statically_bound()) { 1.193 - // LinkResolver reports vtable index even for final methods! 1.194 - vmindex = Method::nonvirtual_vtable_index; 1.195 - } else { 1.196 - vmindex = info.vtable_index(); 1.197 - } 1.198 - oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc()); 1.199 - assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), ""); 1.200 - return Handle(THREAD, res); 1.201 -} 1.202 - 1.203 -oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, 1.204 - AccessFlags mods, oop type, oop name, 1.205 - intptr_t offset, bool is_setter) { 1.206 - int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); 1.207 - flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); 1.208 +oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { 1.209 + int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); 1.210 + flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); 1.211 if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); 1.212 - Metadata* vmtarget = field_holder(); 1.213 - int vmindex = offset; // determines the field uniquely when combined with static bit 1.214 + Metadata* vmtarget = fd.field_holder(); 1.215 + int vmindex = fd.offset(); // determines the field uniquely when combined with static bit 1.216 oop mname_oop = mname(); 1.217 java_lang_invoke_MemberName::set_flags(mname_oop, flags); 1.218 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); 1.219 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); 1.220 - java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror()); 1.221 + java_lang_invoke_MemberName::set_clazz(mname_oop, fd.field_holder()->java_mirror()); 1.222 + oop type = field_signature_type_or_null(fd.signature()); 1.223 + oop name = field_name_or_null(fd.name()); 1.224 if (name != NULL) 1.225 java_lang_invoke_MemberName::set_name(mname_oop, name); 1.226 if (type != NULL) 1.227 @@ -305,19 +262,6 @@ 1.228 return mname(); 1.229 } 1.230 1.231 -Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) { 1.232 - return Handle(); 1.233 -#if 0 // FIXME 1.234 - KlassHandle field_holder = info.klass(); 1.235 - intptr_t field_offset = info.field_offset(); 1.236 - return init_field_MemberName(mname_oop, field_holder(), 1.237 - info.access_flags(), 1.238 - type, name, 1.239 - field_offset, false /*is_setter*/); 1.240 -#endif 1.241 -} 1.242 - 1.243 - 1.244 // JVM 2.9 Special Methods: 1.245 // A method is signature polymorphic if and only if all of the following conditions hold : 1.246 // * It is declared in the java.lang.invoke.MethodHandle class. 1.247 @@ -573,12 +517,12 @@ 1.248 return SystemDictionary::Object_klass()->java_mirror(); 1.249 } 1.250 1.251 -static oop field_name_or_null(Symbol* s) { 1.252 +oop MethodHandles::field_name_or_null(Symbol* s) { 1.253 if (s == NULL) return NULL; 1.254 return StringTable::lookup(s); 1.255 } 1.256 1.257 -static oop field_signature_type_or_null(Symbol* s) { 1.258 +oop MethodHandles::field_signature_type_or_null(Symbol* s) { 1.259 if (s == NULL) return NULL; 1.260 BasicType bt = FieldType::basic_type(s); 1.261 if (is_java_primitive(bt)) { 1.262 @@ -701,7 +645,14 @@ 1.263 return empty; 1.264 } 1.265 } 1.266 - return init_method_MemberName(mname, result, THREAD); 1.267 + if (result.resolved_appendix().not_null()) { 1.268 + // The resolved MemberName must not be accompanied by an appendix argument, 1.269 + // since there is no way to bind this value into the MemberName. 1.270 + // Caller is responsible to prevent this from happening. 1.271 + THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); 1.272 + } 1.273 + oop mname2 = init_method_MemberName(mname, result); 1.274 + return Handle(THREAD, mname2); 1.275 } 1.276 case IS_CONSTRUCTOR: 1.277 { 1.278 @@ -719,22 +670,21 @@ 1.279 } 1.280 } 1.281 assert(result.is_statically_bound(), ""); 1.282 - return init_method_MemberName(mname, result, THREAD); 1.283 + oop mname2 = init_method_MemberName(mname, result); 1.284 + return Handle(THREAD, mname2); 1.285 } 1.286 case IS_FIELD: 1.287 { 1.288 - // This is taken from LinkResolver::resolve_field, sans access checks. 1.289 - fieldDescriptor fd; // find_field initializes fd if found 1.290 - KlassHandle sel_klass(THREAD, InstanceKlass::cast(defc())->find_field(name, type, &fd)); 1.291 - // check if field exists; i.e., if a klass containing the field def has been selected 1.292 - if (sel_klass.is_null()) return empty; // should not happen 1.293 - oop type = field_signature_type_or_null(fd.signature()); 1.294 - oop name = field_name_or_null(fd.name()); 1.295 - bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind)); 1.296 - mname = Handle(THREAD, 1.297 - init_field_MemberName(mname, sel_klass, 1.298 - fd.access_flags(), type, name, fd.offset(), is_setter)); 1.299 - return mname; 1.300 + fieldDescriptor result; // find_field initializes fd if found 1.301 + { 1.302 + assert(!HAS_PENDING_EXCEPTION, ""); 1.303 + LinkResolver::resolve_field(result, defc, name, type, KlassHandle(), Bytecodes::_nop, false, false, THREAD); 1.304 + if (HAS_PENDING_EXCEPTION) { 1.305 + return empty; 1.306 + } 1.307 + } 1.308 + oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind)); 1.309 + return Handle(THREAD, mname2); 1.310 } 1.311 default: 1.312 THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty); 1.313 @@ -793,7 +743,6 @@ 1.314 } 1.315 case IS_FIELD: 1.316 { 1.317 - // This is taken from LinkResolver::resolve_field, sans access checks. 1.318 assert(vmtarget->is_klass(), "field vmtarget is Klass*"); 1.319 if (!((Klass*) vmtarget)->oop_is_instance()) break; 1.320 instanceKlassHandle defc(THREAD, (Klass*) vmtarget); 1.321 @@ -872,11 +821,7 @@ 1.322 Handle result(thread, results->obj_at(rfill++)); 1.323 if (!java_lang_invoke_MemberName::is_instance(result())) 1.324 return -99; // caller bug! 1.325 - oop type = field_signature_type_or_null(st.signature()); 1.326 - oop name = field_name_or_null(st.name()); 1.327 - oop saved = MethodHandles::init_field_MemberName(result, st.klass(), 1.328 - st.access_flags(), type, name, 1.329 - st.offset()); 1.330 + oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor()); 1.331 if (saved != result()) 1.332 results->obj_at_put(rfill-1, saved); // show saved instance to user 1.333 } else if (++overflow >= overflow_limit) { 1.334 @@ -926,7 +871,8 @@ 1.335 Handle result(thread, results->obj_at(rfill++)); 1.336 if (!java_lang_invoke_MemberName::is_instance(result())) 1.337 return -99; // caller bug! 1.338 - oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL); 1.339 + CallInfo info(m); 1.340 + oop saved = MethodHandles::init_method_MemberName(result, info); 1.341 if (saved != result()) 1.342 results->obj_at_put(rfill-1, saved); // show saved instance to user 1.343 } else if (++overflow >= overflow_limit) { 1.344 @@ -1227,7 +1173,8 @@ 1.345 x = ((Klass*) vmtarget)->java_mirror(); 1.346 } else if (vmtarget->is_method()) { 1.347 Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL); 1.348 - x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL); 1.349 + CallInfo info((Method*)vmtarget); 1.350 + x = MethodHandles::init_method_MemberName(mname2, info); 1.351 } 1.352 result->obj_at_put(1, x); 1.353 return JNIHandles::make_local(env, result());