8296101: nmethod::is_unloading result unstable with concurrent unloading
Reviewed-by: kbarrett, dlong
This commit is contained in:
parent
d771abb2fb
commit
cc3c5a18ed
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user