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