mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8152947: VM crash with assert(!removed || is_in_use()) failed: unused osr nmethod should be invalidated
Check OSR invalidation after nmethod state transition. Reviewed-by: ddmitriev, vlivanov
This commit is contained in:
parent
08cd7e16d7
commit
c3ebf37e24
1 changed files with 24 additions and 11 deletions
|
@ -1332,8 +1332,19 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
|
|||
}
|
||||
// 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::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
|
|||
|
||||
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 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
|
|||
// 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 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
|
|||
}
|
||||
} // 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue