85 }; |
85 }; |
86 |
86 |
87 public: |
87 public: |
88 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... |
88 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... |
89 // ByteSize would also be an appropriate type. |
89 // ByteSize would also be an appropriate type. |
90 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } |
90 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } |
91 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } |
91 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } |
92 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } |
92 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } |
93 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); } |
93 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); } |
94 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } |
94 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } |
95 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq); } |
95 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq); } |
96 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ); } |
96 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ); } |
97 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); } |
97 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); } |
98 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); } |
98 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); } |
99 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet); } |
99 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet); } |
100 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible); } |
100 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible); } |
101 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); } |
101 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); } |
102 |
102 |
103 public: |
103 public: |
104 // Eventually we'll make provisions for multiple callbacks, but |
104 // Eventually we'll make provisions for multiple callbacks, but |
105 // now one will suffice. |
105 // now one will suffice. |
106 static int (*SpinCallbackFunction)(intptr_t, int); |
106 static int (*SpinCallbackFunction)(intptr_t, int); |
238 // This means this class can't use any virtual member functions. |
238 // This means this class can't use any virtual member functions. |
239 |
239 |
240 volatile markOop _header; // displaced object header word - mark |
240 volatile markOop _header; // displaced object header word - mark |
241 void* volatile _object; // backward object pointer - strong root |
241 void* volatile _object; // backward object pointer - strong root |
242 |
242 |
243 double SharingPad[1]; // temp to reduce false sharing |
243 double SharingPad[1]; // temp to reduce false sharing |
244 |
244 |
245 // All the following fields must be machine word aligned |
245 // All the following fields must be machine word aligned |
246 // The VM assumes write ordering wrt these fields, which can be |
246 // The VM assumes write ordering wrt these fields, which can be |
247 // read from other threads. |
247 // read from other threads. |
248 |
248 |
249 protected: // protected for jvmtiRawMonitor |
249 protected: // protected for jvmtiRawMonitor |
250 void * volatile _owner; // pointer to owning thread OR BasicLock |
250 void * volatile _owner; // pointer to owning thread OR BasicLock |
251 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor |
251 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor |
252 volatile intptr_t _recursions; // recursion count, 0 for first entry |
252 volatile intptr_t _recursions; // recursion count, 0 for first entry |
253 private: |
253 private: |
254 int OwnerIsThread; // _owner is (Thread *) vs SP/BasicLock |
254 int OwnerIsThread; // _owner is (Thread *) vs SP/BasicLock |
255 ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry. |
255 ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry. |
256 // The list is actually composed of WaitNodes, acting |
256 // The list is actually composed of WaitNodes, acting |
257 // as proxies for Threads. |
257 // as proxies for Threads. |
258 protected: |
258 protected: |
259 ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry. |
259 ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry. |
260 private: |
260 private: |
261 Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling |
261 Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling |
262 Thread * volatile _Responsible; |
262 Thread * volatile _Responsible; |
263 int _PromptDrain; // rqst to drain cxq into EntryList ASAP |
263 int _PromptDrain; // rqst to drain cxq into EntryList ASAP |
264 |
264 |
265 volatile int _Spinner; // for exit->spinner handoff optimization |
265 volatile int _Spinner; // for exit->spinner handoff optimization |
266 volatile int _SpinFreq; // Spin 1-out-of-N attempts: success rate |
266 volatile int _SpinFreq; // Spin 1-out-of-N attempts: success rate |
267 volatile int _SpinClock; |
267 volatile int _SpinClock; |
268 volatile int _SpinDuration; |
268 volatile int _SpinDuration; |
269 volatile intptr_t _SpinState; // MCS/CLH list of spinners |
269 volatile intptr_t _SpinState; // MCS/CLH list of spinners |
270 |
270 |
271 // TODO-FIXME: _count, _waiters and _recursions should be of |
271 // TODO-FIXME: _count, _waiters and _recursions should be of |
272 // type int, or int32_t but not intptr_t. There's no reason |
272 // type int, or int32_t but not intptr_t. There's no reason |
273 // to use 64-bit fields for these variables on a 64-bit JVM. |
273 // to use 64-bit fields for these variables on a 64-bit JVM. |
274 |
274 |
282 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor |
282 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor |
283 private: |
283 private: |
284 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock |
284 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock |
285 |
285 |
286 public: |
286 public: |
287 int _QMix; // Mixed prepend queue discipline |
287 int _QMix; // Mixed prepend queue discipline |
288 ObjectMonitor * FreeNext; // Free list linkage |
288 ObjectMonitor * FreeNext; // Free list linkage |
289 intptr_t StatA, StatsB; |
289 intptr_t StatA, StatsB; |
290 |
290 |
291 public: |
291 public: |
292 static void Initialize(); |
292 static void Initialize(); |
293 static PerfCounter * _sync_ContendedLockAttempts; |
293 static PerfCounter * _sync_ContendedLockAttempts; |