Tue, 03 Dec 2013 08:36:15 -0800
8026066: ICCE for invokeinterface static
Reviewed-by: coleenp, lfoltan, hseigel
1.1 --- a/src/share/vm/interpreter/linkResolver.cpp Mon Dec 02 11:42:10 2013 +0100 1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Tue Dec 03 08:36:15 2013 -0800 1.3 @@ -242,7 +242,7 @@ 1.4 1.5 // Look up method in klasses, including static methods 1.6 // Then look up local default methods 1.7 -void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 1.8 +void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) { 1.9 Method* result_oop = klass->uncached_lookup_method(name, signature); 1.10 if (result_oop == NULL) { 1.11 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); 1.12 @@ -251,7 +251,7 @@ 1.13 } 1.14 } 1.15 1.16 - if (EnableInvokeDynamic && result_oop != NULL) { 1.17 + if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) { 1.18 vmIntrinsics::ID iid = result_oop->intrinsic_id(); 1.19 if (MethodHandles::is_signature_polymorphic(iid)) { 1.20 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. 1.21 @@ -503,11 +503,14 @@ 1.22 } 1.23 1.24 if (code == Bytecodes::_invokeinterface) { 1.25 - resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 1.26 + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); 1.27 } else if (code == Bytecodes::_invokevirtual) { 1.28 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); 1.29 + } else if (!resolved_klass->is_interface()) { 1.30 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); 1.31 } else { 1.32 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); 1.33 + bool nostatics = (code == Bytecodes::_invokestatic) ? false : true; 1.34 + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK); 1.35 } 1.36 } 1.37 1.38 @@ -528,7 +531,7 @@ 1.39 } 1.40 1.41 // 2. lookup method in resolved klass and its super klasses 1.42 - lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 1.43 + lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK); 1.44 1.45 if (resolved_method.is_null()) { // not found in the class hierarchy 1.46 // 3. lookup method in all the interfaces implemented by the resolved klass 1.47 @@ -612,7 +615,8 @@ 1.48 Symbol* method_name, 1.49 Symbol* method_signature, 1.50 KlassHandle current_klass, 1.51 - bool check_access, TRAPS) { 1.52 + bool check_access, 1.53 + bool nostatics, TRAPS) { 1.54 1.55 // check if klass is interface 1.56 if (!resolved_klass->is_interface()) { 1.57 @@ -623,7 +627,8 @@ 1.58 } 1.59 1.60 // lookup method in this interface or its super, java.lang.Object 1.61 - lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 1.62 + // JDK8: also look for static methods 1.63 + lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK); 1.64 1.65 if (resolved_method.is_null()) { 1.66 // lookup method in all the super-interfaces 1.67 @@ -638,6 +643,16 @@ 1.68 } 1.69 } 1.70 1.71 + if (nostatics && resolved_method->is_static()) { 1.72 + ResourceMark rm(THREAD); 1.73 + char buf[200]; 1.74 + jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(), 1.75 + resolved_method->name(), 1.76 + resolved_method->signature())); 1.77 + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1.78 + } 1.79 + 1.80 + 1.81 if (check_access) { 1.82 // JDK8 adds non-public interface methods, and accessability check requirement 1.83 assert(current_klass.not_null() , "current_klass should not be null"); 1.84 @@ -864,7 +879,11 @@ 1.85 Symbol* method_name, Symbol* method_signature, 1.86 KlassHandle current_klass, bool check_access, TRAPS) { 1.87 1.88 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.89 + if (!resolved_klass->is_interface()) { 1.90 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.91 + } else { 1.92 + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.93 + } 1.94 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); 1.95 1.96 // check if static 1.97 @@ -898,7 +917,11 @@ 1.98 // and the selected method is recalculated relative to the direct superclass 1.99 // superinterface.method, which explicitly does not check shadowing 1.100 1.101 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.102 + if (!resolved_klass->is_interface()) { 1.103 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.104 + } else { 1.105 + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); 1.106 + } 1.107 1.108 // check if method name is <init>, that it is found in same klass as static type 1.109 if (resolved_method->name() == vmSymbols::object_initializer_name() && 1.110 @@ -1219,7 +1242,7 @@ 1.111 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, 1.112 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { 1.113 // normal interface method resolution 1.114 - resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 1.115 + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); 1.116 1.117 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); 1.118 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
2.1 --- a/src/share/vm/interpreter/linkResolver.hpp Mon Dec 02 11:42:10 2013 +0100 2.2 +++ b/src/share/vm/interpreter/linkResolver.hpp Tue Dec 03 08:36:15 2013 -0800 2.3 @@ -124,7 +124,7 @@ 2.4 friend class klassItable; 2.5 2.6 private: 2.7 - static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 2.8 + static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS); 2.9 static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 2.10 static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 2.11 static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, 2.12 @@ -134,7 +134,7 @@ 2.13 2.14 static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); 2.15 2.16 - static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 2.17 + static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS); 2.18 static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS); 2.19 2.20 static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
3.1 --- a/test/TEST.groups Mon Dec 02 11:42:10 2013 +0100 3.2 +++ b/test/TEST.groups Tue Dec 03 08:36:15 2013 -0800 3.3 @@ -70,7 +70,6 @@ 3.4 runtime/7107135/Test7107135.sh \ 3.5 runtime/7158988/FieldMonitor.java \ 3.6 runtime/7194254/Test7194254.java \ 3.7 - runtime/8026365/InvokeSpecialAnonTest.java \ 3.8 runtime/jsig/Test8017498.sh \ 3.9 runtime/Metaspace/FragmentMetaspace.java \ 3.10 runtime/NMT/BaselineWithParameter.java \
4.1 --- a/test/runtime/8024804/RegisterNatives.java Mon Dec 02 11:42:10 2013 +0100 4.2 +++ b/test/runtime/8024804/RegisterNatives.java Tue Dec 03 08:36:15 2013 -0800 4.3 @@ -22,6 +22,7 @@ 4.4 */ 4.5 4.6 /* 4.7 + * @ignore 8028741 4.8 * @test 4.9 * @bug 8024804 4.10 * @summary registerNatives() interface resolution should receive IAE