< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page

        

@@ -38,10 +38,11 @@
 #include "runtime/synchronizer.hpp"
 #include "runtime/thread.inline.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/preserveException.hpp"
+#include "evtrace/traceEvents.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
 #endif
 #ifdef TARGET_OS_FAMILY_solaris
 # include "os_solaris.inline.hpp"

@@ -278,33 +279,33 @@
 //  2) wait on lock2
 //  3) when notified on lock2, unlock lock2
 //  4) reenter lock1 with original recursion count
 //  5) lock lock2
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
-intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
+void ObjectSynchronizer::complete_exit(Handle obj, intptr_t *saved_recursions, intptr_t *saved_trace_exit_stack, TRAPS) {
   TEVENT (complete_exit) ;
   if (UseBiasedLocking) {
     BiasedLocking::revoke_and_rebias(obj, false, THREAD);
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
 
   ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
 
-  return monitor->complete_exit(THREAD);
+  monitor->complete_exit(saved_recursions, saved_trace_exit_stack, THREAD);
 }
 
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
-void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
+void ObjectSynchronizer::reenter(Handle obj, intptr_t saved_recursions, intptr_t saved_trace_exit_stack, TRAPS) {
   TEVENT (reenter) ;
   if (UseBiasedLocking) {
     BiasedLocking::revoke_and_rebias(obj, false, THREAD);
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
 
   ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
 
-  monitor->reenter(recursion, THREAD);
+  monitor->reenter(saved_recursions, saved_trace_exit_stack, THREAD);
 }
 // -----------------------------------------------------------------------------
 // JNI locks on java objects
 // NOTE: must use heavy weight monitor to handle jni monitor enter
 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { // possible entry from jni enter

@@ -1308,10 +1309,17 @@
           // with CAS.  That is, we can avoid the xchg-NULL .... ST idiom.
           m->set_owner(mark->locker());
           m->set_object(object);
           // TODO-FIXME: assert BasicLock->dhw != 0.
 
+          // must get a sequence number before the monitor is published below
+          No_Safepoint_Verifier nsv(true, false);
+          intptr_t trace_seq;
+          if (EnableEventTracing) {
+            trace_seq = m->next_trace_seq();
+          }
+
           // Must preserve store ordering. The monitor state must
           // be stable at the time of publishing the monitor address.
           guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ;
           object->release_set_mark(markOopDesc::encode(m));
 

@@ -1325,10 +1333,13 @@
               tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
                 (void *) object, (intptr_t) object->mark(),
                 object->klass()->external_name());
             }
           }
+          if (EnableEventTracing) {
+            TraceEvents::write_monitor_inflate(m, trace_seq);
+          }
           return m ;
       }
 
       // CASE: neutral
       // TODO-FIXME: for entry we currently inflate and then try to CAS _owner.

@@ -1350,16 +1361,28 @@
       m->OwnerIsThread = 1 ;
       m->_recursions   = 0 ;
       m->_Responsible  = NULL ;
       m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ;       // consider: keep metastats by type/class
 
+      // must get a sequence number before the monitor is published below
+      No_Safepoint_Verifier nsv(true, false);
+      intptr_t trace_seq;
+      if (EnableEventTracing) {
+          trace_seq = m->next_trace_seq();
+      }
+
       if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) {
           m->set_object (NULL) ;
           m->set_owner  (NULL) ;
           m->OwnerIsThread = 0 ;
           m->Recycle() ;
           omRelease (Self, m, true) ;
+
+          if (EnableEventTracing) { // must still consume our sequence number
+             TraceEvents::write_monitor_dummy(m, trace_seq);
+          }
+
           m = NULL ;
           continue ;
           // interference - the markword changed - just retry.
           // The state-transitions are one-way, so there's no chance of
           // live-lock -- "Inflated" is an absorbing state.

@@ -1375,10 +1398,13 @@
           tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
             (void *) object, (intptr_t) object->mark(),
             object->klass()->external_name());
         }
       }
+      if (EnableEventTracing) {
+        TraceEvents::write_monitor_inflate(m, trace_seq);
+      }
       return m ;
   }
 }
 
 // Note that we could encounter some performance loss through false-sharing as

@@ -1442,10 +1468,13 @@
          ResourceMark rm;
            tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
                 (void *) obj, (intptr_t) obj->mark(), obj->klass()->external_name());
        }
      }
+     if (EnableEventTracing) {
+       TraceEvents::write_monitor_deflate(mid);
+     }
 
      // Restore the header back to obj
      obj->release_set_mark(mid->header());
      mid->clear();
 

@@ -1603,11 +1632,11 @@
 
 public:
   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
   void do_monitor(ObjectMonitor* mid) {
     if (mid->owner() == THREAD) {
-      (void)mid->complete_exit(CHECK);
+      mid->complete_exit(NULL, NULL, CHECK);
     }
   }
 };
 
 // Release all inflated monitors owned by THREAD.  Lightweight monitors are
< prev index next >