< prev index next >

src/share/vm/runtime/objectMonitor.hpp

Print this page

        

@@ -97,10 +97,11 @@
   static int EntryList_offset_in_bytes()   { return offset_of(ObjectMonitor, _EntryList);  }
   static int FreeNext_offset_in_bytes()    { return offset_of(ObjectMonitor, FreeNext);    }
   static int WaitSet_offset_in_bytes()     { return offset_of(ObjectMonitor, _WaitSet) ;   }
   static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);}
   static int Spinner_offset_in_bytes()     { return offset_of(ObjectMonitor, _Spinner);    }
+  static int trace_exit_stack_offset_in_bytes() { return offset_of(ObjectMonitor, _trace_exit_stack); }
 
  public:
   // Eventaully we'll make provisions for multiple callbacks, but
   // now one will suffice.
   static int (*SpinCallbackFunction)(intptr_t, int) ;

@@ -128,10 +129,12 @@
   intptr_t  count() const;
   void      set_count(intptr_t count);
   intptr_t  contentions() const ;
   intptr_t  recursions() const                                         { return _recursions; }
 
+  intptr_t  next_trace_seq()  { return Atomic::add_ptr(1, &_trace_current_seq); }
+
   // JVM/DI GetMonitorInfo() needs this
   ObjectWaiter* first_waiter()                                         { return _WaitSet; }
   ObjectWaiter* next_waiter(ObjectWaiter* o)                           { return o->_next; }
   Thread* thread_of_waiter(ObjectWaiter* o)                            { return o->_thread; }
 

@@ -153,10 +156,12 @@
     _EntryList    = NULL ;
     _SpinFreq     = 0 ;
     _SpinClock    = 0 ;
     OwnerIsThread = 0 ;
     _previous_owner_tid = 0;
+    _trace_current_seq = 0;
+    _trace_exit_stack = 0;
   }
 
   ~ObjectMonitor() {
    // TODO: Add asserts ...
    // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0

@@ -176,10 +181,12 @@
     _WaitSet       = NULL ;
     _recursions    = 0 ;
     _SpinFreq      = 0 ;
     _SpinClock     = 0 ;
     OwnerIsThread  = 0 ;
+    // tracing: do not reset _trace_current_seq, we also use it
+    // to detect pending events before a monitor is recycled
   }
 
 public:
 
   void*     object() const;

@@ -200,20 +207,22 @@
   void      wait(jlong millis, bool interruptable, TRAPS);
   void      notify(TRAPS);
   void      notifyAll(TRAPS);
 
 // Use the following at your own risk
-  intptr_t  complete_exit(TRAPS);
-  void      reenter(intptr_t recursions, TRAPS);
+  void      complete_exit(intptr_t *saved_recursions, intptr_t *saved_trace_exit_stack, TRAPS);
+  void      reenter(intptr_t saved_recursions, intptr_t saved_trace_exit_stack, TRAPS);
 
  private:
   void      AddWaiter (ObjectWaiter * waiter) ;
   static    void DeferredInitialize();
 
   ObjectWaiter * DequeueWaiter () ;
   void      DequeueSpecificWaiter (ObjectWaiter * waiter) ;
-  void      EnterI (TRAPS) ;
+  void      enter (int after_wait, TRAPS);
+  void      exit(intptr_t *exit_stack_id_for_wait, bool not_suspended, TRAPS);
+  int       EnterI (TRAPS) ;
   void      ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
   void      UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ;
   int       TryLock (Thread * Self) ;
   int       NotRunnable (Thread * Self, Thread * Owner) ;
   int       TrySpin_Fixed (Thread * Self) ;

@@ -273,10 +282,15 @@
   // to use 64-bit fields for these variables on a 64-bit JVM.
 
   volatile intptr_t  _count;        // reference count to prevent reclaimation/deflation
                                     // at stop-the-world time.  See deflate_idle_monitors().
                                     // _count is approximately |_WaitSet| + |_EntryList|
+
+  // TODO: this class appears to be sensitive to false sharing.
+  //       there might be a better location to place this field.
+  volatile intptr_t  _trace_current_seq;
+  volatile intptr_t  _trace_exit_stack;
  protected:
   volatile intptr_t  _waiters;      // number of waiting threads
  private:
  protected:
   ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
< prev index next >