8005849: JEP 167: Event-Based JVM Tracing

Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com>
Co-authored-by: Bengt Rutisson <bengt.rutisson@oracle.com>
Co-authored-by: Calvin Cheung <calvin.cheung@oracle.com>
Co-authored-by: Erik Gahlin <erik.gahlin@oracle.com>
Co-authored-by: Erik Helin <erik.helin@oracle.com>
Co-authored-by: Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>
Co-authored-by: Keith McGuigan <keith.mcguigan@oracle.com>
Co-authored-by: Mattias Tobiasson <mattias.tobiasson@oracle.com>
Co-authored-by: Markus Gronlund <markus.gronlund@oracle.com>
Co-authored-by: Mikael Auno <mikael.auno@oracle.com>
Co-authored-by: Nils Eliasson <nils.eliasson@oracle.com>
Co-authored-by: Nils Loodin <nils.loodin@oracle.com>
Co-authored-by: Rickard Backman <rickard.backman@oracle.com>
Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com>
Co-authored-by: Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
Reviewed-by: acorn, coleenp, sla
This commit is contained in:
Staffan Larsen 2013-06-10 11:30:51 +02:00
parent 6b2c468c35
commit 718f3252f6
195 changed files with 7628 additions and 1484 deletions

View file

@ -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 @@ void ATTR ObjectMonitor::enter(TRAPS) {
// 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 @@ void ATTR ObjectMonitor::enter(TRAPS) {
//
_recursions = 0 ;
_succ = NULL ;
exit (Self) ;
exit (false, Self) ;
jt->java_suspend_self();
}
@ -435,6 +440,14 @@ void ATTR ObjectMonitor::enter(TRAPS) {
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 @@ void ObjectMonitor::UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode)
// 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 @@ void ATTR ObjectMonitor::exit(TRAPS) {
_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 @@ intptr_t ObjectMonitor::complete_exit(TRAPS) {
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 @@ static int Adjust (volatile int * adr, int dx) {
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 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
// 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 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
// 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 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
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 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
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 @@ void ObjectMonitor::notify(TRAPS) {
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 @@ void ObjectMonitor::notifyAll(TRAPS) {
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 ;
}