Skip to content

Commit c05015b

Browse files
committed
8291736: find_method_handle_intrinsic leaks Method*
Reviewed-by: hseigel, iklam, dholmes
1 parent b2067e6 commit c05015b

File tree

1 file changed

+27
-28
lines changed

1 file changed

+27
-28
lines changed

src/hotspot/share/classfile/systemDictionary.cpp

+27-28
Original file line numberDiff line numberDiff line change
@@ -2036,47 +2036,46 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid,
20362036
Symbol* signature,
20372037
TRAPS) {
20382038

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

2046-
Method** met;
2047-
InvokeMethodKey key(signature, iid_as_int);
20482045
{
20492046
MutexLocker ml(THREAD, InvokeMethodTable_lock);
2050-
met = _invoke_method_intrinsic_table.get(key);
2047+
InvokeMethodKey key(signature, iid_as_int);
2048+
Method** met = _invoke_method_intrinsic_table.get(key);
20512049
if (met != nullptr) {
20522050
return *met;
20532051
}
2054-
}
20552052

2056-
methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL);
2057-
if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) {
2058-
// Generate a compiled form of the MH intrinsic
2059-
// linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version.
2060-
AdapterHandlerLibrary::create_native_wrapper(m);
2061-
// Check if have the compiled code.
2062-
if (!m->has_compiled_code()) {
2063-
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(),
2064-
"Out of space in CodeCache for method handle intrinsic");
2065-
}
2066-
}
2067-
// Now grab the lock. We might have to throw away the new method,
2068-
// if a racing thread has managed to install one at the same time.
2069-
{
2070-
MutexLocker ml(THREAD, InvokeMethodTable_lock);
2071-
signature->make_permanent(); // The signature is never unloaded.
2072-
bool created;
2073-
met = _invoke_method_intrinsic_table.put_if_absent(key, m(), &created);
2074-
Method* saved_method = *met;
2075-
assert(Arguments::is_interpreter_only() || (saved_method->has_compiled_code() &&
2076-
saved_method->code()->entry_point() == saved_method->from_compiled_entry()),
2077-
"MH intrinsic invariant");
2078-
return saved_method;
2053+
bool throw_error = false;
2054+
// This function could get an OOM but it is safe to call inside of a lock because
2055+
// throwing OutOfMemoryError doesn't call Java code.
2056+
methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL);
2057+
if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) {
2058+
// Generate a compiled form of the MH intrinsic
2059+
// linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version.
2060+
AdapterHandlerLibrary::create_native_wrapper(m);
2061+
// Check if have the compiled code.
2062+
throw_error = (!m->has_compiled_code());
2063+
}
2064+
2065+
if (!throw_error) {
2066+
signature->make_permanent(); // The signature is never unloaded.
2067+
bool created = _invoke_method_intrinsic_table.put(key, m());
2068+
assert(created, "must be since we still hold the lock");
2069+
assert(Arguments::is_interpreter_only() || (m->has_compiled_code() &&
2070+
m->code()->entry_point() == m->from_compiled_entry()),
2071+
"MH intrinsic invariant");
2072+
return m();
2073+
}
20792074
}
2075+
2076+
// Throw error outside of the lock.
2077+
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(),
2078+
"Out of space in CodeCache for method handle intrinsic");
20802079
}
20812080

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

0 commit comments

Comments
 (0)