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 (gUseReadBarrier || gUseUserfaultfd) { 187 if ((value_ & kGCStateMaskShiftedToggled) == 0) { 188 return kUnlocked; 189 } 190 } else if (value_ == 0) { 191 return kUnlocked; 192 } 193 uint32_t internal_state = (value_ >> kStateShift) & kStateMask; 194 switch (internal_state) { 195 case kStateThinOrUnlocked: 196 return kThinLocked; 197 case kStateHash: 198 return kHashCode; 199 case kStateForwardingAddress: 200 return kForwardingAddress; 201 default: 202 DCHECK_EQ(internal_state, static_cast<uint32_t>(kStateFat)); 203 return kFatLocked; 204 } 205 } 206 ReadBarrierState()207 uint32_t ReadBarrierState() const { 208 return (value_ >> kReadBarrierStateShift) & kReadBarrierStateMask; 209 } 210 GCState()211 uint32_t GCState() const { 212 return (value_ & kGCStateMaskShifted) >> kGCStateShift; 213 } 214 SetReadBarrierState(uint32_t rb_state)215 void SetReadBarrierState(uint32_t rb_state) { 216 DCHECK_EQ(rb_state & ~kReadBarrierStateMask, 0U); 217 DCHECK(rb_state == ReadBarrier::NonGrayState() || 218 rb_state == ReadBarrier::GrayState()) << rb_state; 219 DCHECK_NE(static_cast<uint32_t>(GetState()), static_cast<uint32_t>(kForwardingAddress)); 220 // Clear and or the bits. 221 value_ &= ~(kReadBarrierStateMask << kReadBarrierStateShift); 222 value_ |= (rb_state & kReadBarrierStateMask) << kReadBarrierStateShift; 223 } 224 225 MarkBitState()226 uint32_t MarkBitState() const { 227 return (value_ >> kMarkBitStateShift) & kMarkBitStateMask; 228 } 229 SetMarkBitState(uint32_t mark_bit)230 void SetMarkBitState(uint32_t mark_bit) { 231 DCHECK_EQ(mark_bit & ~kMarkBitStateMask, 0U); 232 DCHECK_NE(static_cast<uint32_t>(GetState()), static_cast<uint32_t>(kForwardingAddress)); 233 // Clear and or the bits. 234 value_ &= kMarkBitStateMaskShiftedToggled; 235 value_ |= mark_bit << kMarkBitStateShift; 236 } 237 238 // Return the owner thin lock thread id. 239 uint32_t ThinLockOwner() const; 240 241 // Return the number of times a lock value has been re-locked. Only valid in thin-locked state. 242 // If the lock is held only once the return value is zero. 243 uint32_t ThinLockCount() const; 244 245 // Return the Monitor encoded in a fat lock. 246 Monitor* FatLockMonitor() const; 247 248 // Return the forwarding address stored in the monitor. 249 size_t ForwardingAddress() const; 250 251 // Constructor a lock word for inflation to use a Monitor. 252 LockWord(Monitor* mon, uint32_t gc_state); 253 254 // Return the hash code stored in the lock word, must be kHashCode state. 255 int32_t GetHashCode() const; 256 257 template <bool kIncludeReadBarrierState> Equal(LockWord lw1,LockWord lw2)258 static bool Equal(LockWord lw1, LockWord lw2) { 259 if (kIncludeReadBarrierState) { 260 return lw1.GetValue() == lw2.GetValue(); 261 } 262 return lw1.GetValueWithoutGCState() == lw2.GetValueWithoutGCState(); 263 } 264 Dump(std::ostream & os)265 void Dump(std::ostream& os) { 266 os << "LockWord:" << std::hex << value_; 267 } 268 269 private: 270 // Default constructor with no lock ownership. 271 LockWord(); 272 LockWord(uint32_t val)273 explicit LockWord(uint32_t val) : value_(val) { 274 // Make sure adding the overflow causes an overflow. 275 constexpr uint64_t overflow = static_cast<uint64_t>(kStateForwardingAddressShifted) + 276 static_cast<uint64_t>(kStateForwardingAddressOverflow); 277 constexpr bool is_larger = overflow > static_cast<uint64_t>(0xFFFFFFFF); 278 static_assert(is_larger, "should have overflowed"); 279 static_assert( 280 (~kStateForwardingAddress & kStateMask) == 0, 281 "READ_BARRIER_MARK_REG relies on the forwarding address state being only one bits"); 282 CheckReadBarrierState(); 283 } 284 285 // Disallow this in favor of explicit Equal() with the 286 // kIncludeReadBarrierState param to make clients be aware of the 287 // read barrier state. 288 bool operator==(const LockWord& rhs) = delete; 289 CheckReadBarrierState()290 void CheckReadBarrierState() const { 291 if (kIsDebugBuild && ((value_ >> kStateShift) & kStateMask) != kStateForwardingAddress) { 292 uint32_t rb_state = ReadBarrierState(); 293 if (!gUseReadBarrier) { 294 DCHECK_EQ(rb_state, 0U); 295 } else { 296 DCHECK(rb_state == ReadBarrier::NonGrayState() || 297 rb_state == ReadBarrier::GrayState()) << rb_state; 298 } 299 } 300 } 301 302 // Note GetValue() includes the read barrier bits and comparing (==) 303 // GetValue() between two lock words to compare the lock states may 304 // not work. Prefer Equal() or GetValueWithoutReadBarrierState(). GetValue()305 uint32_t GetValue() const { 306 CheckReadBarrierState(); 307 return value_; 308 } 309 GetValueWithoutGCState()310 uint32_t GetValueWithoutGCState() const { 311 CheckReadBarrierState(); 312 return value_ & kGCStateMaskShiftedToggled; 313 } 314 315 // Only Object should be converting LockWords to/from uints. 316 friend class mirror::Object; 317 318 // The encoded value holding all the state. 319 uint32_t value_; 320 }; 321 std::ostream& operator<<(std::ostream& os, LockWord::LockState code); 322 323 } // namespace art 324 325 326 #endif // ART_RUNTIME_LOCK_WORD_H_ 327