< prev index next >
src/hotspot/share/code/nmethod.cpp
Print this page
rev 54936 : imported patch 8221734-v3
@@ -47,10 +47,11 @@
#include "oops/method.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiImpl.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/deoptimization.hpp"
#include "runtime/flags/flagSetting.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.hpp"
@@ -1119,15 +1120,11 @@
// If _method is already NULL the Method* is about to be unloaded,
// so we don't have to break the cycle. Note that it is possible to
// have the Method* live here, in case we unload the nmethod because
// it is pointing to some oop (other than the Method*) being unloaded.
if (_method != NULL) {
- // OSR methods point to the Method*, but the Method* does not
- // point back!
- if (_method->code() == this) {
- _method->clear_code(); // Break a cycle
- }
+ _method->unlink_code(this);
}
// Make the class unloaded - i.e., change state and notify sweeper
assert(SafepointSynchronize::is_at_safepoint() || Thread::current()->is_ConcurrentGC_thread(),
"must be at safepoint");
@@ -1205,20 +1202,13 @@
if (PrintCompilation && _state != unloaded) {
print_on(tty, state_msg);
}
}
-void nmethod::unlink_from_method(bool acquire_lock) {
- // We need to check if both the _code and _from_compiled_code_entry_point
- // refer to this nmethod because there is a race in setting these two fields
- // in Method* as seen in bugid 4947125.
- // If the vep() points to the zombie nmethod, the memory for the nmethod
- // could be flushed and the compiler and vtable stubs could still call
- // through it.
- if (method() != NULL && (method()->code() == this ||
- method()->from_compiled_entry() == verified_entry_point())) {
- method()->clear_code(acquire_lock);
+void nmethod::unlink_from_method() {
+ if (method() != NULL) {
+ method()->unlink_code();
}
}
/**
* Common functionality for both make_not_entrant and make_zombie
@@ -1241,28 +1231,28 @@
// This can be called while the system is already at a safepoint which is ok
NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
// during patching, depending on the nmethod state we must notify the GC that
// code has been unloaded, unregistering it. We cannot do this right while
- // holding the Patching_lock because we need to use the CodeCache_lock. This
+ // holding the CompiledMethod_lock because we need to use the CodeCache_lock. This
// would be prone to deadlocks.
// This flag is used to remember whether we need to later lock and unregister.
bool nmethod_needs_unregister = false;
- {
// invalidate osr nmethod before acquiring the patching lock since
// they both acquire leaf locks and we don't want a deadlock.
// This logic is equivalent to the logic below for patching the
// verified entry point of regular methods. We check that the
// nmethod is in use to ensure that it is invalidated only once.
if (is_osr_method() && is_in_use()) {
// this effectively makes the osr nmethod not entrant
invalidate_osr_method();
}
+ {
// Enter critical section. Does not block for safepoint.
- MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
+ MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
if (_state == state) {
// another thread already performed this transition so nothing
// to do, but return false to indicate this.
return false;
@@ -1302,12 +1292,13 @@
// Log the transition once
log_state_change();
// Remove nmethod from method.
- unlink_from_method(false /* already owns Patching_lock */);
- } // leave critical region under Patching_lock
+ unlink_from_method();
+
+ } // leave critical region under CompiledMethod_lock
#if INCLUDE_JVMCI
// Invalidate can't occur while holding the Patching lock
JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
if (nmethod_data != NULL) {
< prev index next >