1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_LOCK_WORD_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_LOCK_WORD_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <cstdint> 21*795d594fSAndroid Build Coastguard Worker #include <iosfwd> 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h" 26*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 27*795d594fSAndroid Build Coastguard Worker #include "read_barrier.h" 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 30*795d594fSAndroid Build Coastguard Worker namespace mirror { 31*795d594fSAndroid Build Coastguard Worker class Object; 32*795d594fSAndroid Build Coastguard Worker } // namespace mirror 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker class Monitor; 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker /* The lock value itself as stored in mirror::Object::monitor_. The two most significant bits 37*795d594fSAndroid Build Coastguard Worker * encode the state. The four possible states are fat locked, thin/unlocked, hash code, and 38*795d594fSAndroid Build Coastguard Worker * forwarding address. 39*795d594fSAndroid Build Coastguard Worker * 40*795d594fSAndroid Build Coastguard Worker * When the lock word is in the "thin" state and its bits are formatted as follows: 41*795d594fSAndroid Build Coastguard Worker * 42*795d594fSAndroid Build Coastguard Worker * |33|2|2|222222221111|1111110000000000| 43*795d594fSAndroid Build Coastguard Worker * |10|9|8|765432109876|5432109876543210| 44*795d594fSAndroid Build Coastguard Worker * |00|m|r| lock count |thread id owner | 45*795d594fSAndroid Build Coastguard Worker * 46*795d594fSAndroid Build Coastguard Worker * The lock count is zero, but the owner is nonzero for a simply held lock. 47*795d594fSAndroid Build Coastguard Worker * When the lock word is in the "fat" state and its bits are formatted as follows: 48*795d594fSAndroid Build Coastguard Worker * 49*795d594fSAndroid Build Coastguard Worker * |33|2|2|2222222211111111110000000000| 50*795d594fSAndroid Build Coastguard Worker * |10|9|8|7654321098765432109876543210| 51*795d594fSAndroid Build Coastguard Worker * |01|m|r| MonitorId | 52*795d594fSAndroid Build Coastguard Worker * 53*795d594fSAndroid Build Coastguard Worker * When the lock word is in hash state and its bits are formatted as follows: 54*795d594fSAndroid Build Coastguard Worker * 55*795d594fSAndroid Build Coastguard Worker * |33|2|2|2222222211111111110000000000| 56*795d594fSAndroid Build Coastguard Worker * |10|9|8|7654321098765432109876543210| 57*795d594fSAndroid Build Coastguard Worker * |10|m|r| HashCode | 58*795d594fSAndroid Build Coastguard Worker * 59*795d594fSAndroid Build Coastguard Worker * When the lock word is in forwarding address state and its bits are formatted as follows: 60*795d594fSAndroid Build Coastguard Worker * 61*795d594fSAndroid Build Coastguard Worker * |33|2|22222222211111111110000000000| 62*795d594fSAndroid Build Coastguard Worker * |10|9|87654321098765432109876543210| 63*795d594fSAndroid Build Coastguard Worker * |11|0| ForwardingAddress | 64*795d594fSAndroid Build Coastguard Worker * 65*795d594fSAndroid Build Coastguard Worker * The `r` bit stores the read barrier state. 66*795d594fSAndroid Build Coastguard Worker * The `m` bit stores the mark bit state. 67*795d594fSAndroid Build Coastguard Worker */ 68*795d594fSAndroid Build Coastguard Worker class LockWord { 69*795d594fSAndroid Build Coastguard Worker public: 70*795d594fSAndroid Build Coastguard Worker enum SizeShiftsAndMasks : uint32_t { // private marker to avoid generate-operator-out.py from processing. 71*795d594fSAndroid Build Coastguard Worker // Number of bits to encode the state, currently just fat or thin/unlocked or hash code. 72*795d594fSAndroid Build Coastguard Worker kStateSize = 2, 73*795d594fSAndroid Build Coastguard Worker kReadBarrierStateSize = 1, 74*795d594fSAndroid Build Coastguard Worker kMarkBitStateSize = 1, 75*795d594fSAndroid Build Coastguard Worker // Number of bits to encode the thin lock owner. 76*795d594fSAndroid Build Coastguard Worker kThinLockOwnerSize = 16, 77*795d594fSAndroid Build Coastguard Worker // Remaining bits are the recursive lock count. Zero means it is locked exactly once 78*795d594fSAndroid Build Coastguard Worker // and not recursively. 79*795d594fSAndroid Build Coastguard Worker kThinLockCountSize = 32 - kThinLockOwnerSize - kStateSize - kReadBarrierStateSize - 80*795d594fSAndroid Build Coastguard Worker kMarkBitStateSize, 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker // Thin lock bits. Owner in lowest bits. 83*795d594fSAndroid Build Coastguard Worker kThinLockOwnerShift = 0, 84*795d594fSAndroid Build Coastguard Worker kThinLockOwnerMask = (1 << kThinLockOwnerSize) - 1, 85*795d594fSAndroid Build Coastguard Worker kThinLockOwnerMaskShifted = kThinLockOwnerMask << kThinLockOwnerShift, 86*795d594fSAndroid Build Coastguard Worker kThinLockMaxOwner = kThinLockOwnerMask, 87*795d594fSAndroid Build Coastguard Worker // Count in higher bits. 88*795d594fSAndroid Build Coastguard Worker kThinLockCountShift = kThinLockOwnerSize + kThinLockOwnerShift, 89*795d594fSAndroid Build Coastguard Worker kThinLockCountMask = (1 << kThinLockCountSize) - 1, 90*795d594fSAndroid Build Coastguard Worker kThinLockMaxCount = kThinLockCountMask, 91*795d594fSAndroid Build Coastguard Worker kThinLockCountOne = 1 << kThinLockCountShift, // == 65536 (0x10000) 92*795d594fSAndroid Build Coastguard Worker kThinLockCountMaskShifted = kThinLockCountMask << kThinLockCountShift, 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker // State in the highest bits. 95*795d594fSAndroid Build Coastguard Worker kStateShift = kReadBarrierStateSize + kThinLockCountSize + kThinLockCountShift + 96*795d594fSAndroid Build Coastguard Worker kMarkBitStateSize, 97*795d594fSAndroid Build Coastguard Worker kStateMask = (1 << kStateSize) - 1, 98*795d594fSAndroid Build Coastguard Worker kStateMaskShifted = kStateMask << kStateShift, 99*795d594fSAndroid Build Coastguard Worker kStateThinOrUnlocked = 0, 100*795d594fSAndroid Build Coastguard Worker kStateFat = 1, 101*795d594fSAndroid Build Coastguard Worker kStateHash = 2, 102*795d594fSAndroid Build Coastguard Worker kStateForwardingAddress = 3, 103*795d594fSAndroid Build Coastguard Worker kStateForwardingAddressShifted = kStateForwardingAddress << kStateShift, 104*795d594fSAndroid Build Coastguard Worker kStateForwardingAddressOverflow = (1 + kStateMask - kStateForwardingAddress) << kStateShift, 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker // Read barrier bit. 107*795d594fSAndroid Build Coastguard Worker kReadBarrierStateShift = kThinLockCountSize + kThinLockCountShift, 108*795d594fSAndroid Build Coastguard Worker kReadBarrierStateMask = (1 << kReadBarrierStateSize) - 1, 109*795d594fSAndroid Build Coastguard Worker kReadBarrierStateMaskShifted = kReadBarrierStateMask << kReadBarrierStateShift, 110*795d594fSAndroid Build Coastguard Worker kReadBarrierStateMaskShiftedToggled = ~kReadBarrierStateMaskShifted, 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker // Mark bit. 113*795d594fSAndroid Build Coastguard Worker kMarkBitStateShift = kReadBarrierStateSize + kReadBarrierStateShift, 114*795d594fSAndroid Build Coastguard Worker kMarkBitStateMask = (1 << kMarkBitStateSize) - 1, 115*795d594fSAndroid Build Coastguard Worker kMarkBitStateMaskShifted = kMarkBitStateMask << kMarkBitStateShift, 116*795d594fSAndroid Build Coastguard Worker kMarkBitStateMaskShiftedToggled = ~kMarkBitStateMaskShifted, 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker // GC state is mark bit and read barrier state. 119*795d594fSAndroid Build Coastguard Worker kGCStateSize = kReadBarrierStateSize + kMarkBitStateSize, 120*795d594fSAndroid Build Coastguard Worker kGCStateShift = kReadBarrierStateShift, 121*795d594fSAndroid Build Coastguard Worker kGCStateMaskShifted = kReadBarrierStateMaskShifted | kMarkBitStateMaskShifted, 122*795d594fSAndroid Build Coastguard Worker kGCStateMaskShiftedToggled = ~kGCStateMaskShifted, 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker // When the state is kHashCode, the non-state bits hold the hashcode. 125*795d594fSAndroid Build Coastguard Worker // Note Object.hashCode() has the hash code layout hardcoded. 126*795d594fSAndroid Build Coastguard Worker kHashShift = 0, 127*795d594fSAndroid Build Coastguard Worker kHashSize = 32 - kStateSize - kReadBarrierStateSize - kMarkBitStateSize, 128*795d594fSAndroid Build Coastguard Worker kHashMask = (1 << kHashSize) - 1, 129*795d594fSAndroid Build Coastguard Worker kMaxHash = kHashMask, 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker // Forwarding address shift. 132*795d594fSAndroid Build Coastguard Worker kForwardingAddressShift = kObjectAlignmentShift, 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker kMonitorIdShift = kHashShift, 135*795d594fSAndroid Build Coastguard Worker kMonitorIdSize = kHashSize, 136*795d594fSAndroid Build Coastguard Worker kMonitorIdMask = kHashMask, 137*795d594fSAndroid Build Coastguard Worker kMonitorIdAlignmentShift = 32 - kMonitorIdSize, 138*795d594fSAndroid Build Coastguard Worker kMonitorIdAlignment = 1 << kMonitorIdAlignmentShift, 139*795d594fSAndroid Build Coastguard Worker kMaxMonitorId = kMaxHash 140*795d594fSAndroid Build Coastguard Worker }; 141*795d594fSAndroid Build Coastguard Worker FromThinLockId(uint32_t thread_id,uint32_t count,uint32_t gc_state)142*795d594fSAndroid Build Coastguard Worker static LockWord FromThinLockId(uint32_t thread_id, uint32_t count, uint32_t gc_state) { 143*795d594fSAndroid Build Coastguard Worker CHECK_LE(thread_id, static_cast<uint32_t>(kThinLockMaxOwner)); 144*795d594fSAndroid Build Coastguard Worker CHECK_LE(count, static_cast<uint32_t>(kThinLockMaxCount)); 145*795d594fSAndroid Build Coastguard Worker // DCHECK_EQ(gc_bits & kGCStateMaskToggled, 0U); 146*795d594fSAndroid Build Coastguard Worker return LockWord((thread_id << kThinLockOwnerShift) | 147*795d594fSAndroid Build Coastguard Worker (count << kThinLockCountShift) | 148*795d594fSAndroid Build Coastguard Worker (gc_state << kGCStateShift) | 149*795d594fSAndroid Build Coastguard Worker (kStateThinOrUnlocked << kStateShift)); 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker FromForwardingAddress(size_t target)152*795d594fSAndroid Build Coastguard Worker static LockWord FromForwardingAddress(size_t target) { 153*795d594fSAndroid Build Coastguard Worker DCHECK_ALIGNED(target, (1 << kStateSize)); 154*795d594fSAndroid Build Coastguard Worker return LockWord((target >> kForwardingAddressShift) | kStateForwardingAddressShifted); 155*795d594fSAndroid Build Coastguard Worker } 156*795d594fSAndroid Build Coastguard Worker FromHashCode(uint32_t hash_code,uint32_t gc_state)157*795d594fSAndroid Build Coastguard Worker static LockWord FromHashCode(uint32_t hash_code, uint32_t gc_state) { 158*795d594fSAndroid Build Coastguard Worker CHECK_LE(hash_code, static_cast<uint32_t>(kMaxHash)); 159*795d594fSAndroid Build Coastguard Worker // DCHECK_EQ(gc_bits & kGCStateMaskToggled, 0U); 160*795d594fSAndroid Build Coastguard Worker return LockWord((hash_code << kHashShift) | 161*795d594fSAndroid Build Coastguard Worker (gc_state << kGCStateShift) | 162*795d594fSAndroid Build Coastguard Worker (kStateHash << kStateShift)); 163*795d594fSAndroid Build Coastguard Worker } 164*795d594fSAndroid Build Coastguard Worker FromDefault(uint32_t gc_state)165*795d594fSAndroid Build Coastguard Worker static LockWord FromDefault(uint32_t gc_state) { 166*795d594fSAndroid Build Coastguard Worker return LockWord(gc_state << kGCStateShift); 167*795d594fSAndroid Build Coastguard Worker } 168*795d594fSAndroid Build Coastguard Worker IsDefault(LockWord lw)169*795d594fSAndroid Build Coastguard Worker static bool IsDefault(LockWord lw) { 170*795d594fSAndroid Build Coastguard Worker return LockWord().GetValue() == lw.GetValue(); 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker Default()173*795d594fSAndroid Build Coastguard Worker static LockWord Default() { 174*795d594fSAndroid Build Coastguard Worker return LockWord(); 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker enum LockState { 178*795d594fSAndroid Build Coastguard Worker kUnlocked, // No lock owners. 179*795d594fSAndroid Build Coastguard Worker kThinLocked, // Single uncontended owner. 180*795d594fSAndroid Build Coastguard Worker kFatLocked, // See associated monitor. 181*795d594fSAndroid Build Coastguard Worker kHashCode, // Lock word contains an identity hash. 182*795d594fSAndroid Build Coastguard Worker kForwardingAddress, // Lock word contains the forwarding address of an object. 183*795d594fSAndroid Build Coastguard Worker }; 184*795d594fSAndroid Build Coastguard Worker GetState()185*795d594fSAndroid Build Coastguard Worker LockState GetState() const { 186*795d594fSAndroid Build Coastguard Worker CheckReadBarrierState(); 187*795d594fSAndroid Build Coastguard Worker if (gUseReadBarrier || gUseUserfaultfd) { 188*795d594fSAndroid Build Coastguard Worker if ((value_ & kGCStateMaskShiftedToggled) == 0) { 189*795d594fSAndroid Build Coastguard Worker return kUnlocked; 190*795d594fSAndroid Build Coastguard Worker } 191*795d594fSAndroid Build Coastguard Worker } else if (value_ == 0) { 192*795d594fSAndroid Build Coastguard Worker return kUnlocked; 193*795d594fSAndroid Build Coastguard Worker } 194*795d594fSAndroid Build Coastguard Worker uint32_t internal_state = (value_ >> kStateShift) & kStateMask; 195*795d594fSAndroid Build Coastguard Worker switch (internal_state) { 196*795d594fSAndroid Build Coastguard Worker case kStateThinOrUnlocked: 197*795d594fSAndroid Build Coastguard Worker return kThinLocked; 198*795d594fSAndroid Build Coastguard Worker case kStateHash: 199*795d594fSAndroid Build Coastguard Worker return kHashCode; 200*795d594fSAndroid Build Coastguard Worker case kStateForwardingAddress: 201*795d594fSAndroid Build Coastguard Worker return kForwardingAddress; 202*795d594fSAndroid Build Coastguard Worker default: 203*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(internal_state, static_cast<uint32_t>(kStateFat)); 204*795d594fSAndroid Build Coastguard Worker return kFatLocked; 205*795d594fSAndroid Build Coastguard Worker } 206*795d594fSAndroid Build Coastguard Worker } 207*795d594fSAndroid Build Coastguard Worker ReadBarrierState()208*795d594fSAndroid Build Coastguard Worker uint32_t ReadBarrierState() const { 209*795d594fSAndroid Build Coastguard Worker return (value_ >> kReadBarrierStateShift) & kReadBarrierStateMask; 210*795d594fSAndroid Build Coastguard Worker } 211*795d594fSAndroid Build Coastguard Worker GCState()212*795d594fSAndroid Build Coastguard Worker uint32_t GCState() const { 213*795d594fSAndroid Build Coastguard Worker return (value_ & kGCStateMaskShifted) >> kGCStateShift; 214*795d594fSAndroid Build Coastguard Worker } 215*795d594fSAndroid Build Coastguard Worker SetReadBarrierState(uint32_t rb_state)216*795d594fSAndroid Build Coastguard Worker void SetReadBarrierState(uint32_t rb_state) { 217*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(rb_state & ~kReadBarrierStateMask, 0U); 218*795d594fSAndroid Build Coastguard Worker DCHECK(rb_state == ReadBarrier::NonGrayState() || 219*795d594fSAndroid Build Coastguard Worker rb_state == ReadBarrier::GrayState()) << rb_state; 220*795d594fSAndroid Build Coastguard Worker DCHECK_NE(static_cast<uint32_t>(GetState()), static_cast<uint32_t>(kForwardingAddress)); 221*795d594fSAndroid Build Coastguard Worker // Clear and or the bits. 222*795d594fSAndroid Build Coastguard Worker value_ &= ~(kReadBarrierStateMask << kReadBarrierStateShift); 223*795d594fSAndroid Build Coastguard Worker value_ |= (rb_state & kReadBarrierStateMask) << kReadBarrierStateShift; 224*795d594fSAndroid Build Coastguard Worker } 225*795d594fSAndroid Build Coastguard Worker 226*795d594fSAndroid Build Coastguard Worker MarkBitState()227*795d594fSAndroid Build Coastguard Worker uint32_t MarkBitState() const { 228*795d594fSAndroid Build Coastguard Worker return (value_ >> kMarkBitStateShift) & kMarkBitStateMask; 229*795d594fSAndroid Build Coastguard Worker } 230*795d594fSAndroid Build Coastguard Worker SetMarkBitState(uint32_t mark_bit)231*795d594fSAndroid Build Coastguard Worker void SetMarkBitState(uint32_t mark_bit) { 232*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(mark_bit & ~kMarkBitStateMask, 0U); 233*795d594fSAndroid Build Coastguard Worker DCHECK_NE(static_cast<uint32_t>(GetState()), static_cast<uint32_t>(kForwardingAddress)); 234*795d594fSAndroid Build Coastguard Worker // Clear and or the bits. 235*795d594fSAndroid Build Coastguard Worker value_ &= kMarkBitStateMaskShiftedToggled; 236*795d594fSAndroid Build Coastguard Worker value_ |= mark_bit << kMarkBitStateShift; 237*795d594fSAndroid Build Coastguard Worker } 238*795d594fSAndroid Build Coastguard Worker 239*795d594fSAndroid Build Coastguard Worker // Return the owner thin lock thread id. 240*795d594fSAndroid Build Coastguard Worker uint32_t ThinLockOwner() const; 241*795d594fSAndroid Build Coastguard Worker 242*795d594fSAndroid Build Coastguard Worker // Return the number of times a lock value has been re-locked. Only valid in thin-locked state. 243*795d594fSAndroid Build Coastguard Worker // If the lock is held only once the return value is zero. 244*795d594fSAndroid Build Coastguard Worker uint32_t ThinLockCount() const; 245*795d594fSAndroid Build Coastguard Worker 246*795d594fSAndroid Build Coastguard Worker // Return the Monitor encoded in a fat lock. 247*795d594fSAndroid Build Coastguard Worker Monitor* FatLockMonitor() const; 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker // Return the forwarding address stored in the monitor. 250*795d594fSAndroid Build Coastguard Worker size_t ForwardingAddress() const; 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker // Constructor a lock word for inflation to use a Monitor. 253*795d594fSAndroid Build Coastguard Worker LockWord(Monitor* mon, uint32_t gc_state); 254*795d594fSAndroid Build Coastguard Worker 255*795d594fSAndroid Build Coastguard Worker // Return the hash code stored in the lock word, must be kHashCode state. 256*795d594fSAndroid Build Coastguard Worker int32_t GetHashCode() const; 257*795d594fSAndroid Build Coastguard Worker 258*795d594fSAndroid Build Coastguard Worker template <bool kIncludeReadBarrierState> Equal(LockWord lw1,LockWord lw2)259*795d594fSAndroid Build Coastguard Worker static bool Equal(LockWord lw1, LockWord lw2) { 260*795d594fSAndroid Build Coastguard Worker if (kIncludeReadBarrierState) { 261*795d594fSAndroid Build Coastguard Worker return lw1.GetValue() == lw2.GetValue(); 262*795d594fSAndroid Build Coastguard Worker } 263*795d594fSAndroid Build Coastguard Worker return lw1.GetValueWithoutGCState() == lw2.GetValueWithoutGCState(); 264*795d594fSAndroid Build Coastguard Worker } 265*795d594fSAndroid Build Coastguard Worker Dump(std::ostream & os)266*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os) { 267*795d594fSAndroid Build Coastguard Worker os << "LockWord:" << std::hex << value_; 268*795d594fSAndroid Build Coastguard Worker } 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker private: 271*795d594fSAndroid Build Coastguard Worker // Default constructor with no lock ownership. 272*795d594fSAndroid Build Coastguard Worker LockWord(); 273*795d594fSAndroid Build Coastguard Worker LockWord(uint32_t val)274*795d594fSAndroid Build Coastguard Worker explicit LockWord(uint32_t val) : value_(val) { 275*795d594fSAndroid Build Coastguard Worker // Make sure adding the overflow causes an overflow. 276*795d594fSAndroid Build Coastguard Worker constexpr uint64_t overflow = static_cast<uint64_t>(kStateForwardingAddressShifted) + 277*795d594fSAndroid Build Coastguard Worker static_cast<uint64_t>(kStateForwardingAddressOverflow); 278*795d594fSAndroid Build Coastguard Worker constexpr bool is_larger = overflow > static_cast<uint64_t>(0xFFFFFFFF); 279*795d594fSAndroid Build Coastguard Worker static_assert(is_larger, "should have overflowed"); 280*795d594fSAndroid Build Coastguard Worker static_assert( 281*795d594fSAndroid Build Coastguard Worker (~kStateForwardingAddress & kStateMask) == 0, 282*795d594fSAndroid Build Coastguard Worker "READ_BARRIER_MARK_REG relies on the forwarding address state being only one bits"); 283*795d594fSAndroid Build Coastguard Worker CheckReadBarrierState(); 284*795d594fSAndroid Build Coastguard Worker } 285*795d594fSAndroid Build Coastguard Worker 286*795d594fSAndroid Build Coastguard Worker // Disallow this in favor of explicit Equal() with the 287*795d594fSAndroid Build Coastguard Worker // kIncludeReadBarrierState param to make clients be aware of the 288*795d594fSAndroid Build Coastguard Worker // read barrier state. 289*795d594fSAndroid Build Coastguard Worker bool operator==(const LockWord& rhs) = delete; 290*795d594fSAndroid Build Coastguard Worker CheckReadBarrierState()291*795d594fSAndroid Build Coastguard Worker void CheckReadBarrierState() const { 292*795d594fSAndroid Build Coastguard Worker if (kIsDebugBuild && ((value_ >> kStateShift) & kStateMask) != kStateForwardingAddress) { 293*795d594fSAndroid Build Coastguard Worker uint32_t rb_state = ReadBarrierState(); 294*795d594fSAndroid Build Coastguard Worker if (!gUseReadBarrier) { 295*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(rb_state, 0U); 296*795d594fSAndroid Build Coastguard Worker } else { 297*795d594fSAndroid Build Coastguard Worker DCHECK(rb_state == ReadBarrier::NonGrayState() || 298*795d594fSAndroid Build Coastguard Worker rb_state == ReadBarrier::GrayState()) << rb_state; 299*795d594fSAndroid Build Coastguard Worker } 300*795d594fSAndroid Build Coastguard Worker } 301*795d594fSAndroid Build Coastguard Worker } 302*795d594fSAndroid Build Coastguard Worker 303*795d594fSAndroid Build Coastguard Worker // Note GetValue() includes the read barrier bits and comparing (==) 304*795d594fSAndroid Build Coastguard Worker // GetValue() between two lock words to compare the lock states may 305*795d594fSAndroid Build Coastguard Worker // not work. Prefer Equal() or GetValueWithoutReadBarrierState(). GetValue()306*795d594fSAndroid Build Coastguard Worker uint32_t GetValue() const { 307*795d594fSAndroid Build Coastguard Worker CheckReadBarrierState(); 308*795d594fSAndroid Build Coastguard Worker return value_; 309*795d594fSAndroid Build Coastguard Worker } 310*795d594fSAndroid Build Coastguard Worker GetValueWithoutGCState()311*795d594fSAndroid Build Coastguard Worker uint32_t GetValueWithoutGCState() const { 312*795d594fSAndroid Build Coastguard Worker CheckReadBarrierState(); 313*795d594fSAndroid Build Coastguard Worker return value_ & kGCStateMaskShiftedToggled; 314*795d594fSAndroid Build Coastguard Worker } 315*795d594fSAndroid Build Coastguard Worker 316*795d594fSAndroid Build Coastguard Worker // Only Object should be converting LockWords to/from uints. 317*795d594fSAndroid Build Coastguard Worker friend class mirror::Object; 318*795d594fSAndroid Build Coastguard Worker 319*795d594fSAndroid Build Coastguard Worker // The encoded value holding all the state. 320*795d594fSAndroid Build Coastguard Worker uint32_t value_; 321*795d594fSAndroid Build Coastguard Worker }; 322*795d594fSAndroid Build Coastguard Worker EXPORT std::ostream& operator<<(std::ostream& os, LockWord::LockState code); 323*795d594fSAndroid Build Coastguard Worker 324*795d594fSAndroid Build Coastguard Worker } // namespace art 325*795d594fSAndroid Build Coastguard Worker 326*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_LOCK_WORD_H_ 327