Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 27 additions & 28 deletions src/hotspot/share/classfile/systemDictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2064,47 +2064,46 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid,
Symbol* signature,
TRAPS) {

methodHandle empty;
const int iid_as_int = vmIntrinsics::as_int(iid);
assert(MethodHandles::is_signature_polymorphic(iid) &&
MethodHandles::is_signature_polymorphic_intrinsic(iid) &&
iid != vmIntrinsics::_invokeGeneric,
"must be a known MH intrinsic iid=%d: %s", iid_as_int, vmIntrinsics::name_at(iid));

Method** met;
InvokeMethodKey key(signature, iid_as_int);
{
MutexLocker ml(THREAD, InvokeMethodTable_lock);
met = _invoke_method_intrinsic_table.get(key);
InvokeMethodKey key(signature, iid_as_int);
Method** met = _invoke_method_intrinsic_table.get(key);
if (met != nullptr) {
return *met;
}
}

methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL);
if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) {
// Generate a compiled form of the MH intrinsic
// linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version.
AdapterHandlerLibrary::create_native_wrapper(m);
// Check if have the compiled code.
if (!m->has_compiled_code()) {
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(),
"Out of space in CodeCache for method handle intrinsic");
}
}
// Now grab the lock. We might have to throw away the new method,
// if a racing thread has managed to install one at the same time.
{
MutexLocker ml(THREAD, InvokeMethodTable_lock);
signature->make_permanent(); // The signature is never unloaded.
bool created;
met = _invoke_method_intrinsic_table.put_if_absent(key, m(), &created);
Method* saved_method = *met;
assert(Arguments::is_interpreter_only() || (saved_method->has_compiled_code() &&
saved_method->code()->entry_point() == saved_method->from_compiled_entry()),
"MH intrinsic invariant");
return saved_method;
bool throw_error = false;
// This function could get an OOM but it is safe to call inside of a lock because
// throwing OutOfMemoryError doesn't call Java code.
methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL);
if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) {
// Generate a compiled form of the MH intrinsic
// linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version.
AdapterHandlerLibrary::create_native_wrapper(m);
// Check if have the compiled code.
throw_error = (!m->has_compiled_code());
}

if (!throw_error) {
signature->make_permanent(); // The signature is never unloaded.
bool created = _invoke_method_intrinsic_table.put(key, m());
assert(created, "must be since we still hold the lock");
assert(Arguments::is_interpreter_only() || (m->has_compiled_code() &&
m->code()->entry_point() == m->from_compiled_entry()),
"MH intrinsic invariant");
return m();
}
}

// Throw error outside of the lock.
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(),
"Out of space in CodeCache for method handle intrinsic");
}

// Helper for unpacking the return value from linkMethod and linkCallSite.
Expand Down