src/hotspot/share/runtime/objectMonitor.cpp
changeset 50113 caf115bb98ad
parent 50083 07015dd8157f
child 50429 83aec1d357d4
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
    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");