< prev index next >
src/hotspot/share/runtime/objectMonitor.cpp
Print this page
rev 56775 : imported patch 8230876.patch
rev 56776 : v2.00 -> v2.07 (CR7/v2.07/10-for-jdk14) patches combined into one; merge with 8230876.patch (2019.10.17) and jdk-14+21.
rev 56777 : See CR7-to-CR8-changes.
*** 237,247 ****
// -----------------------------------------------------------------------------
// Enter support
void ObjectMonitor::enter(TRAPS) {
! ADIM_guarantee(ref_count() > 0, "must be positive: ref_count=%d", ref_count());
// The following code is ordered to check the most common cases first
// and to reduce RTS->RTO cache line upgrades on SPARC and IA32 processors.
Thread * const Self = THREAD;
--- 237,248 ----
// -----------------------------------------------------------------------------
// Enter support
void ObjectMonitor::enter(TRAPS) {
! jint l_ref_count = ref_count();
! ADIM_guarantee(l_ref_count > 0, "must be positive: l_ref_count=%d, ref_count=%d", l_ref_count, ref_count());
// The following code is ordered to check the most common cases first
// and to reduce RTS->RTO cache line upgrades on SPARC and IA32 processors.
Thread * const Self = THREAD;
*** 255,268 ****
// TODO-FIXME: check for integer overflow! BUGID 6557169.
_recursions++;
return;
}
! if (Self->is_lock_owned ((address)cur)) {
assert(_recursions == 0, "internal state error");
_recursions = 1;
! set_owner_from_BasicLock(Self, cur); // Convert from BasicLock* to Thread*.
return;
}
if (AsyncDeflateIdleMonitors &&
try_set_owner_from(Self, DEFLATER_MARKER) == DEFLATER_MARKER) {
--- 256,269 ----
// TODO-FIXME: check for integer overflow! BUGID 6557169.
_recursions++;
return;
}
! if (Self->is_lock_owned((address)cur)) {
assert(_recursions == 0, "internal state error");
_recursions = 1;
! simply_set_owner_from_BasicLock(Self, cur); // Convert from BasicLock* to Thread*.
return;
}
if (AsyncDeflateIdleMonitors &&
try_set_owner_from(Self, DEFLATER_MARKER) == DEFLATER_MARKER) {
*** 298,308 ****
assert(_succ != Self, "invariant");
assert(Self->is_Java_thread(), "invariant");
JavaThread * jt = (JavaThread *) Self;
assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
assert(jt->thread_state() != _thread_blocked, "invariant");
! assert(AsyncDeflateIdleMonitors || this->object() != NULL, "invariant");
assert(_contentions >= 0, "must not be negative: contentions=%d", _contentions);
// Prevent deflation. See ObjectSynchronizer::deflate_monitor(),
// ObjectSynchronizer::deflate_monitor_using_JT() and is_busy().
// Ensure the object <-> monitor relationship remains stable while
--- 299,309 ----
assert(_succ != Self, "invariant");
assert(Self->is_Java_thread(), "invariant");
JavaThread * jt = (JavaThread *) Self;
assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
assert(jt->thread_state() != _thread_blocked, "invariant");
! assert(this->object() != NULL, "invariant");
assert(_contentions >= 0, "must not be negative: contentions=%d", _contentions);
// Prevent deflation. See ObjectSynchronizer::deflate_monitor(),
// ObjectSynchronizer::deflate_monitor_using_JT() and is_busy().
// Ensure the object <-> monitor relationship remains stable while
*** 504,524 ****
if (!AsyncDeflateIdleMonitors) {
ss->print("owner=" INTPTR_FORMAT, p2i(_owner));
} else if (_owner != DEFLATER_MARKER) {
ss->print("owner=" INTPTR_FORMAT, p2i(_owner));
} else {
ss->print("owner=" INTPTR_FORMAT, NULL);
}
ss->print(", cxq=" INTPTR_FORMAT ", EntryList=" INTPTR_FORMAT, p2i(_cxq),
p2i(_EntryList));
return ss->base();
}
#define MAX_RECHECK_INTERVAL 1000
void ObjectMonitor::EnterI(TRAPS) {
! ADIM_guarantee(ref_count() > 0, "must be positive: ref_count=%d", ref_count());
Thread * const Self = THREAD;
assert(Self->is_Java_thread(), "invariant");
assert(((JavaThread *) Self)->thread_state() == _thread_blocked, "invariant");
--- 505,528 ----
if (!AsyncDeflateIdleMonitors) {
ss->print("owner=" INTPTR_FORMAT, p2i(_owner));
} else if (_owner != DEFLATER_MARKER) {
ss->print("owner=" INTPTR_FORMAT, p2i(_owner));
} else {
+ // We report NULL instead of DEFLATER_MARKER here because is_busy()
+ // ignores DEFLATER_MARKER values.
ss->print("owner=" INTPTR_FORMAT, NULL);
}
ss->print(", cxq=" INTPTR_FORMAT ", EntryList=" INTPTR_FORMAT, p2i(_cxq),
p2i(_EntryList));
return ss->base();
}
#define MAX_RECHECK_INTERVAL 1000
void ObjectMonitor::EnterI(TRAPS) {
! jint l_ref_count = ref_count();
! ADIM_guarantee(l_ref_count > 0, "must be positive: l_ref_count=%d, ref_count=%d", l_ref_count, ref_count());
Thread * const Self = THREAD;
assert(Self->is_Java_thread(), "invariant");
assert(((JavaThread *) Self)->thread_state() == _thread_blocked, "invariant");
*** 768,778 ****
// monitor reentry in wait().
//
// In the future we should reconcile EnterI() and ReenterI().
void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
! ADIM_guarantee(ref_count() > 0, "must be positive: ref_count=%d", ref_count());
assert(Self != NULL, "invariant");
assert(SelfNode != NULL, "invariant");
assert(SelfNode->_thread == Self, "invariant");
assert(_waiters > 0, "invariant");
--- 772,783 ----
// monitor reentry in wait().
//
// In the future we should reconcile EnterI() and ReenterI().
void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
! jint l_ref_count = ref_count();
! ADIM_guarantee(l_ref_count > 0, "must be positive: l_ref_count=%d, ref_count=%d", l_ref_count, ref_count());
assert(Self != NULL, "invariant");
assert(SelfNode != NULL, "invariant");
assert(SelfNode->_thread == Self, "invariant");
assert(_waiters > 0, "invariant");
*** 988,998 ****
Thread * const Self = THREAD;
if (THREAD != _owner) {
void* cur = _owner;
if (THREAD->is_lock_owned((address)cur)) {
assert(_recursions == 0, "invariant");
! set_owner_from_BasicLock(Self, cur); // Convert from BasicLock* to Thread*.
_recursions = 0;
} else {
// Apparent unbalanced locking ...
// Naively we'd like to throw IllegalMonitorStateException.
// As a practical matter we can neither allocate nor throw an
--- 993,1003 ----
Thread * const Self = THREAD;
if (THREAD != _owner) {
void* cur = _owner;
if (THREAD->is_lock_owned((address)cur)) {
assert(_recursions == 0, "invariant");
! simply_set_owner_from_BasicLock(Self, cur); // Convert from BasicLock* to Thread*.
_recursions = 0;
} else {
// Apparent unbalanced locking ...
// Naively we'd like to throw IllegalMonitorStateException.
// As a practical matter we can neither allocate nor throw an
*** 1034,1045 ****
for (;;) {
assert(THREAD == _owner, "invariant");
// release semantics: prior loads and stores from within the critical section
// must not float (reorder) past the following store that drops the lock.
- // On SPARC that requires MEMBAR #loadstore|#storestore.
- // But of course in TSO #loadstore|#storestore is not required.
if (AsyncDeflateIdleMonitors) {
set_owner_from(NULL, Self);
} else {
OrderAccess::release_store(&_owner, (void*)NULL); // drop the lock
OrderAccess::storeload(); // See if we need to wake a successor
--- 1039,1048 ----
*** 1251,1261 ****
if (THREAD != _owner) {
void* cur = _owner;
if (THREAD->is_lock_owned((address)cur)) {
assert(_recursions == 0, "internal state error");
! set_owner_from_BasicLock(Self, cur); // Convert from BasicLock* to Thread*.
_recursions = 0;
}
}
guarantee(Self == _owner, "complete_exit not owner");
--- 1254,1264 ----
if (THREAD != _owner) {
void* cur = _owner;
if (THREAD->is_lock_owned((address)cur)) {
assert(_recursions == 0, "internal state error");
! simply_set_owner_from_BasicLock(Self, cur); // Convert from BasicLock* to Thread*.
_recursions = 0;
}
}
guarantee(Self == _owner, "complete_exit not owner");
*** 1301,1311 ****
if (_owner == THREAD) {
return true;
}
void* cur = _owner;
if (THREAD->is_lock_owned((address)cur)) {
! set_owner_from_BasicLock(THREAD, cur); // Convert from BasicLock* to Thread*.
_recursions = 0;
return true;
}
THROW_MSG_(vmSymbols::java_lang_IllegalMonitorStateException(),
"current thread is not owner", false);
--- 1304,1314 ----
if (_owner == THREAD) {
return true;
}
void* cur = _owner;
if (THREAD->is_lock_owned((address)cur)) {
! simply_set_owner_from_BasicLock(THREAD, cur); // Convert from BasicLock* to Thread*.
_recursions = 0;
return true;
}
THROW_MSG_(vmSymbols::java_lang_IllegalMonitorStateException(),
"current thread is not owner", false);
*** 2070,2085 ****
}
DEBUG_ONLY(InitDone = true;)
}
- // For internal use by ObjectSynchronizer::monitors_iterate().
- ObjectMonitorHandle::ObjectMonitorHandle(ObjectMonitor * om_ptr) {
- om_ptr->inc_ref_count();
- _om_ptr = om_ptr;
- }
-
ObjectMonitorHandle::~ObjectMonitorHandle() {
if (_om_ptr != NULL) {
_om_ptr->dec_ref_count();
_om_ptr = NULL;
}
--- 2073,2082 ----
*** 2097,2107 ****
//
bool ObjectMonitorHandle::save_om_ptr(oop object, markWord mark) {
guarantee(mark.has_monitor(), "sanity check: mark=" INTPTR_FORMAT,
mark.value());
! ObjectMonitor * om_ptr = mark.monitor();
om_ptr->inc_ref_count();
if (AsyncDeflateIdleMonitors) {
// Race here if monitor is not owned! The above ref_count bump
// will cause subsequent async deflation to skip it. However,
--- 2094,2104 ----
//
bool ObjectMonitorHandle::save_om_ptr(oop object, markWord mark) {
guarantee(mark.has_monitor(), "sanity check: mark=" INTPTR_FORMAT,
mark.value());
! ObjectMonitor* om_ptr = mark.monitor();
om_ptr->inc_ref_count();
if (AsyncDeflateIdleMonitors) {
// Race here if monitor is not owned! The above ref_count bump
// will cause subsequent async deflation to skip it. However,
*** 2139,2149 ****
_om_ptr = om_ptr;
return true;
}
// For internal use by ObjectSynchronizer::inflate().
! void ObjectMonitorHandle::set_om_ptr(ObjectMonitor * om_ptr) {
if (_om_ptr == NULL) {
ADIM_guarantee(om_ptr != NULL, "cannot clear an unset om_ptr");
om_ptr->inc_ref_count();
_om_ptr = om_ptr;
} else {
--- 2136,2148 ----
_om_ptr = om_ptr;
return true;
}
// For internal use by ObjectSynchronizer::inflate().
! // This function is only used when we don't have to worry about async
! // deflation of the specified ObjectMonitor*.
! void ObjectMonitorHandle::set_om_ptr(ObjectMonitor* om_ptr) {
if (_om_ptr == NULL) {
ADIM_guarantee(om_ptr != NULL, "cannot clear an unset om_ptr");
om_ptr->inc_ref_count();
_om_ptr = om_ptr;
} else {
*** 2151,2160 ****
--- 2150,2205 ----
_om_ptr->dec_ref_count();
_om_ptr = NULL;
}
}
+ // Save the specified ObjectMonitor* if it is safe, i.e., not being
+ // async deflated.
+ //
+ // This function returns true if the ObjectMonitor* has been safely
+ // saved. This function returns false if the specified ObjectMonitor*
+ // is NULL or if we have lost a race with async deflation; the caller
+ // can retry as appropriate.
+ bool ObjectMonitorHandle::set_om_ptr_if_safe(ObjectMonitor* om_ptr) {
+ if (om_ptr == NULL) {
+ return false; // Nothing to save if input is NULL
+ }
+
+ om_ptr->inc_ref_count();
+
+ if (AsyncDeflateIdleMonitors) {
+ if (om_ptr->owner_is_DEFLATER_MARKER() && om_ptr->ref_count() <= 0) {
+ // Async deflation is in progress and our ref_count increment
+ // above lost the race to async deflation.
+ om_ptr->dec_ref_count();
+ return false;
+ }
+ if (om_ptr->ref_count() <= 0) {
+ // Async deflation is in the process of bailing out, but has not
+ // yet restored the ref_count field so we return false to force
+ // a retry. We want a positive ref_count value for a true return.
+ om_ptr->dec_ref_count();
+ return false;
+ }
+ // Unlike save_om_ptr(), we don't have context to determine if
+ // the ObjectMonitor has been deflated and reused for another
+ // object.
+ }
+
+ ADIM_guarantee(_om_ptr == NULL, "sanity check: _om_ptr=" INTPTR_FORMAT,
+ p2i(_om_ptr));
+ _om_ptr = om_ptr;
+ return true;
+ }
+
+ // Unset the _om_ptr field and decrement the ref_count field.
+ void ObjectMonitorHandle::unset_om_ptr() {
+ ADIM_guarantee(_om_ptr != NULL, "_om_ptr must not be NULL");
+ _om_ptr->dec_ref_count();
+ _om_ptr = NULL;
+ }
+
void ObjectMonitor::print_on(outputStream* st) const {
// The minimal things to print for markWord printing, more can be added for debugging and logging.
st->print("{contentions=0x%08x,waiters=0x%08x"
",recursions=" INTX_FORMAT ",owner=" INTPTR_FORMAT "}",
contentions(), waiters(), recursions(),
*** 2199,2209 ****
// _waiters = 1
// _WaitSetLock = 0
// }
//
void ObjectMonitor::print_debug_style_on(outputStream* st) const {
! st->print_cr("(ObjectMonitor *) " INTPTR_FORMAT " = {", p2i(this));
st->print_cr(" _header = " INTPTR_FORMAT, header().value());
st->print_cr(" _object = " INTPTR_FORMAT, p2i(_object));
st->print(" _allocation_state = ");
if (is_free()) {
st->print("Free");
--- 2244,2254 ----
// _waiters = 1
// _WaitSetLock = 0
// }
//
void ObjectMonitor::print_debug_style_on(outputStream* st) const {
! st->print_cr("(ObjectMonitor*) " INTPTR_FORMAT " = {", p2i(this));
st->print_cr(" _header = " INTPTR_FORMAT, header().value());
st->print_cr(" _object = " INTPTR_FORMAT, p2i(_object));
st->print(" _allocation_state = ");
if (is_free()) {
st->print("Free");
< prev index next >