diff -r f9e300086063 -r b7bcf7497f93 hotspot/src/share/vm/runtime/objectMonitor.cpp --- a/hotspot/src/share/vm/runtime/objectMonitor.cpp Fri Jun 07 09:33:01 2013 -0700 +++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp Mon Jun 10 11:30:51 2013 +0200 @@ -36,7 +36,10 @@ #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "services/threadService.hpp" +#include "trace/tracing.hpp" +#include "trace/traceMacros.hpp" #include "utilities/dtrace.hpp" +#include "utilities/macros.hpp" #include "utilities/preserveException.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -371,6 +374,8 @@ // Ensure the object-monitor relationship remains stable while there's contention. Atomic::inc_ptr(&_count); + EventJavaMonitorEnter event; + { // Change java thread status to indicate blocked on monitor enter. JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); @@ -402,7 +407,7 @@ // _recursions = 0 ; _succ = NULL ; - exit (Self) ; + exit (false, Self) ; jt->java_suspend_self(); } @@ -435,6 +440,14 @@ if (JvmtiExport::should_post_monitor_contended_entered()) { JvmtiExport::post_monitor_contended_entered(jt, this); } + + if (event.should_commit()) { + event.set_klass(((oop)this->object())->klass()); + event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid); + event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr())); + event.commit(); + } + if (ObjectMonitor::_sync_ContendedLockAttempts != NULL) { ObjectMonitor::_sync_ContendedLockAttempts->inc() ; } @@ -917,7 +930,7 @@ // Both impinge on OS scalability. Given that, at most one thread parked on // a monitor will use a timer. -void ATTR ObjectMonitor::exit(TRAPS) { +void ATTR ObjectMonitor::exit(bool not_suspended, TRAPS) { Thread * Self = THREAD ; if (THREAD != _owner) { if (THREAD->is_lock_owned((address) _owner)) { @@ -954,6 +967,14 @@ _Responsible = NULL ; } +#if INCLUDE_TRACE + // get the owner's thread id for the MonitorEnter event + // if it is enabled and the thread isn't suspended + if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) { + _previous_owner_tid = SharedRuntime::get_java_tid(Self); + } +#endif + for (;;) { assert (THREAD == _owner, "invariant") ; @@ -1343,7 +1364,7 @@ guarantee(Self == _owner, "complete_exit not owner"); intptr_t save = _recursions; // record the old recursion count _recursions = 0; // set the recursion level to be 0 - exit (Self) ; // exit the monitor + exit (true, Self) ; // exit the monitor guarantee (_owner != Self, "invariant"); return save; } @@ -1397,6 +1418,20 @@ for (v = *adr ; Atomic::cmpxchg (v + dx, adr, v) != v; v = *adr) ; return v ; } + +// helper method for posting a monitor wait event +void ObjectMonitor::post_monitor_wait_event(EventJavaMonitorWait* event, + jlong notifier_tid, + jlong timeout, + bool timedout) { + event->set_klass(((oop)this->object())->klass()); + event->set_timeout((TYPE_ULONG)timeout); + event->set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr())); + event->set_notifier((TYPE_OSTHREAD)notifier_tid); + event->set_timedOut((TYPE_BOOLEAN)timedout); + event->commit(); +} + // ----------------------------------------------------------------------------- // Wait/Notify/NotifyAll // @@ -1412,6 +1447,8 @@ // Throw IMSX or IEX. CHECK_OWNER(); + EventJavaMonitorWait event; + // check for a pending interrupt if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) { // post monitor waited event. Note that this is past-tense, we are done waiting. @@ -1420,10 +1457,14 @@ // wait was not timed out due to thread interrupt. JvmtiExport::post_monitor_waited(jt, this, false); } + if (event.should_commit()) { + post_monitor_wait_event(&event, 0, millis, false); + } TEVENT (Wait - Throw IEX) ; THROW(vmSymbols::java_lang_InterruptedException()); return ; } + TEVENT (Wait) ; assert (Self->_Stalled == 0, "invariant") ; @@ -1455,7 +1496,7 @@ intptr_t save = _recursions; // record the old recursion count _waiters++; // increment the number of waiters _recursions = 0; // set the recursion level to be 1 - exit (Self) ; // exit the monitor + exit (true, Self) ; // exit the monitor guarantee (_owner != Self, "invariant") ; // As soon as the ObjectMonitor's ownership is dropped in the exit() @@ -1555,6 +1596,11 @@ if (JvmtiExport::should_post_monitor_waited()) { JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT); } + + if (event.should_commit()) { + post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT); + } + OrderAccess::fence() ; assert (Self->_Stalled != 0, "invariant") ; @@ -1634,6 +1680,8 @@ iterator->TState = ObjectWaiter::TS_ENTER ; } iterator->_notified = 1 ; + Thread * Self = THREAD; + iterator->_notifier_tid = Self->osthread()->thread_id(); ObjectWaiter * List = _EntryList ; if (List != NULL) { @@ -1758,6 +1806,8 @@ guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ; guarantee (iterator->_notified == 0, "invariant") ; iterator->_notified = 1 ; + Thread * Self = THREAD; + iterator->_notifier_tid = Self->osthread()->thread_id(); if (Policy != 4) { iterator->TState = ObjectWaiter::TS_ENTER ; }