# HG changeset patch # User bharadwaj # Date 1366297535 25200 # Node ID 49cbeca23983e65193fa7ce20e40f5f5be838ebc # Parent 584161d608a5020b755d58d3996707128cf2c71c 8006267: InterfaceMethod_ref should allow invokestatic and invokespecial Summary: Lambda changes; spec 0.6.2 - Allow static invokestatic and invokespecial calls to InterfaceMethod_ref Reviewed-by: dholmes, acorn diff -r 584161d608a5 -r 49cbeca23983 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Apr 17 08:20:02 2013 -0400 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Apr 18 08:05:35 2013 -0700 @@ -436,14 +436,19 @@ ref_index, CHECK_(nullHandle)); break; case JVM_REF_invokeVirtual: - case JVM_REF_invokeStatic: - case JVM_REF_invokeSpecial: case JVM_REF_newInvokeSpecial: check_property( tag.is_method(), "Invalid constant pool index %u in class file %s (not a method)", ref_index, CHECK_(nullHandle)); break; + case JVM_REF_invokeStatic: + case JVM_REF_invokeSpecial: + check_property( + tag.is_method() || tag.is_interface_method(), + "Invalid constant pool index %u in class file %s (not a method)", + ref_index, CHECK_(nullHandle)); + break; case JVM_REF_invokeInterface: check_property( tag.is_interface_method(), @@ -3837,7 +3842,7 @@ } if (TraceClassLoadingPreorder) { - tty->print("[Loading %s", name->as_klass_external_name()); + tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName"); if (cfs->source() != NULL) tty->print(" from %s", cfs->source()); tty->print_cr("]"); } diff -r 584161d608a5 -r 49cbeca23983 hotspot/src/share/vm/classfile/genericSignatures.cpp --- a/hotspot/src/share/vm/classfile/genericSignatures.cpp Wed Apr 17 08:20:02 2013 -0400 +++ b/hotspot/src/share/vm/classfile/genericSignatures.cpp Thu Apr 18 08:05:35 2013 -0700 @@ -268,8 +268,15 @@ Klass* outer = SystemDictionary::find( outer_name, class_loader, protection_domain, CHECK_NULL); if (outer == NULL && !THREAD->is_Compiler_thread()) { - outer = SystemDictionary::resolve_super_or_fail(original_name, - outer_name, class_loader, protection_domain, false, CHECK_NULL); + if (outer_name == ik->super()->name()) { + outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name, + class_loader, protection_domain, + false, CHECK_NULL); + } + else { + outer = SystemDictionary::resolve_or_fail(outer_name, class_loader, + protection_domain, false, CHECK_NULL); + } } InstanceKlass* outer_ik; diff -r 584161d608a5 -r 49cbeca23983 hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Apr 17 08:20:02 2013 -0400 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Apr 18 08:05:35 2013 -0700 @@ -1014,13 +1014,28 @@ resolved_method->name(), resolved_method->signature())); } - // check if public - if (!sel_method->is_public()) { - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), - Method::name_and_sig_as_C_string(recv_klass(), - sel_method->name(), - sel_method->signature())); + // check access + if (sel_method->method_holder()->is_interface()) { + // Method holder is an interface. Throw Illegal Access Error if sel_method + // is neither public nor private. + if (!(sel_method->is_public() || sel_method->is_private())) { + ResourceMark rm(THREAD); + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), + Method::name_and_sig_as_C_string(recv_klass(), + sel_method->name(), + sel_method->signature())); + } + } + else { + // Method holder is a class. Throw Illegal Access Error if sel_method + // is not public. + if (!sel_method->is_public()) { + ResourceMark rm(THREAD); + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), + Method::name_and_sig_as_C_string(recv_klass(), + sel_method->name(), + sel_method->signature())); + } } // check if abstract if (check_null_and_abstract && sel_method->is_abstract()) { diff -r 584161d608a5 -r 49cbeca23983 hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Wed Apr 17 08:20:02 2013 -0400 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Apr 18 08:05:35 2013 -0700 @@ -187,6 +187,11 @@ flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); } else if (mods.is_static()) { flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); + // Check if this method is a lambda method that is generated as + // private static method. + if (m->is_private() && m->method_holder()->is_interface()) { + vmindex = klassItable::compute_itable_index(m); + } } else if (receiver_limit != mklass && !receiver_limit->is_subtype_of(mklass)) { return NULL; // bad receiver limit