--- old/src/share/vm/code/nmethod.cpp 2016-03-29 12:50:00.876652103 +0200 +++ new/src/share/vm/code/nmethod.cpp 2016-03-29 12:50:00.808652100 +0200 @@ -1331,8 +1331,17 @@ } // 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(); + } +#ifndef ASSERT + // 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 @@ -1385,16 +1394,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); } } @@ -1443,8 +1445,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(); } @@ -1510,6 +1513,14 @@ } } // leave critical region under Patching_lock +#ifndef ASSERT + if (is_osr_method()) { + // 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