22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/vmSymbols.hpp" |
26 #include "classfile/vmSymbols.hpp" |
|
27 #include "jfr/jfrEvents.hpp" |
|
28 #include "jfr/support/jfrThreadId.hpp" |
27 #include "memory/resourceArea.hpp" |
29 #include "memory/resourceArea.hpp" |
28 #include "oops/markOop.hpp" |
30 #include "oops/markOop.hpp" |
29 #include "oops/oop.inline.hpp" |
31 #include "oops/oop.inline.hpp" |
30 #include "runtime/handles.inline.hpp" |
32 #include "runtime/handles.inline.hpp" |
31 #include "runtime/interfaceSupport.hpp" |
33 #include "runtime/interfaceSupport.hpp" |
35 #include "runtime/orderAccess.inline.hpp" |
37 #include "runtime/orderAccess.inline.hpp" |
36 #include "runtime/osThread.hpp" |
38 #include "runtime/osThread.hpp" |
37 #include "runtime/stubRoutines.hpp" |
39 #include "runtime/stubRoutines.hpp" |
38 #include "runtime/thread.inline.hpp" |
40 #include "runtime/thread.inline.hpp" |
39 #include "services/threadService.hpp" |
41 #include "services/threadService.hpp" |
40 #include "trace/tracing.hpp" |
|
41 #include "trace/traceMacros.hpp" |
|
42 #include "utilities/dtrace.hpp" |
42 #include "utilities/dtrace.hpp" |
43 #include "utilities/macros.hpp" |
43 #include "utilities/macros.hpp" |
44 #include "utilities/preserveException.hpp" |
44 #include "utilities/preserveException.hpp" |
45 #ifdef TARGET_OS_FAMILY_linux |
45 #ifdef TARGET_OS_FAMILY_linux |
46 # include "os_linux.inline.hpp" |
46 # include "os_linux.inline.hpp" |
51 #ifdef TARGET_OS_FAMILY_windows |
51 #ifdef TARGET_OS_FAMILY_windows |
52 # include "os_windows.inline.hpp" |
52 # include "os_windows.inline.hpp" |
53 #endif |
53 #endif |
54 #ifdef TARGET_OS_FAMILY_bsd |
54 #ifdef TARGET_OS_FAMILY_bsd |
55 # include "os_bsd.inline.hpp" |
55 # include "os_bsd.inline.hpp" |
|
56 #endif |
|
57 #if INCLUDE_JFR |
|
58 #include "jfr/support/jfrFlush.hpp" |
56 #endif |
59 #endif |
57 |
60 |
58 #if defined(__GNUC__) && !defined(IA64) && !defined(PPC64) |
61 #if defined(__GNUC__) && !defined(IA64) && !defined(PPC64) |
59 // Need to inhibit inlining for older versions of GCC to avoid build-time failures |
62 // Need to inhibit inlining for older versions of GCC to avoid build-time failures |
60 #define ATTR __attribute__((noinline)) |
63 #define ATTR __attribute__((noinline)) |
374 |
377 |
375 // Prevent deflation at STW-time. See deflate_idle_monitors() and is_busy(). |
378 // Prevent deflation at STW-time. See deflate_idle_monitors() and is_busy(). |
376 // Ensure the object-monitor relationship remains stable while there's contention. |
379 // Ensure the object-monitor relationship remains stable while there's contention. |
377 Atomic::inc_ptr(&_count); |
380 Atomic::inc_ptr(&_count); |
378 |
381 |
|
382 JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);) |
379 EventJavaMonitorEnter event; |
383 EventJavaMonitorEnter event; |
|
384 if (event.should_commit()) { |
|
385 event.set_monitorClass(((oop)this->object())->klass()); |
|
386 event.set_address((uintptr_t)(this->object_addr())); |
|
387 } |
380 |
388 |
381 { // Change java thread status to indicate blocked on monitor enter. |
389 { // Change java thread status to indicate blocked on monitor enter. |
382 JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); |
390 JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); |
383 |
391 |
384 Self->set_current_pending_monitor(this); |
392 Self->set_current_pending_monitor(this); |
463 // event handler consumed an unpark() issued by the thread that |
471 // event handler consumed an unpark() issued by the thread that |
464 // just exited the monitor. |
472 // just exited the monitor. |
465 } |
473 } |
466 |
474 |
467 if (event.should_commit()) { |
475 if (event.should_commit()) { |
468 event.set_klass(((oop)this->object())->klass()); |
476 event.set_previousOwner((uintptr_t)_previous_owner_tid); |
469 event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid); |
|
470 event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr())); |
|
471 event.commit(); |
477 event.commit(); |
472 } |
478 } |
473 |
479 |
474 if (ObjectMonitor::_sync_ContendedLockAttempts != NULL) { |
480 if (ObjectMonitor::_sync_ContendedLockAttempts != NULL) { |
475 ObjectMonitor::_sync_ContendedLockAttempts->inc() ; |
481 ObjectMonitor::_sync_ContendedLockAttempts->inc() ; |
988 // a MEMBAR or other serializing instruction before fetching EntryList|cxq. |
994 // a MEMBAR or other serializing instruction before fetching EntryList|cxq. |
989 if ((SyncFlags & 4) == 0) { |
995 if ((SyncFlags & 4) == 0) { |
990 _Responsible = NULL ; |
996 _Responsible = NULL ; |
991 } |
997 } |
992 |
998 |
993 #if INCLUDE_TRACE |
999 #if INCLUDE_JFR |
994 // get the owner's thread id for the MonitorEnter event |
1000 // get the owner's thread id for the MonitorEnter event |
995 // if it is enabled and the thread isn't suspended |
1001 // if it is enabled and the thread isn't suspended |
996 if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) { |
1002 if (not_suspended && EventJavaMonitorEnter::is_enabled()) { |
997 _previous_owner_tid = SharedRuntime::get_java_tid(Self); |
1003 _previous_owner_tid = JFR_THREAD_ID(Self); |
998 } |
1004 } |
999 #endif |
1005 #endif |
1000 |
1006 |
1001 for (;;) { |
1007 for (;;) { |
1002 assert (THREAD == _owner, "invariant") ; |
1008 assert (THREAD == _owner, "invariant") ; |
1441 for (v = *adr ; Atomic::cmpxchg (v + dx, adr, v) != v; v = *adr) ; |
1447 for (v = *adr ; Atomic::cmpxchg (v + dx, adr, v) != v; v = *adr) ; |
1442 return v ; |
1448 return v ; |
1443 } |
1449 } |
1444 |
1450 |
1445 // helper method for posting a monitor wait event |
1451 // helper method for posting a monitor wait event |
1446 void ObjectMonitor::post_monitor_wait_event(EventJavaMonitorWait* event, |
1452 static void post_monitor_wait_event(EventJavaMonitorWait* event, |
1447 jlong notifier_tid, |
1453 ObjectMonitor* monitor, |
1448 jlong timeout, |
1454 jlong notifier_tid, |
1449 bool timedout) { |
1455 jlong timeout, |
1450 event->set_klass(((oop)this->object())->klass()); |
1456 bool timedout) { |
1451 event->set_timeout((TYPE_ULONG)timeout); |
1457 assert(monitor != NULL, "invariant"); |
1452 event->set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr())); |
1458 event->set_monitorClass(((oop)monitor->object())->klass()); |
1453 event->set_notifier((TYPE_OSTHREAD)notifier_tid); |
1459 event->set_timeout(timeout); |
1454 event->set_timedOut((TYPE_BOOLEAN)timedout); |
1460 event->set_address((uintptr_t)monitor->object_addr()); |
|
1461 event->set_notifier((u8)notifier_tid); |
|
1462 event->set_timedOut(timedout); |
1455 event->commit(); |
1463 event->commit(); |
1456 } |
1464 } |
1457 |
1465 |
1458 // ----------------------------------------------------------------------------- |
1466 // ----------------------------------------------------------------------------- |
1459 // Wait/Notify/NotifyAll |
1467 // Wait/Notify/NotifyAll |
1487 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally |
1495 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally |
1488 // consume an unpark() meant for the ParkEvent associated with |
1496 // consume an unpark() meant for the ParkEvent associated with |
1489 // this ObjectMonitor. |
1497 // this ObjectMonitor. |
1490 } |
1498 } |
1491 if (event.should_commit()) { |
1499 if (event.should_commit()) { |
1492 post_monitor_wait_event(&event, 0, millis, false); |
1500 post_monitor_wait_event(&event, this, 0, millis, false); |
1493 } |
1501 } |
1494 TEVENT (Wait - Throw IEX) ; |
1502 TEVENT (Wait - Throw IEX) ; |
1495 THROW(vmSymbols::java_lang_InterruptedException()); |
1503 THROW(vmSymbols::java_lang_InterruptedException()); |
1496 return ; |
1504 return ; |
1497 } |
1505 } |
1631 node._event->unpark(); |
1639 node._event->unpark(); |
1632 } |
1640 } |
1633 } |
1641 } |
1634 |
1642 |
1635 if (event.should_commit()) { |
1643 if (event.should_commit()) { |
1636 post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT); |
1644 post_monitor_wait_event(&event, this, node._notifier_tid, millis, ret == OS_TIMEOUT); |
1637 } |
1645 } |
1638 |
1646 |
1639 OrderAccess::fence() ; |
1647 OrderAccess::fence() ; |
1640 |
1648 |
1641 assert (Self->_Stalled != 0, "invariant") ; |
1649 assert (Self->_Stalled != 0, "invariant") ; |
1714 if (Policy != 4) { |
1722 if (Policy != 4) { |
1715 iterator->TState = ObjectWaiter::TS_ENTER ; |
1723 iterator->TState = ObjectWaiter::TS_ENTER ; |
1716 } |
1724 } |
1717 iterator->_notified = 1 ; |
1725 iterator->_notified = 1 ; |
1718 Thread * Self = THREAD; |
1726 Thread * Self = THREAD; |
1719 iterator->_notifier_tid = Self->osthread()->thread_id(); |
1727 iterator->_notifier_tid = JFR_THREAD_ID(Self); |
1720 |
1728 |
1721 ObjectWaiter * List = _EntryList ; |
1729 ObjectWaiter * List = _EntryList ; |
1722 if (List != NULL) { |
1730 if (List != NULL) { |
1723 assert (List->_prev == NULL, "invariant") ; |
1731 assert (List->_prev == NULL, "invariant") ; |
1724 assert (List->TState == ObjectWaiter::TS_ENTER, "invariant") ; |
1732 assert (List->TState == ObjectWaiter::TS_ENTER, "invariant") ; |
1840 |
1848 |
1841 guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ; |
1849 guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ; |
1842 guarantee (iterator->_notified == 0, "invariant") ; |
1850 guarantee (iterator->_notified == 0, "invariant") ; |
1843 iterator->_notified = 1 ; |
1851 iterator->_notified = 1 ; |
1844 Thread * Self = THREAD; |
1852 Thread * Self = THREAD; |
1845 iterator->_notifier_tid = Self->osthread()->thread_id(); |
1853 iterator->_notifier_tid = JFR_THREAD_ID(Self); |
1846 if (Policy != 4) { |
1854 if (Policy != 4) { |
1847 iterator->TState = ObjectWaiter::TS_ENTER ; |
1855 iterator->TState = ObjectWaiter::TS_ENTER ; |
1848 } |
1856 } |
1849 |
1857 |
1850 ObjectWaiter * List = _EntryList ; |
1858 ObjectWaiter * List = _EntryList ; |