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 23d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "base/logging.h" 24590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier#include "utils.h" 25d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 26d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersnamespace art { 27d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersnamespace mirror { 28d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers class Object; 29d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} // namespace mirror 30d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 31d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersclass Monitor; 32d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 33ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier/* The lock value itself as stored in mirror::Object::monitor_. The two most significant bits of 34ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * the state. The three possible states are fat locked, thin/unlocked, and hash code. 35ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * When the lock word is in the "thin" state and its bits are formatted as follows: 36d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 37ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |33|22222222221111|1111110000000000| 38ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |10|98765432109876|5432109876543210| 39ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |00| lock count |thread id owner | 40d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 41ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * When the lock word is in the "fat" state and its bits are formatted as follows: 42d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers * 43ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |33|222222222211111111110000000000| 44ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |10|987654321098765432109876543210| 45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * |01| MonitorId | 46ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * 47ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * When the lock word is in hash state and its bits are formatted as follows: 48ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * 49ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |33|222222222211111111110000000000| 50ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |10|987654321098765432109876543210| 51ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier * |10| HashCode | 52d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers */ 53d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersclass LockWord { 54d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers public: 55d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers enum { 56ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier // Number of bits to encode the state, currently just fat or thin/unlocked or hash code. 57ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kStateSize = 2, 58d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Number of bits to encode the thin lock owner. 59d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockOwnerSize = 16, 60d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Remaining bits are the recursive lock count. 61d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockCountSize = 32 - kThinLockOwnerSize - kStateSize, 62d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Thin lock bits. Owner in lowest bits. 63ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 64d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockOwnerShift = 0, 65d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockOwnerMask = (1 << kThinLockOwnerSize) - 1, 66d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Count in higher bits. 67d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockCountShift = kThinLockOwnerSize + kThinLockOwnerShift, 688d82de5d7b04b8f43e7d2bb7ee8a66b0c7e71e1bDmitry Petrochenko kThinLockCountMask = (1 << kThinLockCountSize) - 1, 69d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLockMaxCount = kThinLockCountMask, 70d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 71d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // State in the highest bits. 72d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateShift = kThinLockCountSize + kThinLockCountShift, 73d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateMask = (1 << kStateSize) - 1, 74d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateThinOrUnlocked = 0, 75d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kStateFat = 1, 76ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kStateHash = 2, 77590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier kStateForwardingAddress = 3, 78ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 79ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier // When the state is kHashCode, the non-state bits hold the hashcode. 80ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashShift = 0, 81ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashSize = 32 - kStateSize, 82ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashMask = (1 << kHashSize) - 1, 83d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers }; 84d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 85d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers static LockWord FromThinLockId(uint32_t thread_id, uint32_t count) { 86d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers CHECK_LE(thread_id, static_cast<uint32_t>(kThinLockOwnerMask)); 87ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier return LockWord((thread_id << kThinLockOwnerShift) | (count << kThinLockCountShift) | 88ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier (kStateThinOrUnlocked << kStateShift)); 89ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier } 90ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 91590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static LockWord FromForwardingAddress(size_t target) { 92590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier DCHECK(IsAligned < 1 << kStateSize>(target)); 93590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return LockWord((target >> kStateSize) | (kStateForwardingAddress << kStateShift)); 94590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 95590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 96ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier static LockWord FromHashCode(uint32_t hash_code) { 97ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier CHECK_LE(hash_code, static_cast<uint32_t>(kHashMask)); 98ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier return LockWord((hash_code << kHashShift) | (kStateHash << kStateShift)); 99d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 100d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 101d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers enum LockState { 102d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kUnlocked, // No lock owners. 103d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers kThinLocked, // Single uncontended owner. 104ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kFatLocked, // See associated monitor. 105ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier kHashCode, // Lock word contains an identity hash. 106590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier kForwardingAddress, // Lock word contains the forwarding address of an object. 107d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers }; 108d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 109d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers LockState GetState() const { 110590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (UNLIKELY(value_ == 0)) { 111d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return kUnlocked; 112d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } else { 113590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier uint32_t internal_state = (value_ >> kStateShift) & kStateMask; 114590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier switch (internal_state) { 115590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier case kStateThinOrUnlocked: 116590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kThinLocked; 117590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier case kStateHash: 118590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kHashCode; 119590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier case kStateForwardingAddress: 120590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kForwardingAddress; 121590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier default: 122590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier DCHECK_EQ(internal_state, static_cast<uint32_t>(kStateFat)); 123590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return kFatLocked; 124590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 125d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 126d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 127d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 128d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Return the owner thin lock thread id. 129d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t ThinLockOwner() const; 130d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 131d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Return the number of times a lock value has been locked. 132d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t ThinLockCount() const; 133d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 134d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Return the Monitor encoded in a fat lock. 135d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers Monitor* FatLockMonitor() const; 136d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 137590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // Return the forwarding address stored in the monitor. 138590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t ForwardingAddress() const; 139590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 140d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Default constructor with no lock ownership. 141d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers LockWord(); 142d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 143d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Constructor a lock word for inflation to use a Monitor. 144d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers explicit LockWord(Monitor* mon); 145d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 146ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier bool operator==(const LockWord& rhs) const { 147d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return GetValue() == rhs.GetValue(); 148d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 149d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 150ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier // Return the hash code stored in the lock word, must be kHashCode state. 1514e6a31eb97f22f4480827474b30b9e64f396eaceMathieu Chartier int32_t GetHashCode() const; 152d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 153d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t GetValue() const { 154d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return value_; 155d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 156d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 157ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier private: 158ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier explicit LockWord(uint32_t val) : value_(val) {} 159ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier 160d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Only Object should be converting LockWords to/from uints. 161d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers friend class mirror::Object; 162d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 163d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // The encoded value holding all the state. 164d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers uint32_t value_; 165d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}; 166d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersstd::ostream& operator<<(std::ostream& os, const LockWord::LockState& code); 167d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 168d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} // namespace art 169d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 170d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 171d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#endif // ART_RUNTIME_LOCK_WORD_H_ 172