126 // in a 64-bit JVM.
127
128 class ObjectMonitor {
129 public:
130 enum {
131 OM_OK, // no error
132 OM_SYSTEM_ERROR, // operating system error
133 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
134 OM_INTERRUPTED, // Thread.interrupt()
135 OM_TIMED_OUT // Object.wait() timed out
136 };
137
138 private:
139 friend class ObjectSynchronizer;
140 friend class ObjectWaiter;
141 friend class VMStructs;
142
143 volatile markOop _header; // displaced object header word - mark
144 void* volatile _object; // backward object pointer - strong root
145 public:
146 ObjectMonitor * FreeNext; // Free list linkage
147 private:
148 DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
149 sizeof(volatile markOop) + sizeof(void * volatile) +
150 sizeof(ObjectMonitor *));
151 protected: // protected for JvmtiRawMonitor
152 void * volatile _owner; // pointer to owning thread OR BasicLock
153 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
154 volatile intptr_t _recursions; // recursion count, 0 for first entry
155 ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
156 // The list is actually composed of WaitNodes,
157 // acting as proxies for Threads.
158 private:
159 ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry.
160 Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
161 Thread * volatile _Responsible;
162
163 volatile int _Spinner; // for exit->spinner handoff optimization
164 volatile int _SpinDuration;
165
166 volatile jint _count; // reference count to prevent reclamation/deflation
234 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); }
235 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq); }
236 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ); }
237 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); }
238
239 // ObjectMonitor references can be ORed with markOopDesc::monitor_value
240 // as part of the ObjectMonitor tagging mechanism. When we combine an
241 // ObjectMonitor reference with an offset, we need to remove the tag
242 // value in order to generate the proper address.
243 //
244 // We can either adjust the ObjectMonitor reference and then add the
245 // offset or we can adjust the offset that is added to the ObjectMonitor
246 // reference. The latter avoids an AGI (Address Generation Interlock)
247 // stall so the helper macro adjusts the offset value that is returned
248 // to the ObjectMonitor reference manipulation code:
249 //
250 #define OM_OFFSET_NO_MONITOR_VALUE_TAG(f) \
251 ((ObjectMonitor::f ## _offset_in_bytes()) - markOopDesc::monitor_value)
252
253 markOop header() const;
254 void set_header(markOop hdr);
255
256 intptr_t is_busy() const {
257 // TODO-FIXME: merge _count and _waiters.
258 // TODO-FIXME: assert _owner == null implies _recursions = 0
259 // TODO-FIXME: assert _WaitSet != null implies _count > 0
260 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList);
261 }
262
263 intptr_t is_entered(Thread* current) const;
264
265 void* owner() const;
266 void set_owner(void* owner);
267
268 jint waiters() const;
269
270 jint count() const;
271 void set_count(jint count);
272 jint contentions() const;
273 intptr_t recursions() const { return _recursions; }
|
126 // in a 64-bit JVM.
127
128 class ObjectMonitor {
129 public:
130 enum {
131 OM_OK, // no error
132 OM_SYSTEM_ERROR, // operating system error
133 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
134 OM_INTERRUPTED, // Thread.interrupt()
135 OM_TIMED_OUT // Object.wait() timed out
136 };
137
138 private:
139 friend class ObjectSynchronizer;
140 friend class ObjectWaiter;
141 friend class VMStructs;
142
143 volatile markOop _header; // displaced object header word - mark
144 void* volatile _object; // backward object pointer - strong root
145 public:
146 ObjectMonitor* FreeNext; // Free list linkage
147 private:
148 DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
149 sizeof(volatile markOop) + sizeof(void * volatile) +
150 sizeof(ObjectMonitor *));
151 protected: // protected for JvmtiRawMonitor
152 void * volatile _owner; // pointer to owning thread OR BasicLock
153 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
154 volatile intptr_t _recursions; // recursion count, 0 for first entry
155 ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
156 // The list is actually composed of WaitNodes,
157 // acting as proxies for Threads.
158 private:
159 ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry.
160 Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
161 Thread * volatile _Responsible;
162
163 volatile int _Spinner; // for exit->spinner handoff optimization
164 volatile int _SpinDuration;
165
166 volatile jint _count; // reference count to prevent reclamation/deflation
234 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); }
235 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq); }
236 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ); }
237 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); }
238
239 // ObjectMonitor references can be ORed with markOopDesc::monitor_value
240 // as part of the ObjectMonitor tagging mechanism. When we combine an
241 // ObjectMonitor reference with an offset, we need to remove the tag
242 // value in order to generate the proper address.
243 //
244 // We can either adjust the ObjectMonitor reference and then add the
245 // offset or we can adjust the offset that is added to the ObjectMonitor
246 // reference. The latter avoids an AGI (Address Generation Interlock)
247 // stall so the helper macro adjusts the offset value that is returned
248 // to the ObjectMonitor reference manipulation code:
249 //
250 #define OM_OFFSET_NO_MONITOR_VALUE_TAG(f) \
251 ((ObjectMonitor::f ## _offset_in_bytes()) - markOopDesc::monitor_value)
252
253 markOop header() const;
254 volatile markOop* header_addr();
255 void set_header(markOop hdr);
256
257 intptr_t is_busy() const {
258 // TODO-FIXME: merge _count and _waiters.
259 // TODO-FIXME: assert _owner == null implies _recursions = 0
260 // TODO-FIXME: assert _WaitSet != null implies _count > 0
261 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList);
262 }
263
264 intptr_t is_entered(Thread* current) const;
265
266 void* owner() const;
267 void set_owner(void* owner);
268
269 jint waiters() const;
270
271 jint count() const;
272 void set_count(jint count);
273 jint contentions() const;
274 intptr_t recursions() const { return _recursions; }
|