equal
deleted
inserted
replaced
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/allocation.inline.hpp" |
29 #include "memory/allocation.inline.hpp" |
28 #include "memory/resourceArea.hpp" |
30 #include "memory/resourceArea.hpp" |
29 #include "oops/markOop.hpp" |
31 #include "oops/markOop.hpp" |
30 #include "oops/oop.inline.hpp" |
32 #include "oops/oop.inline.hpp" |
31 #include "runtime/atomic.hpp" |
33 #include "runtime/atomic.hpp" |
39 #include "runtime/safepointMechanism.inline.hpp" |
41 #include "runtime/safepointMechanism.inline.hpp" |
40 #include "runtime/sharedRuntime.hpp" |
42 #include "runtime/sharedRuntime.hpp" |
41 #include "runtime/stubRoutines.hpp" |
43 #include "runtime/stubRoutines.hpp" |
42 #include "runtime/thread.inline.hpp" |
44 #include "runtime/thread.inline.hpp" |
43 #include "services/threadService.hpp" |
45 #include "services/threadService.hpp" |
44 #include "trace/tracing.hpp" |
|
45 #include "trace/traceMacros.hpp" |
|
46 #include "utilities/dtrace.hpp" |
46 #include "utilities/dtrace.hpp" |
47 #include "utilities/macros.hpp" |
47 #include "utilities/macros.hpp" |
48 #include "utilities/preserveException.hpp" |
48 #include "utilities/preserveException.hpp" |
|
49 #if INCLUDE_JFR |
|
50 #include "jfr/support/jfrFlush.hpp" |
|
51 #endif |
49 |
52 |
50 #ifdef DTRACE_ENABLED |
53 #ifdef DTRACE_ENABLED |
51 |
54 |
52 // Only bother with this argument setup if dtrace is available |
55 // Only bother with this argument setup if dtrace is available |
53 // TODO-FIXME: probes should not fire when caller is _blocked. assert() accordingly. |
56 // TODO-FIXME: probes should not fire when caller is _blocked. assert() accordingly. |
315 |
318 |
316 // Prevent deflation at STW-time. See deflate_idle_monitors() and is_busy(). |
319 // Prevent deflation at STW-time. See deflate_idle_monitors() and is_busy(). |
317 // Ensure the object-monitor relationship remains stable while there's contention. |
320 // Ensure the object-monitor relationship remains stable while there's contention. |
318 Atomic::inc(&_count); |
321 Atomic::inc(&_count); |
319 |
322 |
|
323 JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);) |
320 EventJavaMonitorEnter event; |
324 EventJavaMonitorEnter event; |
|
325 if (event.should_commit()) { |
|
326 event.set_monitorClass(((oop)this->object())->klass()); |
|
327 event.set_address((uintptr_t)(this->object_addr())); |
|
328 } |
321 |
329 |
322 { // Change java thread status to indicate blocked on monitor enter. |
330 { // Change java thread status to indicate blocked on monitor enter. |
323 JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); |
331 JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); |
324 |
332 |
325 Self->set_current_pending_monitor(this); |
333 Self->set_current_pending_monitor(this); |
401 // call park() for the remainder of the monitor enter protocol. So |
409 // call park() for the remainder of the monitor enter protocol. So |
402 // it doesn't matter if the JVMTI_EVENT_MONITOR_CONTENDED_ENTERED |
410 // it doesn't matter if the JVMTI_EVENT_MONITOR_CONTENDED_ENTERED |
403 // event handler consumed an unpark() issued by the thread that |
411 // event handler consumed an unpark() issued by the thread that |
404 // just exited the monitor. |
412 // just exited the monitor. |
405 } |
413 } |
406 |
|
407 if (event.should_commit()) { |
414 if (event.should_commit()) { |
408 event.set_monitorClass(((oop)this->object())->klass()); |
415 event.set_previousOwner((uintptr_t)_previous_owner_tid); |
409 event.set_previousOwner((TYPE_THREAD)_previous_owner_tid); |
|
410 event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr())); |
|
411 event.commit(); |
416 event.commit(); |
412 } |
417 } |
413 |
|
414 OM_PERFDATA_OP(ContendedLockAttempts, inc()); |
418 OM_PERFDATA_OP(ContendedLockAttempts, inc()); |
415 } |
419 } |
416 |
|
417 |
420 |
418 // Caveat: TryLock() is not necessarily serializing if it returns failure. |
421 // Caveat: TryLock() is not necessarily serializing if it returns failure. |
419 // Callers must compensate as needed. |
422 // Callers must compensate as needed. |
420 |
423 |
421 int ObjectMonitor::TryLock(Thread * Self) { |
424 int ObjectMonitor::TryLock(Thread * Self) { |
936 // a MEMBAR or other serializing instruction before fetching EntryList|cxq. |
939 // a MEMBAR or other serializing instruction before fetching EntryList|cxq. |
937 if ((SyncFlags & 4) == 0) { |
940 if ((SyncFlags & 4) == 0) { |
938 _Responsible = NULL; |
941 _Responsible = NULL; |
939 } |
942 } |
940 |
943 |
941 #if INCLUDE_TRACE |
944 #if INCLUDE_JFR |
942 // get the owner's thread id for the MonitorEnter event |
945 // get the owner's thread id for the MonitorEnter event |
943 // if it is enabled and the thread isn't suspended |
946 // if it is enabled and the thread isn't suspended |
944 if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) { |
947 if (not_suspended && EventJavaMonitorEnter::is_enabled()) { |
945 _previous_owner_tid = THREAD_TRACE_ID(Self); |
948 _previous_owner_tid = JFR_THREAD_ID(Self); |
946 } |
949 } |
947 #endif |
950 #endif |
948 |
951 |
949 for (;;) { |
952 for (;;) { |
950 assert(THREAD == _owner, "invariant"); |
953 assert(THREAD == _owner, "invariant"); |
1388 int v; |
1391 int v; |
1389 for (v = *adr; Atomic::cmpxchg(v + dx, adr, v) != v; v = *adr) /* empty */; |
1392 for (v = *adr; Atomic::cmpxchg(v + dx, adr, v) != v; v = *adr) /* empty */; |
1390 return v; |
1393 return v; |
1391 } |
1394 } |
1392 |
1395 |
1393 // helper method for posting a monitor wait event |
1396 static void post_monitor_wait_event(EventJavaMonitorWait* event, |
1394 void ObjectMonitor::post_monitor_wait_event(EventJavaMonitorWait* event, |
1397 ObjectMonitor* monitor, |
1395 jlong notifier_tid, |
1398 jlong notifier_tid, |
1396 jlong timeout, |
1399 jlong timeout, |
1397 bool timedout) { |
1400 bool timedout) { |
1398 assert(event != NULL, "invariant"); |
1401 assert(event != NULL, "invariant"); |
1399 event->set_monitorClass(((oop)this->object())->klass()); |
1402 assert(monitor != NULL, "invariant"); |
|
1403 event->set_monitorClass(((oop)monitor->object())->klass()); |
1400 event->set_timeout(timeout); |
1404 event->set_timeout(timeout); |
1401 event->set_address((TYPE_ADDRESS)this->object_addr()); |
1405 event->set_address((uintptr_t)monitor->object_addr()); |
1402 event->set_notifier(notifier_tid); |
1406 event->set_notifier(notifier_tid); |
1403 event->set_timedOut(timedout); |
1407 event->set_timedOut(timedout); |
1404 event->commit(); |
1408 event->commit(); |
1405 } |
1409 } |
1406 |
1410 |
1436 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally |
1440 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally |
1437 // consume an unpark() meant for the ParkEvent associated with |
1441 // consume an unpark() meant for the ParkEvent associated with |
1438 // this ObjectMonitor. |
1442 // this ObjectMonitor. |
1439 } |
1443 } |
1440 if (event.should_commit()) { |
1444 if (event.should_commit()) { |
1441 post_monitor_wait_event(&event, 0, millis, false); |
1445 post_monitor_wait_event(&event, this, 0, millis, false); |
1442 } |
1446 } |
1443 TEVENT(Wait - Throw IEX); |
1447 TEVENT(Wait - Throw IEX); |
1444 THROW(vmSymbols::java_lang_InterruptedException()); |
1448 THROW(vmSymbols::java_lang_InterruptedException()); |
1445 return; |
1449 return; |
1446 } |
1450 } |
1578 node._event->unpark(); |
1582 node._event->unpark(); |
1579 } |
1583 } |
1580 } |
1584 } |
1581 |
1585 |
1582 if (event.should_commit()) { |
1586 if (event.should_commit()) { |
1583 post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT); |
1587 post_monitor_wait_event(&event, this, node._notifier_tid, millis, ret == OS_TIMEOUT); |
1584 } |
1588 } |
1585 |
1589 |
1586 OrderAccess::fence(); |
1590 OrderAccess::fence(); |
1587 |
1591 |
1588 assert(Self->_Stalled != 0, "invariant"); |
1592 assert(Self->_Stalled != 0, "invariant"); |
1658 // For now we use (b). |
1662 // For now we use (b). |
1659 if (policy != 4) { |
1663 if (policy != 4) { |
1660 iterator->TState = ObjectWaiter::TS_ENTER; |
1664 iterator->TState = ObjectWaiter::TS_ENTER; |
1661 } |
1665 } |
1662 iterator->_notified = 1; |
1666 iterator->_notified = 1; |
1663 iterator->_notifier_tid = THREAD_TRACE_ID(Self); |
1667 iterator->_notifier_tid = JFR_THREAD_ID(Self); |
1664 |
1668 |
1665 ObjectWaiter * list = _EntryList; |
1669 ObjectWaiter * list = _EntryList; |
1666 if (list != NULL) { |
1670 if (list != NULL) { |
1667 assert(list->_prev == NULL, "invariant"); |
1671 assert(list->_prev == NULL, "invariant"); |
1668 assert(list->TState == ObjectWaiter::TS_ENTER, "invariant"); |
1672 assert(list->TState == ObjectWaiter::TS_ENTER, "invariant"); |