< 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 >