diff -r 2c9a2b0e5c07 -r 573180d7f578 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Thu Mar 24 15:53:19 2016 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Mar 30 08:00:51 2016 +0200 @@ -1332,8 +1332,19 @@ } // Unlink the osr method, so we do not look this up again if (is_osr_method()) { - invalidate_osr_method(); + // Invalidate the osr nmethod only once + if (is_in_use()) { + invalidate_osr_method(); + } +#ifdef ASSERT + if (method() != NULL) { + // Make sure osr nmethod is invalidated, i.e. not on the list + bool found = method()->method_holder()->remove_osr_nmethod(this); + assert(!found, "osr nmethod should have been invalidated"); + } +#endif } + // 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 @@ -1386,16 +1397,9 @@ void nmethod::invalidate_osr_method() { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); -#ifndef ASSERT - // Make sure osr nmethod is invalidated only once - if (!is_in_use()) { - return; - } -#endif // Remove from list of active nmethods if (method() != NULL) { - bool removed = method()->method_holder()->remove_osr_nmethod(this); - assert(!removed || is_in_use(), "unused osr nmethod should be invalidated"); + method()->method_holder()->remove_osr_nmethod(this); } } @@ -1444,8 +1448,9 @@ // 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. - if (is_osr_method()) { + // 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(); } @@ -1511,6 +1516,14 @@ } } // leave critical region under Patching_lock +#ifdef ASSERT + if (is_osr_method() && method() != NULL) { + // Make sure osr nmethod is invalidated, i.e. not on the list + bool found = method()->method_holder()->remove_osr_nmethod(this); + assert(!found, "osr nmethod should have been invalidated"); + } +#endif + // When the nmethod becomes zombie it is no longer alive so the // dependencies must be flushed. nmethods in the not_entrant // state will be flushed later when the transition to zombie