1d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers/* 2d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * Copyright (C) 2011 The Android Open Source Project 3d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 4d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 5d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * you may not use this file except in compliance with the License. 6d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * You may obtain a copy of the License at 7d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 8d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 9d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 10d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * Unless required by applicable law or agreed to in writing, software 11d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 12d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * See the License for the specific language governing permissions and 14d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * limitations under the License. 15d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers */ 16d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 17d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#ifndef ART_RUNTIME_LOCK_WORD_H_ 18d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#define ART_RUNTIME_LOCK_WORD_H_ 19d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 20d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include <iosfwd> 21d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include <stdint.h> 22d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 2380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 24d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "base/logging.h" 25e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#include "read_barrier.h" 26d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 27d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersnamespace art { 28d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersnamespace mirror { 29d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers class Object; 30d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} // namespace mirror 31d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 32d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersclass Monitor; 33d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 34ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier/* The lock value itself as stored in mirror::Object::monitor_. The two most significant bits of 35e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * the state. The four possible states are fat locked, thin/unlocked, hash code, and forwarding 36e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * address. When the lock word is in the "thin" state and its bits are formatted as follows: 37d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 38e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |33|22|222222221111|1111110000000000| 39e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |10|98|765432109876|5432109876543210| 40e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |00|rb| lock count |thread id owner | 41d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 42ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * When the lock word is in the "fat" state and its bits are formatted as follows: 43d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 44e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |33|22|2222222211111111110000000000| 45e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |10|98|7654321098765432109876543210| 46e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |01|rb| MonitorId | 47ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * 48ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * When the lock word is in hash state and its bits are formatted as follows: 49ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * 50e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |33|22|2222222211111111110000000000| 51e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |10|98|7654321098765432109876543210| 52e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |10|rb| HashCode | 53e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * 54e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * When the lock word is in fowarding address state and its bits are formatted as follows: 55e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * 56e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |33|22|2222222211111111110000000000| 57e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |10|98|7654321098765432109876543210| 58e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * |11| ForwardingAddress | 59e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * 60e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi * The rb bits store the read barrier state. 61d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers */ 62d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersclass LockWord { 63d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers public: 646a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers enum SizeShiftsAndMasks { // private marker to avoid generate-operator-out.py from processing. 65ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier // Number of bits to encode the state, currently just fat or thin/unlocked or hash code. 66ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kStateSize = 2, 67e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kReadBarrierStateSize = 2, 68d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Number of bits to encode the thin lock owner. 69d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockOwnerSize = 16, 70d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Remaining bits are the recursive lock count. 71e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kThinLockCountSize = 32 - kThinLockOwnerSize - kStateSize - kReadBarrierStateSize, 72d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Thin lock bits. Owner in lowest bits. 73ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 74d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockOwnerShift = 0, 75d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockOwnerMask = (1 << kThinLockOwnerSize) - 1, 76d8481ccad5b33aa9783cd8f7c614ee083a4f1cccnikolay serdjuk kThinLockMaxOwner = kThinLockOwnerMask, 77d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Count in higher bits. 78d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockCountShift = kThinLockOwnerSize + kThinLockOwnerShift, 798d82de5d7b04b8f43e7d2bb7ee8a66b0c7e71e1bDmitry Petrochenko kThinLockCountMask = (1 << kThinLockCountSize) - 1, 80d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockMaxCount = kThinLockCountMask, 81e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kThinLockCountOne = 1 << kThinLockCountShift, // == 65536 (0x10000) 82d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 83d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // State in the highest bits. 84e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kStateShift = kReadBarrierStateSize + kThinLockCountSize + kThinLockCountShift, 85d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateMask = (1 << kStateSize) - 1, 86e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kStateMaskShifted = kStateMask << kStateShift, 87d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateThinOrUnlocked = 0, 88d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateFat = 1, 89ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kStateHash = 2, 90590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier kStateForwardingAddress = 3, 91e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kReadBarrierStateShift = kThinLockCountSize + kThinLockCountShift, 92e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kReadBarrierStateMask = (1 << kReadBarrierStateSize) - 1, 93e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kReadBarrierStateMaskShifted = kReadBarrierStateMask << kReadBarrierStateShift, 94e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kReadBarrierStateMaskShiftedToggled = ~kReadBarrierStateMaskShifted, 95ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 96ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier // When the state is kHashCode, the non-state bits hold the hashcode. 9760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi // Note Object.hashCode() has the hash code layout hardcoded. 98ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashShift = 0, 99e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kHashSize = 32 - kStateSize - kReadBarrierStateSize, 100ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashMask = (1 << kHashSize) - 1, 101d8481ccad5b33aa9783cd8f7c614ee083a4f1cccnikolay serdjuk kMaxHash = kHashMask, 102e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 103e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kMonitorIdShift = kHashShift, 104e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kMonitorIdSize = kHashSize, 105e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kMonitorIdMask = kHashMask, 106e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kMonitorIdAlignmentShift = 32 - kMonitorIdSize, 107e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi kMonitorIdAlignment = 1 << kMonitorIdAlignmentShift, 108d8481ccad5b33aa9783cd8f7c614ee083a4f1cccnikolay serdjuk kMaxMonitorId = kMaxHash 109d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers }; 110d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 111e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi static LockWord FromThinLockId(uint32_t thread_id, uint32_t count, uint32_t rb_state) { 112d8481ccad5b33aa9783cd8f7c614ee083a4f1cccnikolay serdjuk CHECK_LE(thread_id, static_cast<uint32_t>(kThinLockMaxOwner)); 113d8481ccad5b33aa9783cd8f7c614ee083a4f1cccnikolay serdjuk CHECK_LE(count, static_cast<uint32_t>(kThinLockMaxCount)); 11460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(rb_state & ~kReadBarrierStateMask, 0U); 115ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier return LockWord((thread_id << kThinLockOwnerShift) | (count << kThinLockCountShift) | 116e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi (rb_state << kReadBarrierStateShift) | 117e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi (kStateThinOrUnlocked << kStateShift)); 118ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier } 119ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 120590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static LockWord FromForwardingAddress(size_t target) { 12114d90579f013b374638b599361970557ed4b3f09Roland Levillain DCHECK_ALIGNED(target, (1 << kStateSize)); 122590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return LockWord((target >> kStateSize) | (kStateForwardingAddress << kStateShift)); 123590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 124590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 125e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi static LockWord FromHashCode(uint32_t hash_code, uint32_t rb_state) { 126d8481ccad5b33aa9783cd8f7c614ee083a4f1cccnikolay serdjuk CHECK_LE(hash_code, static_cast<uint32_t>(kMaxHash)); 12760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(rb_state & ~kReadBarrierStateMask, 0U); 128e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return LockWord((hash_code << kHashShift) | 129e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi (rb_state << kReadBarrierStateShift) | 130e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi (kStateHash << kStateShift)); 131e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 132e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 133e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi static LockWord FromDefault(uint32_t rb_state) { 13460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(rb_state & ~kReadBarrierStateMask, 0U); 135e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return LockWord(rb_state << kReadBarrierStateShift); 136e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 137e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 138e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi static bool IsDefault(LockWord lw) { 139e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return LockWord().GetValue() == lw.GetValue(); 140e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 141e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 142e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi static LockWord Default() { 143e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return LockWord(); 144d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 145d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 146d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers enum LockState { 147d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kUnlocked, // No lock owners. 148d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLocked, // Single uncontended owner. 149ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kFatLocked, // See associated monitor. 150ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashCode, // Lock word contains an identity hash. 151590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier kForwardingAddress, // Lock word contains the forwarding address of an object. 152d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers }; 153d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 154d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers LockState GetState() const { 155e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi CheckReadBarrierState(); 15660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi if ((!kUseReadBarrier && UNLIKELY(value_ == 0)) || 15760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi (kUseReadBarrier && UNLIKELY((value_ & kReadBarrierStateMaskShiftedToggled) == 0))) { 158d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return kUnlocked; 159d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } else { 160590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier uint32_t internal_state = (value_ >> kStateShift) & kStateMask; 161590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier switch (internal_state) { 162590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier case kStateThinOrUnlocked: 163590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kThinLocked; 164590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier case kStateHash: 165590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kHashCode; 166590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier case kStateForwardingAddress: 167590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kForwardingAddress; 168590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier default: 169590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier DCHECK_EQ(internal_state, static_cast<uint32_t>(kStateFat)); 170590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kFatLocked; 171590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 172d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 173d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 174d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 175e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi uint32_t ReadBarrierState() const { 176e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return (value_ >> kReadBarrierStateShift) & kReadBarrierStateMask; 177e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 178e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 17960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi void SetReadBarrierState(uint32_t rb_state) { 18060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(rb_state & ~kReadBarrierStateMask, 0U); 18160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_NE(static_cast<uint32_t>(GetState()), static_cast<uint32_t>(kForwardingAddress)); 18260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi // Clear and or the bits. 18360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi value_ &= ~(kReadBarrierStateMask << kReadBarrierStateShift); 18460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi value_ |= (rb_state & kReadBarrierStateMask) << kReadBarrierStateShift; 18560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi } 18660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi 187d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Return the owner thin lock thread id. 188d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t ThinLockOwner() const; 189d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 190d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Return the number of times a lock value has been locked. 191d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t ThinLockCount() const; 192d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 193d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Return the Monitor encoded in a fat lock. 194d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers Monitor* FatLockMonitor() const; 195d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 196590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // Return the forwarding address stored in the monitor. 197590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t ForwardingAddress() const; 198590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 199e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // Constructor a lock word for inflation to use a Monitor. 2003887c468d731420e929e6ad3acf190d5431e94fcRoland Levillain LockWord(Monitor* mon, uint32_t rb_state); 201e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 202e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // Return the hash code stored in the lock word, must be kHashCode state. 203e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi int32_t GetHashCode() const; 204e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 205e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi template <bool kIncludeReadBarrierState> 206e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi static bool Equal(LockWord lw1, LockWord lw2) { 207e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi if (kIncludeReadBarrierState) { 208e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return lw1.GetValue() == lw2.GetValue(); 209e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 210e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return lw1.GetValueWithoutReadBarrierState() == lw2.GetValueWithoutReadBarrierState(); 211e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 212e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 2133f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi void Dump(std::ostream& os) { 2143f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi os << "LockWord:" << std::hex << value_; 2153f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 2163f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 217e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi private: 218d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Default constructor with no lock ownership. 219d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers LockWord(); 220d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 221e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi explicit LockWord(uint32_t val) : value_(val) { 222e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi CheckReadBarrierState(); 223d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 224d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 225e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // Disallow this in favor of explicit Equal() with the 226e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // kIncludeReadBarrierState param to make clients be aware of the 227e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // read barrier state. 228e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi bool operator==(const LockWord& rhs) = delete; 229e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi 230e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi void CheckReadBarrierState() const { 231e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi if (kIsDebugBuild && ((value_ >> kStateShift) & kStateMask) != kStateForwardingAddress) { 232e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi uint32_t rb_state = ReadBarrierState(); 233e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi if (!kUseReadBarrier) { 234e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi DCHECK_EQ(rb_state, 0U); 235e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } else { 236e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi DCHECK(rb_state == ReadBarrier::white_ptr_ || 237e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi rb_state == ReadBarrier::gray_ptr_ || 238e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi rb_state == ReadBarrier::black_ptr_) << rb_state; 239e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 240e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 241e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 242d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 243e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // Note GetValue() includes the read barrier bits and comparing (==) 244e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // GetValue() between two lock words to compare the lock states may 245e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // not work. Prefer Equal() or GetValueWithoutReadBarrierState(). 246d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t GetValue() const { 247e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi CheckReadBarrierState(); 248d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return value_; 249d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 250d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 251e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi uint32_t GetValueWithoutReadBarrierState() const { 252e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi CheckReadBarrierState(); 253e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi return value_ & ~(kReadBarrierStateMask << kReadBarrierStateShift); 254e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi } 255ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 256d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Only Object should be converting LockWords to/from uints. 257d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers friend class mirror::Object; 258d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 259d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // The encoded value holding all the state. 260d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t value_; 261d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}; 262d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersstd::ostream& operator<<(std::ostream& os, const LockWord::LockState& code); 263d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 264d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} // namespace art 265d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 266d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 267d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#endif // ART_RUNTIME_LOCK_WORD_H_ 268