Skip to content

Commit a7a82b0

Browse files
author
Daniel D. Daugherty
committed
8235795: replace monitor list mux{Acquire,Release}(&gListLock) with spin locks
Reviewed-by: dholmes, coleenp, rehn
1 parent 8ff24c5 commit a7a82b0

File tree

6 files changed

+749
-310
lines changed

6 files changed

+749
-310
lines changed

src/hotspot/share/runtime/objectMonitor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1987,7 +1987,7 @@ void ObjectMonitor::print_debug_style_on(outputStream* st) const {
19871987
st->print_cr("(ObjectMonitor*) " INTPTR_FORMAT " = {", p2i(this));
19881988
st->print_cr(" _header = " INTPTR_FORMAT, header().value());
19891989
st->print_cr(" _object = " INTPTR_FORMAT, p2i(_object));
1990-
st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(_next_om));
1990+
st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(next_om()));
19911991
st->print_cr(" _pad_buf0 = {");
19921992
st->print_cr(" [0] = '\\0'");
19931993
st->print_cr(" ...");

src/hotspot/share/runtime/objectMonitor.hpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,22 @@ class ObjectMonitor {
136136
// Enforced by the assert() in header_addr().
137137
volatile markWord _header; // displaced object header word - mark
138138
void* volatile _object; // backward object pointer - strong root
139-
public:
140-
ObjectMonitor* _next_om; // Next ObjectMonitor* linkage
141139
private:
142140
// Separate _header and _owner on different cache lines since both can
143141
// have busy multi-threaded access. _header and _object are set at
144142
// initial inflation and _object doesn't change until deflation so
145143
// _object is a good choice to share the cache line with _header.
146-
// _next_om shares _header's cache line for pre-monitor list historical
147-
// reasons. _next_om only changes if the next ObjectMonitor is deflated.
148144
DEFINE_PAD_MINUS_SIZE(0, OM_CACHE_LINE_SIZE,
149-
sizeof(volatile markWord) + sizeof(void* volatile) +
150-
sizeof(ObjectMonitor *));
145+
sizeof(volatile markWord) + sizeof(void* volatile));
151146
void* volatile _owner; // pointer to owning thread OR BasicLock
152147
volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
148+
// Separate _owner and _next_om on different cache lines since
149+
// both can have busy multi-threaded access. _previous_owner_tid is only
150+
// changed by ObjectMonitor::exit() so it is a good choice to share the
151+
// cache line with _owner.
152+
DEFINE_PAD_MINUS_SIZE(1, OM_CACHE_LINE_SIZE, sizeof(void* volatile) +
153+
sizeof(volatile jlong));
154+
ObjectMonitor* _next_om; // Next ObjectMonitor* linkage
153155
volatile intx _recursions; // recursion count, 0 for first entry
154156
ObjectWaiter* volatile _EntryList; // Threads blocked on entry or reentry.
155157
// The list is actually composed of WaitNodes,
@@ -249,6 +251,14 @@ class ObjectMonitor {
249251
// _owner field. Returns the prior value of the _owner field.
250252
void* try_set_owner_from(void* old_value, void* new_value);
251253

254+
ObjectMonitor* next_om() const;
255+
// Simply set _next_om field to new_value.
256+
void set_next_om(ObjectMonitor* new_value);
257+
// Try to set _next_om field to new_value if the current value matches
258+
// old_value, using Atomic::cmpxchg(). Otherwise, does not change the
259+
// _next_om field. Returns the prior value of the _next_om field.
260+
ObjectMonitor* try_set_next_om(ObjectMonitor* old_value, ObjectMonitor* new_value);
261+
252262
jint waiters() const;
253263

254264
jint contentions() const;

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,24 @@ inline void* ObjectMonitor::try_set_owner_from(void* old_value, void* new_value)
137137
return prev;
138138
}
139139

140+
// The _next_om field can be concurrently read and modified so we
141+
// use Atomic operations to disable compiler optimizations that
142+
// might try to elide loading and/or storing this field.
143+
144+
inline ObjectMonitor* ObjectMonitor::next_om() const {
145+
return Atomic::load(&_next_om);
146+
}
147+
148+
// Simply set _next_om field to new_value.
149+
inline void ObjectMonitor::set_next_om(ObjectMonitor* new_value) {
150+
Atomic::store(&_next_om, new_value);
151+
}
152+
153+
// Try to set _next_om field to new_value if the current value matches
154+
// old_value. Otherwise, does not change the _next_om field. Returns
155+
// the prior value of the _next_om field.
156+
inline ObjectMonitor* ObjectMonitor::try_set_next_om(ObjectMonitor* old_value, ObjectMonitor* new_value) {
157+
return Atomic::cmpxchg(&_next_om, old_value, new_value);
158+
}
159+
140160
#endif // SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP

0 commit comments

Comments
 (0)