8256368: Avoid repeated upcalls into Java to re-resolve MH/VH linkers/invokers
Reviewed-by: dlong, kvn
This commit is contained in:
parent
95f198b2b1
commit
534e557874
src/hotspot/share
test/jdk
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user