< 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 >