namespace art HIDDEN { namespace mirror { class Object;
} // namespace mirror
class Monitor;
/* The lock value itself as stored in mirror::Object::monitor_. The two most significant bits *encodethestate.Thefourpossiblestatesarefatlocked,thin/unlocked,hashcode,and *forwardingaddress. * *Whenthelockwordisinthe"thin"stateanditsbitsareformattedasfollows: * *|33|2|2|222222221111|1111110000000000| *|10|9|8|765432109876|5432109876543210| *|00|m|r|lockcount|threadidowner| * *Thelockcountiszero,buttheownerisnonzeroforasimplyheldlock. *Whenthelockwordisinthe"fat"stateanditsbitsareformattedasfollows: * *|33|2|2|2222222211111111110000000000| *|10|9|8|7654321098765432109876543210| *|01|m|r|MonitorId| * *Whenthelockwordisinhashstateanditsbitsareformattedasfollows: * *|33|2|2|2222222211111111110000000000| *|10|9|8|7654321098765432109876543210| *|10|m|r|HashCode| * *Whenthelockwordisinforwardingaddressstateanditsbitsareformattedasfollows: * *|33|2|22222222211111111110000000000| *|10|9|87654321098765432109876543210| *|11|0|ForwardingAddress| * *The`r`bitstoresthereadbarrierstate. *The`m`bitstoresthemarkbitstate.
*/ class LockWord { public: enum SizeShiftsAndMasks : uint32_t { // private marker to avoid generate-operator-out.py from processing. // Number of bits to encode the state, currently just fat or thin/unlocked or hash code.
kStateSize = 2,
kReadBarrierStateSize = 1,
kMarkBitStateSize = 1, // Number of bits to encode the thin lock owner.
kThinLockOwnerSize = 16, // Remaining bits are the recursive lock count. Zero means it is locked exactly once // and not recursively.
kThinLockCountSize = 32 - kThinLockOwnerSize - kStateSize - kReadBarrierStateSize -
kMarkBitStateSize,
// GC state is mark bit and read barrier state.
kGCStateSize = kReadBarrierStateSize + kMarkBitStateSize,
kGCStateShift = kReadBarrierStateShift,
kGCStateMaskShifted = kReadBarrierStateMaskShifted | kMarkBitStateMaskShifted,
kGCStateMaskShiftedToggled = ~kGCStateMaskShifted,
// When the state is kHashCode, the non-state bits hold the hashcode. // Note Object.hashCode() has the hash code layout hardcoded.
kHashShift = 0,
kHashSize = 32 - kStateSize - kReadBarrierStateSize - kMarkBitStateSize,
kHashMask = (1 << kHashSize) - 1,
kMaxHash = kHashMask,
enum LockState {
kUnlocked, // No lock owners.
kThinLocked, // Single uncontended owner.
kFatLocked, // See associated monitor.
kHashCode, // Lock word contains an identity hash.
kForwardingAddress, // Lock word contains the forwarding address of an object.
};
// Return the number of times a lock value has been re-locked. Only valid in thin-locked state. // If the lock is held only once the return value is zero.
uint32_t ThinLockCount() const;
// Return the Monitor encoded in a fat lock.
Monitor* FatLockMonitor() const;
// Return the forwarding address stored in the monitor.
size_t ForwardingAddress() const;
// Constructor a lock word for inflation to use a Monitor.
LockWord(Monitor* mon, uint32_t gc_state);
// Return the hash code stored in the lock word, must be kHashCode state.
int32_t GetHashCode() const;
private: // Default constructor with no lock ownership.
LockWord();
explicit LockWord(uint32_t val) : value_(val) { // Make sure adding the overflow causes an overflow.
constexpr uint64_t overflow = static_cast<uint64_t>(kStateForwardingAddressShifted) + static_cast<uint64_t>(kStateForwardingAddressOverflow);
constexpr bool is_larger = overflow > static_cast<uint64_t>(0xFFFFFFFF);
static_assert(is_larger, "should have overflowed");
static_assert(
(~kStateForwardingAddress & kStateMask) == 0, "READ_BARRIER_MARK_REG relies on the forwarding address state being only one bits");
CheckReadBarrierState();
}
// Disallow this in favor of explicit Equal() with the // kIncludeReadBarrierState param to make clients be aware of the // read barrier state. booloperator==(const LockWord& rhs) = delete;
// Note GetValue() includes the read barrier bits and comparing (==) // GetValue() between two lock words to compare the lock states may // not work. Prefer Equal() or GetValueWithoutReadBarrierState().
uint32_t GetValue() const {
CheckReadBarrierState(); return value_;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.