mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-08 04:29:28 +00:00
8291736: find_method_handle_intrinsic leaks Method*
Reviewed-by: hseigel, iklam, dholmes
This commit is contained in:
parent
b2067e63da
commit
c05015bc93
@ -2036,47 +2036,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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// 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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user