< prev index next > src/hotspot/share/code/compiledMethod.cpp
// Check that the metadata embedded in the nmethod is alive
DEBUG_ONLY(metadata_do(check_class));
}
-// The IsUnloadingStruct represents a tuple comprising a result of
-// IsUnloadingBehaviour::is_unloading() for a given unloading cycle.
-struct IsUnloadingStruct {
- unsigned int _is_unloading:1;
- unsigned int _unloading_cycle:2;
-};
-
-// The IsUnloadingUnion allows treating the tuple of the IsUnloadingStruct
-// like a uint8_t, making it possible to read and write the tuple atomically.
-union IsUnloadingUnion {
- IsUnloadingStruct _inflated;
- uint8_t _value;
-};
+// The _is_unloading_state encodes a tuple comprising the unloading cycle
+// and the result of IsUnloadingBehaviour::is_unloading() fpr that cycle.
+// This is the bit layout of the _is_unloading_state byte: 00000CCU
+// CC refers to the cycle, which has 2 bits, and U refers to the result of
+// IsUnloadingBehaviour::is_unloading() for that unloading cycle.
bool CompiledMethod::is_unloading() {
- IsUnloadingUnion state;
- state._value = RawAccess<MO_RELAXED>::load(&_is_unloading_state);
- if (state._inflated._is_unloading == 1) {
+ uint8_t state = RawAccess<MO_RELAXED>::load(&_is_unloading_state);
+ bool state_is_unloading = (state & (uint8_t)1u) == 1;
+ uint8_t state_unloading_cycle = (state & (uint8_t)0x7u) >> 1;
+ if (state_is_unloading) {
return true;
}
- if (state._inflated._unloading_cycle == CodeCache::unloading_cycle()) {
- return state._inflated._is_unloading == 1;
+ if (state_unloading_cycle == CodeCache::unloading_cycle()) {
+ return false;
}
// The IsUnloadingBehaviour is responsible for checking if there are any dead
// oops in the CompiledMethod, by calling oops_do on it.
- bool result = IsUnloadingBehaviour::current()->is_unloading(this);
+ state_unloading_cycle = CodeCache::unloading_cycle();
+ state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
- state._inflated._unloading_cycle = CodeCache::unloading_cycle();
- state._inflated._is_unloading = result ? 1 : 0;
+ state = (state_unloading_cycle << 1) | (state_is_unloading ? 1 : 0);
- RawAccess<MO_RELAXED>::store(&_is_unloading_state, state._value);
+ RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
- return result;
+ return state_is_unloading;
}
void CompiledMethod::clear_unloading_state() {
- IsUnloadingUnion state;
- state._inflated._unloading_cycle = CodeCache::unloading_cycle();
- state._inflated._is_unloading = 0;
- RawAccess<MO_RELAXED>::store(&_is_unloading_state, state._value);
+ uint8_t state = CodeCache::unloading_cycle() << 1;
+ RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
}
// Called to clean up after class unloading for live nmethods and from the sweeper
// for all methods.
void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
< prev index next >