1.1 --- a/src/share/vm/prims/methodHandles.cpp Thu Dec 05 16:37:29 2013 +0400 1.2 +++ b/src/share/vm/prims/methodHandles.cpp Thu Dec 05 00:36:42 2013 -0800 1.3 @@ -175,8 +175,8 @@ 1.4 1.5 oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { 1.6 assert(info.resolved_appendix().is_null(), "only normal methods here"); 1.7 - KlassHandle receiver_limit = info.resolved_klass(); 1.8 methodHandle m = info.resolved_method(); 1.9 + KlassHandle m_klass = m->method_holder(); 1.10 int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); 1.11 int vmindex = Method::invalid_vtable_index; 1.12 1.13 @@ -184,14 +184,13 @@ 1.14 case CallInfo::itable_call: 1.15 vmindex = info.itable_index(); 1.16 // More importantly, the itable index only works with the method holder. 1.17 - receiver_limit = m->method_holder(); 1.18 - assert(receiver_limit->verify_itable_index(vmindex), ""); 1.19 + assert(m_klass->verify_itable_index(vmindex), ""); 1.20 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); 1.21 if (TraceInvokeDynamic) { 1.22 ResourceMark rm; 1.23 - tty->print_cr("memberName: invokeinterface method_holder::method: %s, receiver: %s, itableindex: %d, access_flags:", 1.24 - Method::name_and_sig_as_C_string(receiver_limit(), m->name(), m->signature()), 1.25 - receiver_limit()->internal_name(), vmindex); 1.26 + tty->print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:", 1.27 + Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()), 1.28 + vmindex); 1.29 m->access_flags().print_on(tty); 1.30 if (!m->is_abstract()) { 1.31 tty->print("default"); 1.32 @@ -203,12 +202,35 @@ 1.33 case CallInfo::vtable_call: 1.34 vmindex = info.vtable_index(); 1.35 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); 1.36 - assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe"); 1.37 + assert(info.resolved_klass()->is_subtype_of(m_klass()), "virtual call must be type-safe"); 1.38 + if (m_klass->is_interface()) { 1.39 + // This is a vtable call to an interface method (abstract "miranda method" or default method). 1.40 + // The vtable index is meaningless without a class (not interface) receiver type, so get one. 1.41 + // (LinkResolver should help us figure this out.) 1.42 + KlassHandle m_klass_non_interface = info.resolved_klass(); 1.43 + if (m_klass_non_interface->is_interface()) { 1.44 + m_klass_non_interface = SystemDictionary::Object_klass(); 1.45 +#ifdef ASSERT 1.46 + { ResourceMark rm; 1.47 + Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex); 1.48 + assert(m->name() == m2->name() && m->signature() == m2->signature(), 1.49 + err_msg("at %d, %s != %s", vmindex, 1.50 + m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string())); 1.51 + } 1.52 +#endif //ASSERT 1.53 + } 1.54 + if (!m->is_public()) { 1.55 + assert(m->is_public(), "virtual call must be to public interface method"); 1.56 + return NULL; // elicit an error later in product build 1.57 + } 1.58 + assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface()), "virtual call must be type-safe"); 1.59 + m_klass = m_klass_non_interface; 1.60 + } 1.61 if (TraceInvokeDynamic) { 1.62 ResourceMark rm; 1.63 tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:", 1.64 - Method::name_and_sig_as_C_string(receiver_limit(), m->name(), m->signature()), 1.65 - receiver_limit()->internal_name(), vmindex); 1.66 + Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()), 1.67 + m_klass->internal_name(), vmindex); 1.68 m->access_flags().print_on(tty); 1.69 if (m->is_default_method()) { 1.70 tty->print("default"); 1.71 @@ -223,10 +245,8 @@ 1.72 flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); 1.73 } else if (m->is_initializer()) { 1.74 flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.75 - assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed"); 1.76 } else { 1.77 flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.78 - assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe"); 1.79 } 1.80 break; 1.81 1.82 @@ -242,7 +262,7 @@ 1.83 java_lang_invoke_MemberName::set_flags( mname_oop, flags); 1.84 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m()); 1.85 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index 1.86 - java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); 1.87 + java_lang_invoke_MemberName::set_clazz( mname_oop, m_klass->java_mirror()); 1.88 // Note: name and type can be lazily computed by resolve_MemberName, 1.89 // if Java code needs them as resolved String and MethodType objects. 1.90 // The clazz must be eagerly stored, because it provides a GC 1.91 @@ -569,7 +589,7 @@ 1.92 // An unresolved member name is a mere symbolic reference. 1.93 // Resolving it plants a vmtarget/vmindex in it, 1.94 // which refers directly to JVM internals. 1.95 -Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) { 1.96 +Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS) { 1.97 Handle empty; 1.98 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); 1.99 1.100 @@ -646,20 +666,20 @@ 1.101 assert(!HAS_PENDING_EXCEPTION, ""); 1.102 if (ref_kind == JVM_REF_invokeStatic) { 1.103 LinkResolver::resolve_static_call(result, 1.104 - defc, name, type, KlassHandle(), false, false, THREAD); 1.105 + defc, name, type, caller, caller.not_null(), false, THREAD); 1.106 } else if (ref_kind == JVM_REF_invokeInterface) { 1.107 LinkResolver::resolve_interface_call(result, Handle(), defc, 1.108 - defc, name, type, KlassHandle(), false, false, THREAD); 1.109 + defc, name, type, caller, caller.not_null(), false, THREAD); 1.110 } else if (mh_invoke_id != vmIntrinsics::_none) { 1.111 assert(!is_signature_polymorphic_static(mh_invoke_id), ""); 1.112 LinkResolver::resolve_handle_call(result, 1.113 - defc, name, type, KlassHandle(), THREAD); 1.114 + defc, name, type, caller, THREAD); 1.115 } else if (ref_kind == JVM_REF_invokeSpecial) { 1.116 LinkResolver::resolve_special_call(result, 1.117 - defc, name, type, KlassHandle(), false, THREAD); 1.118 + defc, name, type, caller, caller.not_null(), THREAD); 1.119 } else if (ref_kind == JVM_REF_invokeVirtual) { 1.120 LinkResolver::resolve_virtual_call(result, Handle(), defc, 1.121 - defc, name, type, KlassHandle(), false, false, THREAD); 1.122 + defc, name, type, caller, caller.not_null(), false, THREAD); 1.123 } else { 1.124 assert(false, err_msg("ref_kind=%d", ref_kind)); 1.125 } 1.126 @@ -683,7 +703,7 @@ 1.127 assert(!HAS_PENDING_EXCEPTION, ""); 1.128 if (name == vmSymbols::object_initializer_name()) { 1.129 LinkResolver::resolve_special_call(result, 1.130 - defc, name, type, KlassHandle(), false, THREAD); 1.131 + defc, name, type, caller, caller.not_null(), THREAD); 1.132 } else { 1.133 break; // will throw after end of switch 1.134 } 1.135 @@ -700,7 +720,7 @@ 1.136 fieldDescriptor result; // find_field initializes fd if found 1.137 { 1.138 assert(!HAS_PENDING_EXCEPTION, ""); 1.139 - LinkResolver::resolve_field(result, defc, name, type, KlassHandle(), Bytecodes::_nop, false, false, THREAD); 1.140 + LinkResolver::resolve_field(result, defc, name, type, caller, Bytecodes::_nop, false, false, THREAD); 1.141 if (HAS_PENDING_EXCEPTION) { 1.142 return empty; 1.143 } 1.144 @@ -1121,7 +1141,11 @@ 1.145 } 1.146 } 1.147 1.148 - Handle resolved = MethodHandles::resolve_MemberName(mname, CHECK_NULL); 1.149 + KlassHandle caller(THREAD, 1.150 + caller_jh == NULL ? (Klass*) NULL : 1.151 + java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh))); 1.152 + Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL); 1.153 + 1.154 if (resolved.is_null()) { 1.155 int flags = java_lang_invoke_MemberName::flags(mname()); 1.156 int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;