Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/objectMonitor.hpp @ 7588:f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data.
Reviewed-by: jrose, dholmes
Contributed-by: eric.mccorkle@oracle.com
author | coleenp |
---|---|
date | Mon, 14 Jan 2013 11:01:39 -0500 |
parents | c760f78e0a53 |
children | f9be75d21404 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1998, 2010, 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 |
33 // ObjectWaiter serves as a "proxy" or surrogate thread. | |
34 // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific | |
35 // ParkEvent instead. Beware, however, that the JVMTI code | |
36 // knows about ObjectWaiters, so we'll have to reconcile that code. | |
37 // See next_waiter(), first_waiter(), etc. | |
38 | |
39 class ObjectWaiter : public StackObj { | |
40 public: | |
41 enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ; | |
42 enum Sorted { PREPEND, APPEND, SORTED } ; | |
43 ObjectWaiter * volatile _next; | |
44 ObjectWaiter * volatile _prev; | |
45 Thread* _thread; | |
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 | |
0 | 58 // WARNING: |
59 // This is a very sensitive and fragile class. DO NOT make any | |
60 // change unless you are fully aware of the underlying semantics. | |
61 | |
62 // This class can not inherit from any other class, because I have | |
63 // to let the displaced header be the very first word. Otherwise I | |
64 // have to let markOop include this file, which would export the | |
65 // monitor data structure to everywhere. | |
66 // | |
67 // The ObjectMonitor class is used to implement JavaMonitors which have | |
68 // transformed from the lightweight structure of the thread stack to a | |
69 // heavy weight lock due to contention | |
70 | |
71 // It is also used as RawMonitor by the JVMTI | |
72 | |
73 | |
74 class ObjectMonitor { | |
75 public: | |
76 enum { | |
77 OM_OK, // no error | |
78 OM_SYSTEM_ERROR, // operating system error | |
79 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException | |
80 OM_INTERRUPTED, // Thread.interrupt() | |
81 OM_TIMED_OUT // Object.wait() timed out | |
82 }; | |
83 | |
84 public: | |
85 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... | |
86 // ByteSize would also be an appropriate type. | |
87 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } | |
88 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } | |
89 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } | |
90 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); } | |
91 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } | |
92 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; } | |
93 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; } | |
94 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); } | |
95 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); } | |
96 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; } | |
97 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);} | |
98 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); } | |
99 | |
100 public: | |
101 // Eventaully we'll make provisions for multiple callbacks, but | |
102 // now one will suffice. | |
103 static int (*SpinCallbackFunction)(intptr_t, int) ; | |
104 static intptr_t SpinCallbackArgument ; | |
105 | |
106 | |
107 public: | |
108 markOop header() const; | |
109 void set_header(markOop hdr); | |
110 | |
1878 | 111 intptr_t is_busy() const { |
112 // TODO-FIXME: merge _count and _waiters. | |
113 // TODO-FIXME: assert _owner == null implies _recursions = 0 | |
114 // TODO-FIXME: assert _WaitSet != null implies _count > 0 | |
115 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ; | |
116 } | |
117 | |
0 | 118 intptr_t is_entered(Thread* current) const; |
119 | |
120 void* owner() const; | |
121 void set_owner(void* owner); | |
122 | |
123 intptr_t waiters() const; | |
124 | |
125 intptr_t count() const; | |
126 void set_count(intptr_t count); | |
127 intptr_t contentions() const ; | |
1878 | 128 intptr_t recursions() const { return _recursions; } |
0 | 129 |
130 // JVM/DI GetMonitorInfo() needs this | |
1878 | 131 ObjectWaiter* first_waiter() { return _WaitSet; } |
132 ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; } | |
133 Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; } | |
134 | |
135 // initialize the monitor, exception the semaphore, all other fields | |
136 // are simple integers or pointers | |
137 ObjectMonitor() { | |
138 _header = NULL; | |
139 _count = 0; | |
140 _waiters = 0, | |
141 _recursions = 0; | |
142 _object = NULL; | |
143 _owner = NULL; | |
144 _WaitSet = NULL; | |
145 _WaitSetLock = 0 ; | |
146 _Responsible = NULL ; | |
147 _succ = NULL ; | |
148 _cxq = NULL ; | |
149 FreeNext = NULL ; | |
150 _EntryList = NULL ; | |
151 _SpinFreq = 0 ; | |
152 _SpinClock = 0 ; | |
153 OwnerIsThread = 0 ; | |
154 } | |
0 | 155 |
1878 | 156 ~ObjectMonitor() { |
157 // TODO: Add asserts ... | |
158 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 | |
159 // _count == 0 _EntryList == NULL etc | |
160 } | |
161 | |
162 private: | |
163 void Recycle () { | |
164 // TODO: add stronger asserts ... | |
165 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 | |
166 // _count == 0 EntryList == NULL | |
167 // _recursions == 0 _WaitSet == NULL | |
168 // TODO: assert (is_busy()|_recursions) == 0 | |
169 _succ = NULL ; | |
170 _EntryList = NULL ; | |
171 _cxq = NULL ; | |
172 _WaitSet = NULL ; | |
173 _recursions = 0 ; | |
174 _SpinFreq = 0 ; | |
175 _SpinClock = 0 ; | |
176 OwnerIsThread = 0 ; | |
177 } | |
178 | |
179 public: | |
0 | 180 |
181 void* object() const; | |
182 void* object_addr(); | |
183 void set_object(void* obj); | |
184 | |
185 bool check(TRAPS); // true if the thread owns the monitor. | |
186 void check_slow(TRAPS); | |
187 void clear(); | |
188 #ifndef PRODUCT | |
189 void verify(); | |
190 void print(); | |
191 #endif | |
192 | |
193 bool try_enter (TRAPS) ; | |
194 void enter(TRAPS); | |
195 void exit(TRAPS); | |
196 void wait(jlong millis, bool interruptable, TRAPS); | |
197 void notify(TRAPS); | |
198 void notifyAll(TRAPS); | |
199 | |
200 // Use the following at your own risk | |
201 intptr_t complete_exit(TRAPS); | |
202 void reenter(intptr_t recursions, TRAPS); | |
203 | |
204 private: | |
205 void AddWaiter (ObjectWaiter * waiter) ; | |
1878 | 206 static void DeferredInitialize(); |
0 | 207 |
208 ObjectWaiter * DequeueWaiter () ; | |
209 void DequeueSpecificWaiter (ObjectWaiter * waiter) ; | |
210 void EnterI (TRAPS) ; | |
211 void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ; | |
212 void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ; | |
213 int TryLock (Thread * Self) ; | |
214 int NotRunnable (Thread * Self, Thread * Owner) ; | |
215 int TrySpin_Fixed (Thread * Self) ; | |
216 int TrySpin_VaryFrequency (Thread * Self) ; | |
217 int TrySpin_VaryDuration (Thread * Self) ; | |
218 void ctAsserts () ; | |
219 void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ; | |
220 bool ExitSuspendEquivalent (JavaThread * Self) ; | |
221 | |
222 private: | |
223 friend class ObjectSynchronizer; | |
224 friend class ObjectWaiter; | |
225 friend class VMStructs; | |
226 | |
227 // WARNING: this must be the very first word of ObjectMonitor | |
228 // This means this class can't use any virtual member functions. | |
229 // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the | |
230 // implicit 0 offset in emitted code. | |
231 | |
232 volatile markOop _header; // displaced object header word - mark | |
233 void* volatile _object; // backward object pointer - strong root | |
234 | |
235 double SharingPad [1] ; // temp to reduce false sharing | |
236 | |
237 // All the following fields must be machine word aligned | |
238 // The VM assumes write ordering wrt these fields, which can be | |
239 // read from other threads. | |
240 | |
1878 | 241 protected: // protected for jvmtiRawMonitor |
0 | 242 void * volatile _owner; // pointer to owning thread OR BasicLock |
243 volatile intptr_t _recursions; // recursion count, 0 for first entry | |
1878 | 244 private: |
0 | 245 int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock |
246 ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry. | |
247 // The list is actually composed of WaitNodes, acting | |
248 // as proxies for Threads. | |
1878 | 249 protected: |
0 | 250 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry. |
1878 | 251 private: |
0 | 252 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling |
253 Thread * volatile _Responsible ; | |
254 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP | |
255 | |
256 volatile int _Spinner ; // for exit->spinner handoff optimization | |
257 volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate | |
258 volatile int _SpinClock ; | |
259 volatile int _SpinDuration ; | |
260 volatile intptr_t _SpinState ; // MCS/CLH list of spinners | |
261 | |
262 // TODO-FIXME: _count, _waiters and _recursions should be of | |
263 // type int, or int32_t but not intptr_t. There's no reason | |
264 // to use 64-bit fields for these variables on a 64-bit JVM. | |
265 | |
266 volatile intptr_t _count; // reference count to prevent reclaimation/deflation | |
267 // at stop-the-world time. See deflate_idle_monitors(). | |
268 // _count is approximately |_WaitSet| + |_EntryList| | |
1878 | 269 protected: |
0 | 270 volatile intptr_t _waiters; // number of waiting threads |
1878 | 271 private: |
272 protected: | |
0 | 273 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor |
1878 | 274 private: |
0 | 275 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock |
276 | |
277 public: | |
278 int _QMix ; // Mixed prepend queue discipline | |
279 ObjectMonitor * FreeNext ; // Free list linkage | |
280 intptr_t StatA, StatsB ; | |
281 | |
1878 | 282 public: |
283 static void Initialize () ; | |
284 static PerfCounter * _sync_ContendedLockAttempts ; | |
285 static PerfCounter * _sync_FutileWakeups ; | |
286 static PerfCounter * _sync_Parks ; | |
287 static PerfCounter * _sync_EmptyNotifications ; | |
288 static PerfCounter * _sync_Notifications ; | |
289 static PerfCounter * _sync_SlowEnter ; | |
290 static PerfCounter * _sync_SlowExit ; | |
291 static PerfCounter * _sync_SlowNotify ; | |
292 static PerfCounter * _sync_SlowNotifyAll ; | |
293 static PerfCounter * _sync_FailedSpins ; | |
294 static PerfCounter * _sync_SuccessfulSpins ; | |
295 static PerfCounter * _sync_PrivateA ; | |
296 static PerfCounter * _sync_PrivateB ; | |
297 static PerfCounter * _sync_MonInCirculation ; | |
298 static PerfCounter * _sync_MonScavenged ; | |
299 static PerfCounter * _sync_Inflations ; | |
300 static PerfCounter * _sync_Deflations ; | |
301 static PerfLongVariable * _sync_MonExtant ; | |
302 | |
303 public: | |
304 static int Knob_Verbose; | |
305 static int Knob_SpinLimit; | |
0 | 306 }; |
1878 | 307 |
308 #undef TEVENT | |
309 #define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); } | |
310 | |
311 #define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }} | |
312 | |
313 #undef TEVENT | |
314 #define TEVENT(nom) {;} | |
315 | |
1972 | 316 |
317 #endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP |