mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 22:04:51 +02:00
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:
parent
6b2c468c35
commit
718f3252f6
195 changed files with 7628 additions and 1484 deletions
|
@ -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 ;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue