Skip to content

Commit 1707d5c

Browse files
author
Daniel D. Daugherty
committed
8238174: migrate ObjectMonitor::_owner field away from C++ volatile semantics
Reviewed-by: dholmes, mdoerr
1 parent 50a2c22 commit 1707d5c

File tree

4 files changed

+48
-42
lines changed

4 files changed

+48
-42
lines changed

src/hotspot/share/runtime/objectMonitor.cpp

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ bool ObjectMonitor::enter(TRAPS) {
341341
// Note that if we acquire the monitor from an initial spin
342342
// we forgo posting JVMTI events and firing DTRACE probes.
343343
if (TrySpin(Self) > 0) {
344-
assert(_owner == Self, "must be Self: owner=" INTPTR_FORMAT, p2i(_owner));
344+
assert(owner_raw() == Self, "must be Self: owner=" INTPTR_FORMAT, p2i(owner_raw()));
345345
assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions);
346346
assert(object()->mark() == markWord::encode(this),
347347
"object mark must match encoded this: mark=" INTPTR_FORMAT
@@ -351,7 +351,7 @@ bool ObjectMonitor::enter(TRAPS) {
351351
return true;
352352
}
353353

354-
assert(_owner != Self, "invariant");
354+
assert(owner_raw() != Self, "invariant");
355355
assert(_succ != Self, "invariant");
356356
JavaThread * jt = Self->as_Java_thread();
357357
assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
@@ -442,7 +442,7 @@ bool ObjectMonitor::enter(TRAPS) {
442442

443443
// Must either set _recursions = 0 or ASSERT _recursions == 0.
444444
assert(_recursions == 0, "invariant");
445-
assert(_owner == Self, "invariant");
445+
assert(owner_raw() == Self, "invariant");
446446
assert(_succ != Self, "invariant");
447447
assert(object()->mark() == markWord::encode(this), "invariant");
448448

@@ -480,7 +480,7 @@ bool ObjectMonitor::enter(TRAPS) {
480480
// Callers must compensate as needed.
481481

482482
int ObjectMonitor::TryLock(Thread * Self) {
483-
void * own = _owner;
483+
void* own = owner_raw();
484484
if (own != NULL) return 0;
485485
if (try_set_owner_from(NULL, Self) == NULL) {
486486
assert(_recursions == 0, "invariant");
@@ -660,8 +660,8 @@ const char* ObjectMonitor::is_busy_to_string(stringStream* ss) {
660660
} else {
661661
ss->print("contentions=0");
662662
}
663-
if (_owner != DEFLATER_MARKER) {
664-
ss->print("owner=" INTPTR_FORMAT, p2i(_owner));
663+
if (!owner_is_DEFLATER_MARKER()) {
664+
ss->print("owner=" INTPTR_FORMAT, p2i(owner_raw()));
665665
} else {
666666
// We report NULL instead of DEFLATER_MARKER here because is_busy()
667667
// ignores DEFLATER_MARKER values.
@@ -681,7 +681,7 @@ void ObjectMonitor::EnterI(TRAPS) {
681681
// Try the lock - TATAS
682682
if (TryLock (Self) > 0) {
683683
assert(_succ != Self, "invariant");
684-
assert(_owner == Self, "invariant");
684+
assert(owner_raw() == Self, "invariant");
685685
assert(_Responsible != Self, "invariant");
686686
return;
687687
}
@@ -714,15 +714,15 @@ void ObjectMonitor::EnterI(TRAPS) {
714714
// effects.
715715

716716
if (TrySpin(Self) > 0) {
717-
assert(_owner == Self, "invariant");
717+
assert(owner_raw() == Self, "invariant");
718718
assert(_succ != Self, "invariant");
719719
assert(_Responsible != Self, "invariant");
720720
return;
721721
}
722722

723723
// The Spin failed -- Enqueue and park the thread ...
724724
assert(_succ != Self, "invariant");
725-
assert(_owner != Self, "invariant");
725+
assert(owner_raw() != Self, "invariant");
726726
assert(_Responsible != Self, "invariant");
727727

728728
// Enqueue "Self" on ObjectMonitor's _cxq.
@@ -752,7 +752,7 @@ void ObjectMonitor::EnterI(TRAPS) {
752752
// As an optional optimization we retry the lock.
753753
if (TryLock (Self) > 0) {
754754
assert(_succ != Self, "invariant");
755-
assert(_owner == Self, "invariant");
755+
assert(owner_raw() == Self, "invariant");
756756
assert(_Responsible != Self, "invariant");
757757
return;
758758
}
@@ -804,7 +804,7 @@ void ObjectMonitor::EnterI(TRAPS) {
804804
for (;;) {
805805

806806
if (TryLock(Self) > 0) break;
807-
assert(_owner != Self, "invariant");
807+
assert(owner_raw() != Self, "invariant");
808808

809809
// park self
810810
if (_Responsible == Self) {
@@ -873,7 +873,7 @@ void ObjectMonitor::EnterI(TRAPS) {
873873
// The head of cxq is volatile but the interior is stable.
874874
// In addition, Self.TState is stable.
875875

876-
assert(_owner == Self, "invariant");
876+
assert(owner_raw() == Self, "invariant");
877877

878878
UnlinkAfterAcquire(Self, &node);
879879
if (_succ == Self) _succ = NULL;
@@ -949,7 +949,7 @@ void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
949949
for (;;) {
950950
ObjectWaiter::TStates v = SelfNode->TState;
951951
guarantee(v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant");
952-
assert(_owner != Self, "invariant");
952+
assert(owner_raw() != Self, "invariant");
953953

954954
if (TryLock(Self) > 0) break;
955955
if (TrySpin(Self) > 0) break;
@@ -1008,7 +1008,7 @@ void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
10081008
// The head of cxq is volatile but the interior is stable.
10091009
// In addition, Self.TState is stable.
10101010

1011-
assert(_owner == Self, "invariant");
1011+
assert(owner_raw() == Self, "invariant");
10121012
assert(object()->mark() == markWord::encode(this), "invariant");
10131013
UnlinkAfterAcquire(Self, SelfNode);
10141014
if (_succ == Self) _succ = NULL;
@@ -1022,7 +1022,7 @@ void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
10221022
// unlinking the thread until ::exit()-time.
10231023

10241024
void ObjectMonitor::UnlinkAfterAcquire(Thread *Self, ObjectWaiter *SelfNode) {
1025-
assert(_owner == Self, "invariant");
1025+
assert(owner_raw() == Self, "invariant");
10261026
assert(SelfNode->_thread == Self, "invariant");
10271027

10281028
if (SelfNode->TState == ObjectWaiter::TS_ENTER) {
@@ -1142,7 +1142,7 @@ void ObjectMonitor::UnlinkAfterAcquire(Thread *Self, ObjectWaiter *SelfNode) {
11421142

11431143
void ObjectMonitor::exit(bool not_suspended, TRAPS) {
11441144
Thread* const Self = THREAD;
1145-
void* cur = Atomic::load(&_owner);
1145+
void* cur = owner_raw();
11461146
if (THREAD != cur) {
11471147
if (THREAD->is_lock_owned((address)cur)) {
11481148
assert(_recursions == 0, "invariant");
@@ -1188,7 +1188,7 @@ void ObjectMonitor::exit(bool not_suspended, TRAPS) {
11881188
#endif
11891189

11901190
for (;;) {
1191-
assert(THREAD == _owner, "invariant");
1191+
assert(THREAD == owner_raw(), "invariant");
11921192

11931193
// Drop the lock.
11941194
// release semantics: prior loads and stores from within the critical section
@@ -1244,7 +1244,7 @@ void ObjectMonitor::exit(bool not_suspended, TRAPS) {
12441244
return;
12451245
}
12461246

1247-
guarantee(_owner == THREAD, "invariant");
1247+
guarantee(owner_raw() == THREAD, "invariant");
12481248

12491249
ObjectWaiter * w = NULL;
12501250

@@ -1356,7 +1356,7 @@ bool ObjectMonitor::ExitSuspendEquivalent(JavaThread * jSelf) {
13561356

13571357

13581358
void ObjectMonitor::ExitEpilog(Thread * Self, ObjectWaiter * Wakee) {
1359-
assert(_owner == Self, "invariant");
1359+
assert(owner_raw() == Self, "invariant");
13601360

13611361
// Exit protocol:
13621362
// 1. ST _succ = wakee
@@ -1400,7 +1400,7 @@ intx ObjectMonitor::complete_exit(TRAPS) {
14001400

14011401
assert(InitDone, "Unexpectedly not initialized");
14021402

1403-
void* cur = Atomic::load(&_owner);
1403+
void* cur = owner_raw();
14041404
if (THREAD != cur) {
14051405
if (THREAD->is_lock_owned((address)cur)) {
14061406
assert(_recursions == 0, "internal state error");
@@ -1409,11 +1409,11 @@ intx ObjectMonitor::complete_exit(TRAPS) {
14091409
}
14101410
}
14111411

1412-
guarantee(Self == _owner, "complete_exit not owner");
1412+
guarantee(Self == owner_raw(), "complete_exit not owner");
14131413
intx save = _recursions; // record the old recursion count
14141414
_recursions = 0; // set the recursion level to be 0
14151415
exit(true, Self); // exit the monitor
1416-
guarantee(_owner != Self, "invariant");
1416+
guarantee(owner_raw() != Self, "invariant");
14171417
return save;
14181418
}
14191419

@@ -1423,7 +1423,7 @@ bool ObjectMonitor::reenter(intx recursions, TRAPS) {
14231423
Thread * const Self = THREAD;
14241424
JavaThread * jt = Self->as_Java_thread();
14251425

1426-
guarantee(_owner != Self, "reenter already owner");
1426+
guarantee(owner_raw() != Self, "reenter already owner");
14271427
if (!enter(THREAD)) {
14281428
return false;
14291429
}
@@ -1451,7 +1451,7 @@ bool ObjectMonitor::reenter(intx recursions, TRAPS) {
14511451
// (IMSE). If there is a pending exception and the specified thread
14521452
// is not the owner, that exception will be replaced by the IMSE.
14531453
bool ObjectMonitor::check_owner(Thread* THREAD) {
1454-
void* cur = Atomic::load(&_owner);
1454+
void* cur = owner_raw();
14551455
if (cur == THREAD) {
14561456
return true;
14571457
}
@@ -1549,7 +1549,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
15491549
_waiters++; // increment the number of waiters
15501550
_recursions = 0; // set the recursion level to be 1
15511551
exit(true, Self); // exit the monitor
1552-
guarantee(_owner != Self, "invariant");
1552+
guarantee(owner_raw() != Self, "invariant");
15531553

15541554
// The thread is on the WaitSet list - now park() it.
15551555
// On MP systems it's conceivable that a brief spin before we park
@@ -1664,7 +1664,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
16641664
assert(Self->_Stalled != 0, "invariant");
16651665
Self->_Stalled = 0;
16661666

1667-
assert(_owner != Self, "invariant");
1667+
assert(owner_raw() != Self, "invariant");
16681668
ObjectWaiter::TStates v = node.TState;
16691669
if (v == ObjectWaiter::TS_RUN) {
16701670
enter(Self);
@@ -1679,7 +1679,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
16791679
// Node is about to go out-of-scope, but even if it were immortal we wouldn't
16801680
// want residual elements associated with this thread left on any lists.
16811681
guarantee(node.TState == ObjectWaiter::TS_RUN, "invariant");
1682-
assert(_owner == Self, "invariant");
1682+
assert(owner_raw() == Self, "invariant");
16831683
assert(_succ != Self, "invariant");
16841684
} // OSThreadWaitState()
16851685

@@ -1691,7 +1691,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
16911691
_waiters--; // decrement the number of waiters
16921692

16931693
// Verify a few postconditions
1694-
assert(_owner == Self, "invariant");
1694+
assert(owner_raw() == Self, "invariant");
16951695
assert(_succ != Self, "invariant");
16961696
assert(object()->mark() == markWord::encode(this), "invariant");
16971697

@@ -1920,7 +1920,7 @@ int ObjectMonitor::TrySpin(Thread * Self) {
19201920
ctr = _SpinDuration;
19211921
if (ctr <= 0) return 0;
19221922

1923-
if (NotRunnable(Self, (Thread *) _owner)) {
1923+
if (NotRunnable(Self, (Thread *) owner_raw())) {
19241924
return 0;
19251925
}
19261926

@@ -1966,7 +1966,7 @@ int ObjectMonitor::TrySpin(Thread * Self) {
19661966
// the spin without prejudice or apply a "penalty" to the
19671967
// spin count-down variable "ctr", reducing it by 100, say.
19681968

1969-
Thread * ox = (Thread *) _owner;
1969+
Thread * ox = (Thread *) owner_raw();
19701970
if (ox == NULL) {
19711971
ox = (Thread*)try_set_owner_from(NULL, Self);
19721972
if (ox == NULL) {
@@ -2092,7 +2092,7 @@ int ObjectMonitor::NotRunnable(Thread * Self, Thread * ox) {
20922092

20932093
if (BlockedOn == 1) return 1;
20942094
if (BlockedOn != 0) {
2095-
return BlockedOn != intptr_t(this) && _owner == ox;
2095+
return BlockedOn != intptr_t(this) && owner_raw() == ox;
20962096
}
20972097

20982098
assert(sizeof(((JavaThread *)ox)->_thread_state == sizeof(int)), "invariant");
@@ -2284,7 +2284,7 @@ void ObjectMonitor::print_debug_style_on(outputStream* st) const {
22842284
st->print_cr(" ...");
22852285
st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf0) - 1);
22862286
st->print_cr(" }");
2287-
st->print_cr(" _owner = " INTPTR_FORMAT, p2i(_owner));
2287+
st->print_cr(" _owner = " INTPTR_FORMAT, p2i(owner_raw()));
22882288
st->print_cr(" _previous_owner_tid = " JLONG_FORMAT, _previous_owner_tid);
22892289
st->print_cr(" _pad_buf1 = {");
22902290
st->print_cr(" [0] = '\\0'");

src/hotspot/share/runtime/objectMonitor.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,13 @@ class ObjectMonitor : public CHeapObj<mtInternal> {
147147
sizeof(WeakHandle));
148148
// Used by async deflation as a marker in the _owner field:
149149
#define DEFLATER_MARKER reinterpret_cast<void*>(-1)
150-
void* volatile _owner; // pointer to owning thread OR BasicLock
150+
void* _owner; // pointer to owning thread OR BasicLock
151151
volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
152152
// Separate _owner and _next_om on different cache lines since
153153
// both can have busy multi-threaded access. _previous_owner_tid is only
154154
// changed by ObjectMonitor::exit() so it is a good choice to share the
155155
// cache line with _owner.
156-
DEFINE_PAD_MINUS_SIZE(1, OM_CACHE_LINE_SIZE, sizeof(void* volatile) +
156+
DEFINE_PAD_MINUS_SIZE(1, OM_CACHE_LINE_SIZE, sizeof(void*) +
157157
sizeof(volatile jlong));
158158
ObjectMonitor* _next_om; // Next ObjectMonitor* linkage
159159
volatile intx _recursions; // recursion count, 0 for first entry
@@ -242,8 +242,8 @@ class ObjectMonitor : public CHeapObj<mtInternal> {
242242
if (contentions() > 0) {
243243
ret_code |= contentions();
244244
}
245-
if (_owner != DEFLATER_MARKER) {
246-
ret_code |= intptr_t(_owner);
245+
if (!owner_is_DEFLATER_MARKER()) {
246+
ret_code |= intptr_t(owner_raw());
247247
}
248248
return ret_code;
249249
}
@@ -252,8 +252,9 @@ class ObjectMonitor : public CHeapObj<mtInternal> {
252252
intptr_t is_entered(Thread* current) const;
253253

254254
void* owner() const; // Returns NULL if DEFLATER_MARKER is observed.
255+
void* owner_raw() const;
255256
// Returns true if owner field == DEFLATER_MARKER and false otherwise.
256-
bool owner_is_DEFLATER_MARKER();
257+
bool owner_is_DEFLATER_MARKER() const;
257258
// Returns true if 'this' is being async deflated and false otherwise.
258259
bool is_being_async_deflated();
259260
// Clear _owner field; current value must match old_value.

src/hotspot/share/runtime/objectMonitor.inline.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
#include "runtime/synchronizer.hpp"
3232

3333
inline intptr_t ObjectMonitor::is_entered(TRAPS) const {
34-
if (THREAD == _owner || THREAD->is_lock_owned((address) _owner)) {
34+
void* owner = owner_raw();
35+
if (THREAD == owner || THREAD->is_lock_owned((address)owner)) {
3536
return 1;
3637
}
3738
return 0;
@@ -55,15 +56,19 @@ inline jint ObjectMonitor::waiters() const {
5556

5657
// Returns NULL if DEFLATER_MARKER is observed.
5758
inline void* ObjectMonitor::owner() const {
58-
void* owner = _owner;
59+
void* owner = owner_raw();
5960
return owner != DEFLATER_MARKER ? owner : NULL;
6061
}
6162

63+
inline void* ObjectMonitor::owner_raw() const {
64+
return Atomic::load(&_owner);
65+
}
66+
6267
// Returns true if owner field == DEFLATER_MARKER and false otherwise.
6368
// This accessor is called when we really need to know if the owner
6469
// field == DEFLATER_MARKER and any non-NULL value won't do the trick.
65-
inline bool ObjectMonitor::owner_is_DEFLATER_MARKER() {
66-
return Atomic::load(&_owner) == DEFLATER_MARKER;
70+
inline bool ObjectMonitor::owner_is_DEFLATER_MARKER() const {
71+
return owner_raw() == DEFLATER_MARKER;
6772
}
6873

6974
// Returns true if 'this' is being async deflated and false otherwise.

src/hotspot/share/runtime/synchronizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
341341
if (m->object_peek() == NULL) {
342342
return false;
343343
}
344-
Thread* const owner = (Thread *) m->_owner;
344+
Thread* const owner = (Thread *) m->owner_raw();
345345

346346
// Lock contention and Transactional Lock Elision (TLE) diagnostics
347347
// and observability

0 commit comments

Comments
 (0)