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