From 89e0b67d907582bb1961b68622ace38c9089e9b3 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Sat, 3 Apr 2021 00:38:26 +0300 Subject: [PATCH 1/4] LinkResolver::vtable_index_of_interface_method --- src/hotspot/share/interpreter/linkResolver.cpp | 8 +++----- src/hotspot/share/interpreter/linkResolver.hpp | 2 +- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index 1c3043ac44054..4e5da98657baf 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -149,8 +149,7 @@ CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass, TRAPS) { kind = CallInfo::vtable_call; } else if (!resolved_klass->is_interface()) { // A default or miranda method. Compute the vtable index. - index = LinkResolver::vtable_index_of_interface_method(resolved_klass, - _resolved_method); + index = LinkResolver::vtable_index_of_interface_method(resolved_klass, resolved_method); assert(index >= 0 , "we should have valid vtable index at this point"); kind = CallInfo::vtable_call; @@ -405,8 +404,7 @@ Method* LinkResolver::lookup_instance_method_in_klasses(Klass* klass, return result; } -int LinkResolver::vtable_index_of_interface_method(Klass* klass, - const methodHandle& resolved_method) { +int LinkResolver::vtable_index_of_interface_method(Klass* klass, Method* resolved_method) { int vtable_index = Method::invalid_vtable_index; Symbol* name = resolved_method->name(); @@ -1391,7 +1389,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, // do lookup based on receiver klass using the vtable index if (resolved_method->method_holder()->is_interface()) { // default or miranda method - vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method); + vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method()); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index)); diff --git a/src/hotspot/share/interpreter/linkResolver.hpp b/src/hotspot/share/interpreter/linkResolver.hpp index 9eeb10cc6fd3f..53bf66a9f4bb1 100644 --- a/src/hotspot/share/interpreter/linkResolver.hpp +++ b/src/hotspot/share/interpreter/linkResolver.hpp @@ -317,7 +317,7 @@ class LinkResolver: AllStatic { static Method* resolve_static_call_or_null(const LinkInfo& link_info); static Method* resolve_special_call_or_null(const LinkInfo& link_info); - static int vtable_index_of_interface_method(Klass* klass, const methodHandle& resolved_method); + static int vtable_index_of_interface_method(Klass* klass, Method* resolved_method); // same as above for compile-time resolution; returns vtable_index if current_klass if linked static int resolve_virtual_vtable_index (Klass* receiver_klass, diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 1119bc30a8024..15a68c1009faf 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -728,7 +728,7 @@ C2V_END C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method)) Klass* klass = JVMCIENV->asKlass(jvmci_type); - methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method)); + Method* method = JVMCIENV->asMethod(jvmci_method); if (klass->is_interface()) { JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name())); } From a2bf479490cd2a77c77932c21b4b57403c3330a2 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Tue, 6 Apr 2021 16:11:54 +0300 Subject: [PATCH 2/4] Revert jvmciCompilerToVM.cpp change. --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 15a68c1009faf..dcc43fbb6fad5 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -728,7 +728,7 @@ C2V_END C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method)) Klass* klass = JVMCIENV->asKlass(jvmci_type); - Method* method = JVMCIENV->asMethod(jvmci_method); + methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method)); if (klass->is_interface()) { JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name())); } @@ -741,7 +741,7 @@ C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, job if (!InstanceKlass::cast(klass)->is_linked()) { JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name())); } - return LinkResolver::vtable_index_of_interface_method(klass, method); + return LinkResolver::vtable_index_of_interface_method(klass, method()); C2V_END C2V_VMENTRY_NULL(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type)) From 9dfc9437a2cb0d008d0be0f3260b040c325da958 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 8 Apr 2021 00:31:07 +0300 Subject: [PATCH 3/4] Move itable_index_of_interface_method() implementation to InstanceKlass --- .../share/interpreter/linkResolver.cpp | 29 +++---------------- .../share/interpreter/linkResolver.hpp | 2 +- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 2 +- src/hotspot/share/oops/instanceKlass.cpp | 27 +++++++++++++++++ src/hotspot/share/oops/instanceKlass.hpp | 1 + 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index 4e5da98657baf..1c532d6a74308 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -149,7 +149,7 @@ CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass, TRAPS) { kind = CallInfo::vtable_call; } else if (!resolved_klass->is_interface()) { // A default or miranda method. Compute the vtable index. - index = LinkResolver::vtable_index_of_interface_method(resolved_klass, resolved_method); + index = LinkResolver::vtable_index_of_interface_method(resolved_klass, _resolved_method); assert(index >= 0 , "we should have valid vtable index at this point"); kind = CallInfo::vtable_call; @@ -404,30 +404,9 @@ Method* LinkResolver::lookup_instance_method_in_klasses(Klass* klass, return result; } -int LinkResolver::vtable_index_of_interface_method(Klass* klass, Method* resolved_method) { - - int vtable_index = Method::invalid_vtable_index; - Symbol* name = resolved_method->name(); - Symbol* signature = resolved_method->signature(); +int LinkResolver::vtable_index_of_interface_method(Klass* klass, const methodHandle& resolved_method) { InstanceKlass* ik = InstanceKlass::cast(klass); - - // First check in default method array - if (!resolved_method->is_abstract() && ik->default_methods() != NULL) { - int index = InstanceKlass::find_method_index(ik->default_methods(), - name, signature, - Klass::OverpassLookupMode::find, - Klass::StaticLookupMode::find, - Klass::PrivateLookupMode::find); - if (index >= 0 ) { - vtable_index = ik->default_vtable_indices()->at(index); - } - } - if (vtable_index == Method::invalid_vtable_index) { - // get vtable_index for miranda methods - klassVtable vt = ik->vtable(); - vtable_index = vt.index_of_miranda(name, signature); - } - return vtable_index; + return ik->vtable_index_of_interface_method(resolved_method()); } Method* LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info) { @@ -1389,7 +1368,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, // do lookup based on receiver klass using the vtable index if (resolved_method->method_holder()->is_interface()) { // default or miranda method - vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method()); + vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index)); diff --git a/src/hotspot/share/interpreter/linkResolver.hpp b/src/hotspot/share/interpreter/linkResolver.hpp index 53bf66a9f4bb1..9eeb10cc6fd3f 100644 --- a/src/hotspot/share/interpreter/linkResolver.hpp +++ b/src/hotspot/share/interpreter/linkResolver.hpp @@ -317,7 +317,7 @@ class LinkResolver: AllStatic { static Method* resolve_static_call_or_null(const LinkInfo& link_info); static Method* resolve_special_call_or_null(const LinkInfo& link_info); - static int vtable_index_of_interface_method(Klass* klass, Method* resolved_method); + static int vtable_index_of_interface_method(Klass* klass, const methodHandle& resolved_method); // same as above for compile-time resolution; returns vtable_index if current_klass if linked static int resolve_virtual_vtable_index (Klass* receiver_klass, diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index dcc43fbb6fad5..1119bc30a8024 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -741,7 +741,7 @@ C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, job if (!InstanceKlass::cast(klass)->is_linked()) { JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name())); } - return LinkResolver::vtable_index_of_interface_method(klass, method()); + return LinkResolver::vtable_index_of_interface_method(klass, method); C2V_END C2V_VMENTRY_NULL(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type)) diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 2319a381394b4..81da660477e35 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -3185,6 +3185,33 @@ Method* InstanceKlass::method_at_itable(Klass* holder, int index, TRAPS) { return m; } +int InstanceKlass::vtable_index_of_interface_method(Method* intf_method) { + assert(this->is_linked(), "required"); + assert(intf_method->method_holder()->is_interface(), "not an interface method"); + assert(this->is_subtype_of(intf_method->method_holder()), "interface not implemented"); + + int vtable_index = Method::invalid_vtable_index; + Symbol* name = intf_method->name(); + Symbol* signature = intf_method->signature(); + + // First check in default method array + if (!intf_method->is_abstract() && this->default_methods() != NULL) { + int index = InstanceKlass::find_method_index(this->default_methods(), + name, signature, + Klass::OverpassLookupMode::find, + Klass::StaticLookupMode::find, + Klass::PrivateLookupMode::find); + if (index >= 0 ) { + vtable_index = this->default_vtable_indices()->at(index); + } + } + if (vtable_index == Method::invalid_vtable_index) { + // get vtable_index for miranda methods + klassVtable vt = this->vtable(); + vtable_index = vt.index_of_miranda(name, signature); + } + return vtable_index; +} #if INCLUDE_JVMTI // update default_methods for redefineclasses for methods that are diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index c5f62cf17bb48..f4970e3de3dd5 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1109,6 +1109,7 @@ class InstanceKlass: public Klass { // Java itable klassItable itable() const; // return klassItable wrapper Method* method_at_itable(Klass* holder, int index, TRAPS); + int vtable_index_of_interface_method(Method* method); #if INCLUDE_JVMTI void adjust_default_methods(bool* trace_name_printed); From b5aaf41e41299e841409df8e9aca018926d2a83a Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 8 Apr 2021 13:24:58 +0300 Subject: [PATCH 4/4] InstanceKlass::method_at_itable_or_null() cleanups --- src/hotspot/share/oops/instanceKlass.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index db8b2ee512b38..4ec28f5d026db 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -3193,28 +3193,28 @@ Method* InstanceKlass::method_at_itable_or_null(InstanceKlass* holder, int index } int InstanceKlass::vtable_index_of_interface_method(Method* intf_method) { - assert(this->is_linked(), "required"); + assert(is_linked(), "required"); assert(intf_method->method_holder()->is_interface(), "not an interface method"); - assert(this->is_subtype_of(intf_method->method_holder()), "interface not implemented"); + assert(is_subtype_of(intf_method->method_holder()), "interface not implemented"); int vtable_index = Method::invalid_vtable_index; Symbol* name = intf_method->name(); Symbol* signature = intf_method->signature(); // First check in default method array - if (!intf_method->is_abstract() && this->default_methods() != NULL) { - int index = InstanceKlass::find_method_index(this->default_methods(), - name, signature, - Klass::OverpassLookupMode::find, - Klass::StaticLookupMode::find, - Klass::PrivateLookupMode::find); - if (index >= 0 ) { - vtable_index = this->default_vtable_indices()->at(index); + if (!intf_method->is_abstract() && default_methods() != NULL) { + int index = find_method_index(default_methods(), + name, signature, + Klass::OverpassLookupMode::find, + Klass::StaticLookupMode::find, + Klass::PrivateLookupMode::find); + if (index >= 0) { + vtable_index = default_vtable_indices()->at(index); } } if (vtable_index == Method::invalid_vtable_index) { // get vtable_index for miranda methods - klassVtable vt = this->vtable(); + klassVtable vt = vtable(); vtable_index = vt.index_of_miranda(name, signature); } return vtable_index;