Mon, 14 Oct 2013 21:52:42 -0400
8026299: invokespecial gets ICCE when it should get AME.
Reviewed-by: ccheung, coleenp
src/share/vm/interpreter/linkResolver.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/interpreter/linkResolver.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/interpreter/linkResolver.cpp Sat Oct 12 15:39:16 2013 -0400 1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Mon Oct 14 21:52:42 2013 -0400 1.3 @@ -454,7 +454,7 @@ 1.4 Symbol* method_name = vmSymbols::invoke_name(); 1.5 Symbol* method_signature = pool->signature_ref_at(index); 1.6 KlassHandle current_klass(THREAD, pool->pool_holder()); 1.7 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 1.8 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); 1.9 return; 1.10 } 1.11 1.12 @@ -476,22 +476,34 @@ 1.13 1.14 if (code == Bytecodes::_invokeinterface) { 1.15 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 1.16 + } else if (code == Bytecodes::_invokevirtual) { 1.17 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); 1.18 } else { 1.19 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 1.20 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); 1.21 } 1.22 } 1.23 1.24 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, 1.25 Symbol* method_name, Symbol* method_signature, 1.26 - KlassHandle current_klass, bool check_access, TRAPS) { 1.27 + KlassHandle current_klass, bool check_access, 1.28 + bool require_methodref, TRAPS) { 1.29 1.30 Handle nested_exception; 1.31 1.32 - // 1. lookup method in resolved klass and its super klasses 1.33 + // 1. check if methodref required, that resolved_klass is not interfacemethodref 1.34 + if (require_methodref && resolved_klass->is_interface()) { 1.35 + ResourceMark rm(THREAD); 1.36 + char buf[200]; 1.37 + jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", 1.38 + resolved_klass()->external_name()); 1.39 + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1.40 + } 1.41 + 1.42 + // 2. lookup method in resolved klass and its super klasses 1.43 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 1.44 1.45 if (resolved_method.is_null()) { // not found in the class hierarchy 1.46 - // 2. lookup method in all the interfaces implemented by the resolved klass 1.47 + // 3. lookup method in all the interfaces implemented by the resolved klass 1.48 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); 1.49 1.50 if (resolved_method.is_null()) { 1.51 @@ -505,7 +517,7 @@ 1.52 } 1.53 1.54 if (resolved_method.is_null()) { 1.55 - // 3. method lookup failed 1.56 + // 4. method lookup failed 1.57 ResourceMark rm(THREAD); 1.58 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), 1.59 Method::name_and_sig_as_C_string(resolved_klass(), 1.60 @@ -515,15 +527,6 @@ 1.61 } 1.62 } 1.63 1.64 - // 4. check if klass is not interface 1.65 - if (resolved_klass->is_interface() && resolved_method->is_abstract()) { 1.66 - ResourceMark rm(THREAD); 1.67 - char buf[200]; 1.68 - jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", 1.69 - resolved_klass()->external_name()); 1.70 - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1.71 - } 1.72 - 1.73 // 5. check if method is concrete 1.74 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { 1.75 ResourceMark rm(THREAD); 1.76 @@ -833,7 +836,7 @@ 1.77 Symbol* method_name, Symbol* method_signature, 1.78 KlassHandle current_klass, bool check_access, TRAPS) { 1.79 1.80 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 1.81 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.82 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); 1.83 1.84 // check if static 1.85 @@ -867,7 +870,7 @@ 1.86 // and the selected method is recalculated relative to the direct superclass 1.87 // superinterface.method, which explicitly does not check shadowing 1.88 1.89 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 1.90 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); 1.91 1.92 // check if method name is <init>, that it is found in same klass as static type 1.93 if (resolved_method->name() == vmSymbols::object_initializer_name() && 1.94 @@ -1013,7 +1016,7 @@ 1.95 Symbol* method_name, Symbol* method_signature, 1.96 KlassHandle current_klass, bool check_access, TRAPS) { 1.97 // normal method resolution 1.98 - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 1.99 + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); 1.100 1.101 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); 1.102 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
2.1 --- a/src/share/vm/interpreter/linkResolver.hpp Sat Oct 12 15:39:16 2013 -0400 2.2 +++ b/src/share/vm/interpreter/linkResolver.hpp Mon Oct 14 21:52:42 2013 -0400 2.3 @@ -136,7 +136,7 @@ 2.4 static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); 2.5 2.6 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.7 - static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 2.8 + 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.9 2.10 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); 2.11 static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);