Mercurial > hg > truffle
annotate src/share/vm/runtime/objectMonitor.hpp @ 14680:2dfa56e10640
8027124: [TESTBUG] NonTieredLevelsTest: java.lang.RuntimeException: private TestCase$Helper(java.lang.Object) must be osr_compiled
Reviewed-by: kvn, roland
author | iignatyev |
---|---|
date | Thu, 06 Mar 2014 12:47:45 +0400 |
parents | 63a4eb8bcd23 |
children | 4ca6dc0799b6 |
rev | line source |
---|---|
0 | 1 /* |
10405 | 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP |
26 #define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP | |
27 | |
28 #include "runtime/os.hpp" | |
1983
c760f78e0a53
7003125: precompiled.hpp is included when precompiled headers are not used
stefank
parents:
1972
diff
changeset
|
29 #include "runtime/park.hpp" |
1972 | 30 #include "runtime/perfData.hpp" |
31 | |
1878 | 32 // ObjectWaiter serves as a "proxy" or surrogate thread. |
33 // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific | |
34 // ParkEvent instead. Beware, however, that the JVMTI code | |
35 // knows about ObjectWaiters, so we'll have to reconcile that code. | |
36 // See next_waiter(), first_waiter(), etc. | |
37 | |
38 class ObjectWaiter : public StackObj { | |
39 public: | |
40 enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ; | |
41 enum Sorted { PREPEND, APPEND, SORTED } ; | |
42 ObjectWaiter * volatile _next; | |
43 ObjectWaiter * volatile _prev; | |
44 Thread* _thread; | |
10405 | 45 jlong _notifier_tid; |
1878 | 46 ParkEvent * _event; |
47 volatile int _notified ; | |
48 volatile TStates TState ; | |
49 Sorted _Sorted ; // List placement disposition | |
50 bool _active ; // Contention monitoring is enabled | |
51 public: | |
52 ObjectWaiter(Thread* thread); | |
53 | |
54 void wait_reenter_begin(ObjectMonitor *mon); | |
55 void wait_reenter_end(ObjectMonitor *mon); | |
56 }; | |
57 | |
10405 | 58 // forward declaration to avoid include tracing.hpp |
59 class EventJavaMonitorWait; | |
60 | |
0 | 61 // WARNING: |
62 // This is a very sensitive and fragile class. DO NOT make any | |
63 // change unless you are fully aware of the underlying semantics. | |
64 | |
65 // This class can not inherit from any other class, because I have | |
66 // to let the displaced header be the very first word. Otherwise I | |
67 // have to let markOop include this file, which would export the | |
68 // monitor data structure to everywhere. | |
69 // | |
70 // The ObjectMonitor class is used to implement JavaMonitors which have | |
71 // transformed from the lightweight structure of the thread stack to a | |
72 // heavy weight lock due to contention | |
73 | |
74 // It is also used as RawMonitor by the JVMTI | |
75 | |
76 | |
77 class ObjectMonitor { | |
78 public: | |
79 enum { | |
80 OM_OK, // no error | |
81 OM_SYSTEM_ERROR, // operating system error | |
82 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException | |
83 OM_INTERRUPTED, // Thread.interrupt() | |
84 OM_TIMED_OUT // Object.wait() timed out | |
85 }; | |
86 | |
87 public: | |
88 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... | |
89 // ByteSize would also be an appropriate type. | |
90 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } | |
91 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } | |
92 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } | |
93 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); } | |
94 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } | |
95 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; } | |
96 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; } | |
97 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); } | |
98 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); } | |
99 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; } | |
100 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);} | |
101 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); } | |
102 | |
103 public: | |
14309 | 104 // Eventually we'll make provisions for multiple callbacks, but |
0 | 105 // now one will suffice. |
106 static int (*SpinCallbackFunction)(intptr_t, int) ; | |
107 static intptr_t SpinCallbackArgument ; | |
108 | |
109 | |
110 public: | |
111 markOop header() const; | |
112 void set_header(markOop hdr); | |
113 | |
1878 | 114 intptr_t is_busy() const { |
115 // TODO-FIXME: merge _count and _waiters. | |
116 // TODO-FIXME: assert _owner == null implies _recursions = 0 | |
117 // TODO-FIXME: assert _WaitSet != null implies _count > 0 | |
118 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ; | |
119 } | |
120 | |
0 | 121 intptr_t is_entered(Thread* current) const; |
122 | |
123 void* owner() const; | |
124 void set_owner(void* owner); | |
125 | |
126 intptr_t waiters() const; | |
127 | |
128 intptr_t count() const; | |
129 void set_count(intptr_t count); | |
130 intptr_t contentions() const ; | |
1878 | 131 intptr_t recursions() const { return _recursions; } |
0 | 132 |
133 // JVM/DI GetMonitorInfo() needs this | |
1878 | 134 ObjectWaiter* first_waiter() { return _WaitSet; } |
135 ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; } | |
136 Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; } | |
137 | |
138 // initialize the monitor, exception the semaphore, all other fields | |
139 // are simple integers or pointers | |
140 ObjectMonitor() { | |
141 _header = NULL; | |
142 _count = 0; | |
143 _waiters = 0, | |
144 _recursions = 0; | |
145 _object = NULL; | |
146 _owner = NULL; | |
147 _WaitSet = NULL; | |
148 _WaitSetLock = 0 ; | |
149 _Responsible = NULL ; | |
150 _succ = NULL ; | |
151 _cxq = NULL ; | |
152 FreeNext = NULL ; | |
153 _EntryList = NULL ; | |
154 _SpinFreq = 0 ; | |
155 _SpinClock = 0 ; | |
156 OwnerIsThread = 0 ; | |
10405 | 157 _previous_owner_tid = 0; |
1878 | 158 } |
0 | 159 |
1878 | 160 ~ObjectMonitor() { |
161 // TODO: Add asserts ... | |
162 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 | |
163 // _count == 0 _EntryList == NULL etc | |
164 } | |
165 | |
166 private: | |
167 void Recycle () { | |
168 // TODO: add stronger asserts ... | |
169 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 | |
170 // _count == 0 EntryList == NULL | |
171 // _recursions == 0 _WaitSet == NULL | |
172 // TODO: assert (is_busy()|_recursions) == 0 | |
173 _succ = NULL ; | |
174 _EntryList = NULL ; | |
175 _cxq = NULL ; | |
176 _WaitSet = NULL ; | |
177 _recursions = 0 ; | |
178 _SpinFreq = 0 ; | |
179 _SpinClock = 0 ; | |
180 OwnerIsThread = 0 ; | |
181 } | |
182 | |
183 public: | |
0 | 184 |
185 void* object() const; | |
186 void* object_addr(); | |
187 void set_object(void* obj); | |
188 | |
189 bool check(TRAPS); // true if the thread owns the monitor. | |
190 void check_slow(TRAPS); | |
191 void clear(); | |
192 #ifndef PRODUCT | |
193 void verify(); | |
194 void print(); | |
195 #endif | |
196 | |
197 bool try_enter (TRAPS) ; | |
198 void enter(TRAPS); | |
10405 | 199 void exit(bool not_suspended, TRAPS); |
0 | 200 void wait(jlong millis, bool interruptable, TRAPS); |
201 void notify(TRAPS); | |
202 void notifyAll(TRAPS); | |
203 | |
204 // Use the following at your own risk | |
205 intptr_t complete_exit(TRAPS); | |
206 void reenter(intptr_t recursions, TRAPS); | |
207 | |
208 private: | |
209 void AddWaiter (ObjectWaiter * waiter) ; | |
1878 | 210 static void DeferredInitialize(); |
0 | 211 |
212 ObjectWaiter * DequeueWaiter () ; | |
213 void DequeueSpecificWaiter (ObjectWaiter * waiter) ; | |
214 void EnterI (TRAPS) ; | |
215 void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ; | |
216 void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ; | |
217 int TryLock (Thread * Self) ; | |
218 int NotRunnable (Thread * Self, Thread * Owner) ; | |
219 int TrySpin_Fixed (Thread * Self) ; | |
220 int TrySpin_VaryFrequency (Thread * Self) ; | |
221 int TrySpin_VaryDuration (Thread * Self) ; | |
222 void ctAsserts () ; | |
223 void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ; | |
224 bool ExitSuspendEquivalent (JavaThread * Self) ; | |
10405 | 225 void post_monitor_wait_event(EventJavaMonitorWait * event, |
226 jlong notifier_tid, | |
227 jlong timeout, | |
228 bool timedout); | |
0 | 229 |
230 private: | |
231 friend class ObjectSynchronizer; | |
232 friend class ObjectWaiter; | |
233 friend class VMStructs; | |
234 | |
235 // WARNING: this must be the very first word of ObjectMonitor | |
236 // This means this class can't use any virtual member functions. | |
237 // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the | |
238 // implicit 0 offset in emitted code. | |
239 | |
240 volatile markOop _header; // displaced object header word - mark | |
241 void* volatile _object; // backward object pointer - strong root | |
242 | |
243 double SharingPad [1] ; // temp to reduce false sharing | |
244 | |
245 // All the following fields must be machine word aligned | |
246 // The VM assumes write ordering wrt these fields, which can be | |
247 // read from other threads. | |
248 | |
1878 | 249 protected: // protected for jvmtiRawMonitor |
0 | 250 void * volatile _owner; // pointer to owning thread OR BasicLock |
10405 | 251 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor |
0 | 252 volatile intptr_t _recursions; // recursion count, 0 for first entry |
1878 | 253 private: |
0 | 254 int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock |
255 ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry. | |
256 // The list is actually composed of WaitNodes, acting | |
257 // as proxies for Threads. | |
1878 | 258 protected: |
0 | 259 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry. |
1878 | 260 private: |
0 | 261 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling |
262 Thread * volatile _Responsible ; | |
263 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP | |
264 | |
265 volatile int _Spinner ; // for exit->spinner handoff optimization | |
266 volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate | |
267 volatile int _SpinClock ; | |
268 volatile int _SpinDuration ; | |
269 volatile intptr_t _SpinState ; // MCS/CLH list of spinners | |
270 | |
271 // TODO-FIXME: _count, _waiters and _recursions should be of | |
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. | |
274 | |
14309 | 275 volatile intptr_t _count; // reference count to prevent reclamation/deflation |
0 | 276 // at stop-the-world time. See deflate_idle_monitors(). |
277 // _count is approximately |_WaitSet| + |_EntryList| | |
1878 | 278 protected: |
0 | 279 volatile intptr_t _waiters; // number of waiting threads |
1878 | 280 private: |
281 protected: | |
0 | 282 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor |
1878 | 283 private: |
0 | 284 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock |
285 | |
286 public: | |
287 int _QMix ; // Mixed prepend queue discipline | |
288 ObjectMonitor * FreeNext ; // Free list linkage | |
289 intptr_t StatA, StatsB ; | |
290 | |
1878 | 291 public: |
292 static void Initialize () ; | |
293 static PerfCounter * _sync_ContendedLockAttempts ; | |
294 static PerfCounter * _sync_FutileWakeups ; | |
295 static PerfCounter * _sync_Parks ; | |
296 static PerfCounter * _sync_EmptyNotifications ; | |
297 static PerfCounter * _sync_Notifications ; | |
298 static PerfCounter * _sync_SlowEnter ; | |
299 static PerfCounter * _sync_SlowExit ; | |
300 static PerfCounter * _sync_SlowNotify ; | |
301 static PerfCounter * _sync_SlowNotifyAll ; | |
302 static PerfCounter * _sync_FailedSpins ; | |
303 static PerfCounter * _sync_SuccessfulSpins ; | |
304 static PerfCounter * _sync_PrivateA ; | |
305 static PerfCounter * _sync_PrivateB ; | |
306 static PerfCounter * _sync_MonInCirculation ; | |
307 static PerfCounter * _sync_MonScavenged ; | |
308 static PerfCounter * _sync_Inflations ; | |
309 static PerfCounter * _sync_Deflations ; | |
310 static PerfLongVariable * _sync_MonExtant ; | |
311 | |
312 public: | |
313 static int Knob_Verbose; | |
314 static int Knob_SpinLimit; | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
10405
diff
changeset
|
315 void* operator new (size_t size) throw() { |
10271 | 316 return AllocateHeap(size, mtInternal); |
317 } | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
10405
diff
changeset
|
318 void* operator new[] (size_t size) throw() { |
10271 | 319 return operator new (size); |
320 } | |
321 void operator delete(void* p) { | |
322 FreeHeap(p, mtInternal); | |
323 } | |
324 void operator delete[] (void *p) { | |
325 operator delete(p); | |
326 } | |
0 | 327 }; |
1878 | 328 |
329 #undef TEVENT | |
330 #define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); } | |
331 | |
332 #define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }} | |
333 | |
334 #undef TEVENT | |
335 #define TEVENT(nom) {;} | |
336 | |
1972 | 337 |
338 #endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP |