--- old/src/share/vm/runtime/objectMonitor.hpp 2016-10-25 10:40:10.306778274 +0200 +++ new/src/share/vm/runtime/objectMonitor.hpp 2016-10-25 10:40:10.257778242 +0200 @@ -99,6 +99,7 @@ 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 @@ -130,6 +131,8 @@ 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; } @@ -155,6 +158,8 @@ _SpinClock = 0 ; OwnerIsThread = 0 ; _previous_owner_tid = 0; + _trace_current_seq = 0; + _trace_exit_stack = 0; } ~ObjectMonitor() { @@ -178,6 +183,8 @@ _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: @@ -202,8 +209,8 @@ 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) ; @@ -211,7 +218,9 @@ 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) ; @@ -275,6 +284,11 @@ 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: