8296101: nmethod::is_unloading result unstable with concurrent unloading

Reviewed-by: kbarrett, dlong
This commit is contained in:
Erik Österlund 2022-11-03 13:31:07 +00:00
parent d771abb2fb
commit cc3c5a18ed

View File

@ -1655,11 +1655,22 @@ bool nmethod::is_unloading() {
// or because is_cold() heuristically determines it is time to unload.
state_unloading_cycle = current_cycle;
state_is_unloading = IsUnloadingBehaviour::is_unloading(this);
state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
uint8_t new_state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
// Note that if an nmethod has dead oops, everyone will agree that the
// nmethod is_unloading. However, the is_cold heuristics can yield
// different outcomes, so we guard the computed result with a CAS
// to ensure all threads have a shared view of whether an nmethod
// is_unloading or not.
uint8_t found_state = Atomic::cmpxchg(&_is_unloading_state, state, new_state, memory_order_relaxed);
return state_is_unloading;
if (found_state == state) {
// First to change state, we win
return state_is_unloading;
} else {
// State already set, so use it
return IsUnloadingState::is_unloading(found_state);
}
}
void nmethod::clear_unloading_state() {