提交 7e476f9e 编写于 作者: A acorn

8026066: ICCE for invokeinterface static

Reviewed-by: coleenp, lfoltan, hseigel
上级 4315d18b
...@@ -242,7 +242,7 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i ...@@ -242,7 +242,7 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i
// Look up method in klasses, including static methods // Look up method in klasses, including static methods
// Then look up local default methods // Then look up local default methods
void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) {
Method* result_oop = klass->uncached_lookup_method(name, signature); Method* result_oop = klass->uncached_lookup_method(name, signature);
if (result_oop == NULL) { if (result_oop == NULL) {
Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
...@@ -251,7 +251,7 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl ...@@ -251,7 +251,7 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl
} }
} }
if (EnableInvokeDynamic && result_oop != NULL) { if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
vmIntrinsics::ID iid = result_oop->intrinsic_id(); vmIntrinsics::ID iid = result_oop->intrinsic_id();
if (MethodHandles::is_signature_polymorphic(iid)) { if (MethodHandles::is_signature_polymorphic(iid)) {
// Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
...@@ -503,11 +503,14 @@ void LinkResolver::resolve_method_statically(methodHandle& resolved_method, Klas ...@@ -503,11 +503,14 @@ void LinkResolver::resolve_method_statically(methodHandle& resolved_method, Klas
} }
if (code == Bytecodes::_invokeinterface) { if (code == Bytecodes::_invokeinterface) {
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
} else if (code == Bytecodes::_invokevirtual) { } else if (code == Bytecodes::_invokevirtual) {
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
} else { } else if (!resolved_klass->is_interface()) {
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
} else {
bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK);
} }
} }
...@@ -528,7 +531,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res ...@@ -528,7 +531,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
} }
// 2. lookup method in resolved klass and its super klasses // 2. lookup method in resolved klass and its super klasses
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
if (resolved_method.is_null()) { // not found in the class hierarchy if (resolved_method.is_null()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass // 3. lookup method in all the interfaces implemented by the resolved klass
...@@ -612,7 +615,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, ...@@ -612,7 +615,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
Symbol* method_name, Symbol* method_name,
Symbol* method_signature, Symbol* method_signature,
KlassHandle current_klass, KlassHandle current_klass,
bool check_access, TRAPS) { bool check_access,
bool nostatics, TRAPS) {
// check if klass is interface // check if klass is interface
if (!resolved_klass->is_interface()) { if (!resolved_klass->is_interface()) {
...@@ -623,7 +627,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, ...@@ -623,7 +627,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
} }
// lookup method in this interface or its super, java.lang.Object // lookup method in this interface or its super, java.lang.Object
lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); // JDK8: also look for static methods
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
if (resolved_method.is_null()) { if (resolved_method.is_null()) {
// lookup method in all the super-interfaces // lookup method in all the super-interfaces
...@@ -638,6 +643,16 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, ...@@ -638,6 +643,16 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
} }
} }
if (nostatics && resolved_method->is_static()) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
if (check_access) { if (check_access) {
// JDK8 adds non-public interface methods, and accessability check requirement // JDK8 adds non-public interface methods, and accessability check requirement
assert(current_klass.not_null() , "current_klass should not be null"); assert(current_klass.not_null() , "current_klass should not be null");
...@@ -864,7 +879,11 @@ void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, ...@@ -864,7 +879,11 @@ void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method,
Symbol* method_name, Symbol* method_signature, Symbol* method_name, Symbol* method_signature,
KlassHandle current_klass, bool check_access, TRAPS) { KlassHandle current_klass, bool check_access, TRAPS) {
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); if (!resolved_klass->is_interface()) {
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
} else {
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
}
assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
// check if static // check if static
...@@ -898,7 +917,11 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method ...@@ -898,7 +917,11 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
// and the selected method is recalculated relative to the direct superclass // and the selected method is recalculated relative to the direct superclass
// superinterface.method, which explicitly does not check shadowing // superinterface.method, which explicitly does not check shadowing
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); if (!resolved_klass->is_interface()) {
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
} else {
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
}
// check if method name is <init>, that it is found in same klass as static type // check if method name is <init>, that it is found in same klass as static type
if (resolved_method->name() == vmSymbols::object_initializer_name() && if (resolved_method->name() == vmSymbols::object_initializer_name() &&
...@@ -1219,7 +1242,7 @@ void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHa ...@@ -1219,7 +1242,7 @@ void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHa
void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
// normal interface method resolution // normal interface method resolution
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
......
...@@ -124,7 +124,7 @@ class LinkResolver: AllStatic { ...@@ -124,7 +124,7 @@ class LinkResolver: AllStatic {
friend class klassItable; friend class klassItable;
private: private:
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS);
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
...@@ -134,7 +134,7 @@ class LinkResolver: AllStatic { ...@@ -134,7 +134,7 @@ class LinkResolver: AllStatic {
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 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);
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); 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);
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); 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);
......
...@@ -70,7 +70,6 @@ needs_jdk = \ ...@@ -70,7 +70,6 @@ needs_jdk = \
runtime/7107135/Test7107135.sh \ runtime/7107135/Test7107135.sh \
runtime/7158988/FieldMonitor.java \ runtime/7158988/FieldMonitor.java \
runtime/7194254/Test7194254.java \ runtime/7194254/Test7194254.java \
runtime/8026365/InvokeSpecialAnonTest.java \
runtime/jsig/Test8017498.sh \ runtime/jsig/Test8017498.sh \
runtime/Metaspace/FragmentMetaspace.java \ runtime/Metaspace/FragmentMetaspace.java \
runtime/NMT/BaselineWithParameter.java \ runtime/NMT/BaselineWithParameter.java \
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
*/ */
/* /*
* @ignore 8028741
* @test * @test
* @bug 8024804 * @bug 8024804
* @summary registerNatives() interface resolution should receive IAE * @summary registerNatives() interface resolution should receive IAE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册