if (object == null) {
throw new NullPointerException();
}
// Prepare
final Word tid = Word.fromIntZeroExtend(VmMagic.currentProcessor().getCurrentThread().getId());
final Address objectPtr = ObjectReference.fromObject(object).toAddress();
final Address statusPtr = objectPtr.add(ObjectLayout.FLAGS_SLOT * Address.size());
for (;;) {
// attempt fast path: object is not locked.
final Word oldlockword = statusPtr.prepareWord();
final Word statusFlags = oldlockword.and(Word.fromIntZeroExtend(ObjectFlags.STATUS_FLAGS_MASK));
if (statusPtr.attempt(statusFlags, statusFlags.or(tid))) {
// fast path succeeded, the object was not locked and
// has been locked by the current thread.
return;
}
// object is locked or has an inflated lock.
if (!oldlockword.and(Word.fromIntZeroExtend(ObjectFlags.LOCK_EXPANDED)).isZero()) {
// slow path 2: high bit of lock word is set --> inflated lock
final Monitor m = getMonitor(oldlockword);
m.enter();
return;
} else if (oldlockword.and(Word.fromIntZeroExtend(ObjectFlags.THREAD_ID_MASK)).EQ(tid)) {
// Current thread owns the thinlock
final Word counter = oldlockword.and(Word.fromIntZeroExtend(ObjectFlags.LOCK_COUNT_MASK));
if (counter.EQ(Word.fromIntZeroExtend(ObjectFlags.LOCK_COUNT_MASK))) {
// thin lock entry counter == max, so we need to inflate
// ourselves.
installInflatedLock(object, null).enter();
return;
} else {
// not-quite-so-fast path: locked by current thread.
// increment counter.
// Try to update lock, it may be inflated by some other
// thread, so
// be cautious
final Word newlockword;
newlockword = oldlockword.add(Word.fromIntZeroExtend(ObjectFlags.LOCK_COUNT_INC));
// Try to update lock, it may be inflated by some other
// thread, so
// be cautious
if (statusPtr.attempt(oldlockword, newlockword)) {