< prev index next >

src/hotspot/share/runtime/objectMonitor.cpp

Print this page
rev 57232 : v2.00 -> v2.08 (CR8/v2.08/11-for-jdk14) patches combined into one; merge with jdk-14+25 snapshot; merge with jdk-14+26 snapshot.
rev 57233 : See CR8-to-CR9-changes; merge with 8230876.patch (2019.11.15); merge with jdk-14+25 snapshot; fuzzy merge with jdk-14+26 snapshot.

*** 304,318 **** 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 ! // there's contention. ! Atomic::add(&_contentions, 1); JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);) EventJavaMonitorEnter event; if (event.should_commit()) { event.set_monitorClass(((oop)this->object())->klass()); --- 304,315 ---- 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); ! // Keep track of contention for JVM/TI and M&M queries. ! Atomic::inc(&_contentions); JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);) EventJavaMonitorEnter event; if (event.should_commit()) { event.set_monitorClass(((oop)this->object())->klass());
*** 946,957 **** // inopportune) reclamation of "this". // // We'd like to assert that: (THREAD->thread_state() != _thread_blocked) ; // There's one exception to the claim above, however. EnterI() can call // exit() to drop a lock if the acquirer has been externally suspended. ! // In that case exit() is called with _thread_state as _thread_blocked, ! // but the monitor's _contentions field is > 0, which inhibits reclamation. // // 1-0 exit // ~~~~~~~~ // ::exit() uses a canonical 1-1 idiom with a MEMBAR although some of // the fast-path operators have been optimized so the common ::exit() --- 943,954 ---- // inopportune) reclamation of "this". // // We'd like to assert that: (THREAD->thread_state() != _thread_blocked) ; // There's one exception to the claim above, however. EnterI() can call // exit() to drop a lock if the acquirer has been externally suspended. ! // In that case exit() is called with _thread_state == _thread_blocked, ! // but the monitor's ref_count is > 0, which inhibits reclamation. // // 1-0 exit // ~~~~~~~~ // ::exit() uses a canonical 1-1 idiom with a MEMBAR although some of // the fast-path operators have been optimized so the common ::exit()
*** 1007,1026 **** // see x86_32.ad Fast_Unlock() and the I1 and I2 properties. // Upon deeper reflection, however, in a properly run JVM the only // way we should encounter this situation is in the presence of // unbalanced JNI locking. TODO: CheckJNICalls. // See also: CR4414101 ! //#ifdef ASSERT LogStreamHandle(Error, monitorinflation) lsh; lsh.print_cr("ERROR: ObjectMonitor::exit(): thread=" INTPTR_FORMAT " is exiting an ObjectMonitor it does not own.", p2i(THREAD)); lsh.print_cr("The imbalance is possibly caused by JNI locking."); print_debug_style_on(&lsh); ! //#endif ! // Changing this from an assert() to ADIM_guarantee() may run ! // afoul of any test that is inducing non-balanced JNI locking. ! ADIM_guarantee(false, "Non-balanced monitor enter/exit!"); return; } } if (_recursions != 0) { --- 1004,1021 ---- // see x86_32.ad Fast_Unlock() and the I1 and I2 properties. // Upon deeper reflection, however, in a properly run JVM the only // way we should encounter this situation is in the presence of // unbalanced JNI locking. TODO: CheckJNICalls. // See also: CR4414101 ! #ifdef ASSERT LogStreamHandle(Error, monitorinflation) lsh; lsh.print_cr("ERROR: ObjectMonitor::exit(): thread=" INTPTR_FORMAT " is exiting an ObjectMonitor it does not own.", p2i(THREAD)); lsh.print_cr("The imbalance is possibly caused by JNI locking."); print_debug_style_on(&lsh); ! #endif ! assert(false, "Non-balanced monitor enter/exit!"); return; } } if (_recursions != 0) {
*** 1041,1058 **** #endif 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. ! if (AsyncDeflateIdleMonitors) { ! set_owner_from(NULL, Self); ! } else { ! Atomic::release_store(&_owner, (void*)NULL); // drop the lock ! OrderAccess::storeload(); // See if we need to wake a successor ! } if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) { return; } // Other threads are blocked trying to acquire the lock. --- 1036,1053 ---- #endif for (;;) { assert(THREAD == _owner, "invariant"); + // Drop the lock. // release semantics: prior loads and stores from within the critical section // must not float (reorder) past the following store that drops the lock. ! // Uses a storeload to separate release_store(owner) from the ! // successor check. The try_set_owner() below uses cmpxchg() so ! // we get the fence down there. ! release_clear_owner_with_barrier(Self, /* needs_fence */ false); ! if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) { return; } // Other threads are blocked trying to acquire the lock.
*** 1222,1238 **** // Hygiene -- once we've set _owner = NULL we can't safely dereference Wakee again. // The thread associated with Wakee may have grabbed the lock and "Wakee" may be // out-of-scope (non-extant). Wakee = NULL; ! // Drop the lock ! if (AsyncDeflateIdleMonitors) { ! set_owner_from(NULL, Self); ! } else { ! Atomic::release_store(&_owner, (void*)NULL); ! OrderAccess::fence(); // ST _owner vs LD in unpark() ! } DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self); Trigger->unpark(); // Maintain stats and report events to JVMTI --- 1217,1229 ---- // Hygiene -- once we've set _owner = NULL we can't safely dereference Wakee again. // The thread associated with Wakee may have grabbed the lock and "Wakee" may be // out-of-scope (non-extant). Wakee = NULL; ! // Drop the lock. ! // Uses a fence to separate release_store(owner) from the LD in unpark(). ! release_clear_owner_with_barrier(Self, /* needs_fence */ true); DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self); Trigger->unpark(); // Maintain stats and report events to JVMTI
*** 2099,2110 **** // This function returns true if the ObjectMonitor* has been safely // saved. This function returns false if we have lost a race with // async deflation; the caller should retry as appropriate. // 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) { --- 2090,2103 ---- // This function returns true if the ObjectMonitor* has been safely // saved. This function returns false if we have lost a race with // async deflation; the caller should retry as appropriate. // bool ObjectMonitorHandle::save_om_ptr(oop object, markWord mark) { ! // is_marked() is a superset of has_monitor() so make sure we ! // are called with the proper markWord value. ! guarantee(mark.has_monitor() && !mark.is_marked(), "sanity check: mark=" ! INTPTR_FORMAT, mark.value()); ObjectMonitor* om_ptr = mark.monitor(); om_ptr->inc_ref_count(); if (AsyncDeflateIdleMonitors) {
*** 2213,2223 **** contentions(), waiters(), recursions(), p2i(owner())); } void ObjectMonitor::print() const { print_on(tty); } ! //#ifdef ASSERT // Print the ObjectMonitor like a debugger would: // // (ObjectMonitor) 0x00007fdfb6012e40 = { // _header = 0x0000000000000001 // _object = 0x000000070ff45fd0 --- 2206,2216 ---- contentions(), waiters(), recursions(), p2i(owner())); } void ObjectMonitor::print() const { print_on(tty); } ! #ifdef ASSERT // Print the ObjectMonitor like a debugger would: // // (ObjectMonitor) 0x00007fdfb6012e40 = { // _header = 0x0000000000000001 // _object = 0x000000070ff45fd0
*** 2285,2295 **** st->print_cr(" _pad_buf2 = {"); st->print_cr(" [0] = '\\0'"); st->print_cr(" ..."); st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf1) - 1); st->print_cr(" }"); ! st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(_next_om)); st->print_cr(" _recursions = " INTX_FORMAT, _recursions); st->print_cr(" _EntryList = " INTPTR_FORMAT, p2i(_EntryList)); st->print_cr(" _cxq = " INTPTR_FORMAT, p2i(_cxq)); st->print_cr(" _succ = " INTPTR_FORMAT, p2i(_succ)); st->print_cr(" _Responsible = " INTPTR_FORMAT, p2i(_Responsible)); --- 2278,2288 ---- st->print_cr(" _pad_buf2 = {"); st->print_cr(" [0] = '\\0'"); st->print_cr(" ..."); st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf1) - 1); st->print_cr(" }"); ! st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(Atomic::load(&_next_om))); st->print_cr(" _recursions = " INTX_FORMAT, _recursions); st->print_cr(" _EntryList = " INTPTR_FORMAT, p2i(_EntryList)); st->print_cr(" _cxq = " INTPTR_FORMAT, p2i(_cxq)); st->print_cr(" _succ = " INTPTR_FORMAT, p2i(_succ)); st->print_cr(" _Responsible = " INTPTR_FORMAT, p2i(_Responsible));
*** 2299,2304 **** st->print_cr(" _WaitSet = " INTPTR_FORMAT, p2i(_WaitSet)); st->print_cr(" _waiters = %d", _waiters); st->print_cr(" _WaitSetLock = %d", _WaitSetLock); st->print_cr("}"); } ! //#endif --- 2292,2297 ---- st->print_cr(" _WaitSet = " INTPTR_FORMAT, p2i(_WaitSet)); st->print_cr(" _waiters = %d", _waiters); st->print_cr(" _WaitSetLock = %d", _WaitSetLock); st->print_cr("}"); } ! #endif
< prev index next >