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