< 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 >