8256368: Avoid repeated upcalls into Java to re-resolve MH/VH linkers/invokers

Reviewed-by: dlong, kvn
This commit is contained in:
Vladimir Ivanov 2022-02-14 11:57:46 +00:00
parent 95f198b2b1
commit 534e557874
5 changed files with 35 additions and 25 deletions

@ -2078,9 +2078,9 @@ static Method* unpack_method_and_appendix(Handle mname,
Method* SystemDictionary::find_method_handle_invoker(Klass* klass,
Symbol* name,
Symbol* signature,
Klass* accessing_klass,
Handle *appendix_result,
TRAPS) {
Klass* accessing_klass,
Handle* appendix_result,
TRAPS) {
assert(THREAD->can_call_java() ,"");
Handle method_type =
SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_NULL);

@ -67,7 +67,7 @@ bool BootstrapInfo::resolve_previously_linked_invokedynamic(CallInfo& result, TR
if (!cpce->is_f1_null()) {
methodHandle method( THREAD, cpce->f1_as_method());
Handle appendix( THREAD, cpce->appendix_if_resolved(_pool));
result.set_handle(method, appendix, THREAD);
result.set_handle(vmClasses::MethodHandle_klass(), method, appendix, THREAD);
Exceptions::wrap_dynamic_exception(/* is_indy */ true, CHECK_false);
return true;
} else if (cpce->indy_resolution_failed()) {
@ -221,7 +221,7 @@ bool BootstrapInfo::save_and_throw_indy_exc(TRAPS) {
void BootstrapInfo::resolve_newly_linked_invokedynamic(CallInfo& result, TRAPS) {
assert(is_resolved(), "");
result.set_handle(resolved_method(), resolved_appendix(), CHECK);
result.set_handle(vmClasses::MethodHandle_klass(), resolved_method(), resolved_appendix(), CHECK);
}
void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) {

@ -94,11 +94,6 @@ void CallInfo::set_virtual(Klass* resolved_klass,
assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
}
void CallInfo::set_handle(const methodHandle& resolved_method,
Handle resolved_appendix, TRAPS) {
set_handle(vmClasses::MethodHandle_klass(), resolved_method, resolved_appendix, CHECK);
}
void CallInfo::set_handle(Klass* resolved_klass,
const methodHandle& resolved_method,
Handle resolved_appendix, TRAPS) {
@ -476,14 +471,12 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info,
}
Handle appendix;
Handle method_type;
Method* result = SystemDictionary::find_method_handle_invoker(
klass,
name,
full_signature,
link_info.current_klass(),
&appendix,
CHECK_NULL);
Method* result = SystemDictionary::find_method_handle_invoker(klass,
name,
full_signature,
link_info.current_klass(),
&appendix,
CHECK_NULL);
if (lt_mh.is_enabled()) {
LogStream ls(lt_mh);
ls.print("lookup_polymorphic_method => (via Java) ");
@ -621,7 +614,7 @@ Method* LinkResolver::resolve_method_statically(Bytecodes::Code code,
Klass* resolved_klass = link_info.resolved_klass();
if (pool->has_preresolution()
|| (resolved_klass == vmClasses::MethodHandle_klass() &&
|| ((resolved_klass == vmClasses::MethodHandle_klass() || resolved_klass == vmClasses::VarHandle_klass()) &&
MethodHandles::is_signature_polymorphic_name(resolved_klass, link_info.name()))) {
Method* result = ConstantPool::method_at_if_loaded(pool, index);
if (result != NULL) {
@ -1679,15 +1672,31 @@ void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const
resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
}
bool LinkResolver::resolve_previously_linked_invokehandle(CallInfo& result, const LinkInfo& link_info, const constantPoolHandle& pool, int index, TRAPS) {
int cache_index = ConstantPool::decode_cpcache_index(index, true);
ConstantPoolCacheEntry* cpce = pool->cache()->entry_at(cache_index);
if (!cpce->is_f1_null()) {
Klass* resolved_klass = link_info.resolved_klass();
methodHandle method(THREAD, cpce->f1_as_method());
Handle appendix(THREAD, cpce->appendix_if_resolved(pool));
result.set_handle(resolved_klass, method, appendix, CHECK_false);
return true;
} else {
return false;
}
}
void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
// This guy is reached from InterpreterRuntime::resolve_invokehandle.
LinkInfo link_info(pool, index, CHECK);
if (log_is_enabled(Info, methodhandles)) {
ResourceMark rm(THREAD);
log_info(methodhandles)("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
link_info.signature()->as_C_string());
}
{ // Check if the call site has been bound already, and short circuit:
bool is_done = resolve_previously_linked_invokehandle(result, link_info, pool, index, CHECK);
if (is_done) return;
}
resolve_handle_call(result, link_info, CHECK);
}
@ -1699,7 +1708,7 @@ void LinkResolver::resolve_handle_call(CallInfo& result,
assert(resolved_klass == vmClasses::MethodHandle_klass() ||
resolved_klass == vmClasses::VarHandle_klass(), "");
assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
Handle resolved_appendix;
Handle resolved_appendix;
Method* resolved_method = lookup_polymorphic_method(link_info, &resolved_appendix, CHECK);
result.set_handle(resolved_klass, methodHandle(THREAD, resolved_method), resolved_appendix, CHECK);
}

@ -66,8 +66,6 @@ class CallInfo : public StackObj {
const methodHandle& resolved_method,
const methodHandle& selected_method,
int vtable_index, TRAPS);
void set_handle(const methodHandle& resolved_method,
Handle resolved_appendix, TRAPS);
void set_handle(Klass* resolved_klass,
const methodHandle& resolved_method,
Handle resolved_appendix, TRAPS);
@ -249,6 +247,11 @@ class LinkResolver: AllStatic {
Klass* recv_klass,
bool check_null_and_abstract, TRAPS);
static bool resolve_previously_linked_invokehandle(CallInfo& result,
const LinkInfo& link_info,
const constantPoolHandle& pool,
int index, TRAPS);
static void check_field_accessability(Klass* ref_klass,
Klass* resolved_klass,
Klass* sel_klass,
@ -337,7 +340,6 @@ class LinkResolver: AllStatic {
const methodHandle& attached_method,
Bytecodes::Code byte, TRAPS);
public:
// Only resolved method known.
static void throw_abstract_method_error(const methodHandle& resolved_method, TRAPS) {
throw_abstract_method_error(resolved_method, methodHandle(), NULL, CHECK);

@ -28,4 +28,3 @@
#############################################################################
java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all
java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTest.java 8256368 generic-all