Mercurial > hg > truffle
annotate src/share/vm/runtime/mutexLocker.hpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | e522a00b91aa |
children | 836a62f43af9 |
rev | line source |
---|---|
0 | 1 /* |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
3960
diff
changeset
|
2 * Copyright (c) 1997, 2012, 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:
1358
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1358
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:
1358
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_RUNTIME_MUTEXLOCKER_HPP |
26 #define SHARE_VM_RUNTIME_MUTEXLOCKER_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "runtime/mutex.hpp" | |
30 #ifdef TARGET_OS_FAMILY_linux | |
31 # include "os_linux.inline.hpp" | |
32 #endif | |
33 #ifdef TARGET_OS_FAMILY_solaris | |
34 # include "os_solaris.inline.hpp" | |
35 #endif | |
36 #ifdef TARGET_OS_FAMILY_windows | |
37 # include "os_windows.inline.hpp" | |
38 #endif | |
3960 | 39 #ifdef TARGET_OS_FAMILY_bsd |
40 # include "os_bsd.inline.hpp" | |
41 #endif | |
1972 | 42 |
0 | 43 // Mutexes used in the VM. |
44 | |
45 extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code | |
46 extern Monitor* SystemDictionary_lock; // a lock on the system dictonary | |
47 extern Mutex* PackageTable_lock; // a lock on the class loader package table | |
48 extern Mutex* CompiledIC_lock; // a lock used to guard compiled IC patching and access | |
49 extern Mutex* InlineCacheBuffer_lock; // a lock used to guard the InlineCacheBuffer | |
50 extern Mutex* VMStatistic_lock; // a lock used to guard statistics count increment | |
51 extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles | |
52 extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list | |
53 extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke | |
54 extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers | |
55 extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers | |
56 extern Monitor* JNICritical_lock; // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in | |
57 extern Mutex* JvmtiThreadState_lock; // a lock on modification of JVMTI thread data | |
58 extern Monitor* JvmtiPendingEvent_lock; // a lock on the JVMTI pending events list | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
59 extern Monitor* Heap_lock; // a lock on the heap |
0 | 60 extern Mutex* ExpandHeap_lock; // a lock on expanding the heap |
61 extern Mutex* AdapterHandlerLibrary_lock; // a lock on the AdapterHandlerLibrary | |
62 extern Mutex* SignatureHandlerLibrary_lock; // a lock on the SignatureHandlerLibrary | |
63 extern Mutex* VtableStubs_lock; // a lock on the VtableStubs | |
64 extern Mutex* SymbolTable_lock; // a lock on the symbol table | |
65 extern Mutex* StringTable_lock; // a lock on the interned string table | |
66 extern Mutex* CodeCache_lock; // a lock on the CodeCache, rank is special, use MutexLockerEx | |
67 extern Mutex* MethodData_lock; // a lock on installation of method data | |
68 extern Mutex* RetData_lock; // a lock on installation of RetData inside method data | |
69 extern Mutex* DerivedPointerTableGC_lock; // a lock to protect the derived pointer table | |
70 extern Monitor* VMOperationQueue_lock; // a lock on queue of vm_operations waiting to execute | |
71 extern Monitor* VMOperationRequest_lock; // a lock on Threads waiting for a vm_operation to terminate | |
72 extern Monitor* Safepoint_lock; // a lock used by the safepoint abstraction | |
73 extern Monitor* Threads_lock; // a lock on the Threads table of active Java threads | |
74 // (also used by Safepoints too to block threads creation/destruction) | |
75 extern Monitor* CGC_lock; // used for coordination between | |
76 // fore- & background GC threads. | |
77 extern Mutex* STS_init_lock; // coordinate initialization of SuspendibleThreadSets. | |
78 extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL | |
79 extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification | |
80 extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
81 extern Monitor* CMark_lock; // used for concurrent mark thread coordination |
1358
72f725c5a7be
6940310: G1: MT-unsafe calls to CM::region_stack_push() / CM::region_stack_pop()
tonyp
parents:
844
diff
changeset
|
82 extern Mutex* CMRegionStack_lock; // used for protecting accesses to the CM region stack |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
83 extern Mutex* SATB_Q_FL_lock; // Protects SATB Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
84 // buffer free list. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
85 extern Monitor* SATB_Q_CBL_mon; // Protects SATB Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
86 // completed buffer queue. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
87 extern Mutex* Shared_SATB_Q_lock; // Lock protecting SATB |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
88 // queue shared by |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
89 // non-Java threads. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
90 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
91 extern Mutex* DirtyCardQ_FL_lock; // Protects dirty card Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
92 // buffer free list. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
93 extern Monitor* DirtyCardQ_CBL_mon; // Protects dirty card Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
94 // completed buffer queue. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
95 extern Mutex* Shared_DirtyCardQ_lock; // Lock protecting dirty card |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
96 // queue shared by |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
97 // non-Java threads. |
0 | 98 // (see option ExplicitGCInvokesConcurrent) |
99 extern Mutex* ParGCRareEvent_lock; // Synchronizes various (rare) parallel GC ops. | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
100 extern Mutex* EvacFailureStack_lock; // guards the evac failure scan stack |
0 | 101 extern Mutex* Compile_lock; // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc) |
102 extern Monitor* MethodCompileQueue_lock; // a lock held when method compilations are enqueued, dequeued | |
103 extern Monitor* CompileThread_lock; // a lock held by compile threads during compilation system initialization | |
104 extern Mutex* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated | |
105 extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics | |
106 extern Mutex* MultiArray_lock; // a lock used to guard allocation of multi-dim arrays | |
107 extern Monitor* Terminator_lock; // a lock used to guard termination of the vm | |
108 extern Monitor* BeforeExit_lock; // a lock used to guard cleanups and shutdown hooks | |
109 extern Monitor* Notify_lock; // a lock used to synchronize the start-up of the vm | |
110 extern Monitor* Interrupt_lock; // a lock used for condition variable mediated interrupt processing | |
111 extern Monitor* ProfileVM_lock; // a lock used for profiling the VMThread | |
112 extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles | |
113 extern Mutex* ExceptionCache_lock; // a lock used to synchronize exception cache updates | |
114 extern Mutex* OsrList_lock; // a lock used to serialize access to OSR queues | |
115 | |
116 #ifndef PRODUCT | |
117 extern Mutex* FullGCALot_lock; // a lock to make FullGCALot MT safe | |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
3960
diff
changeset
|
118 #endif // PRODUCT |
0 | 119 extern Mutex* Debug1_lock; // A bunch of pre-allocated locks that can be used for tracing |
120 extern Mutex* Debug2_lock; // down synchronization related bugs! | |
121 extern Mutex* Debug3_lock; | |
122 | |
123 extern Mutex* RawMonitor_lock; | |
124 extern Mutex* PerfDataMemAlloc_lock; // a lock on the allocator for PerfData memory for performance data | |
125 extern Mutex* PerfDataManager_lock; // a long on access to PerfDataManager resources | |
126 extern Mutex* ParkerFreeList_lock; | |
127 extern Mutex* OopMapCacheAlloc_lock; // protects allocation of oop_map caches | |
128 | |
2152 | 129 extern Mutex* FreeList_lock; // protects the free region list during safepoints |
130 extern Monitor* SecondaryFreeList_lock; // protects the secondary free region list | |
131 extern Mutex* OldSets_lock; // protects the old region sets | |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
3960
diff
changeset
|
132 extern Monitor* RootRegionScan_lock; // used to notify that the CM threads have finished scanning the IM snapshot regions |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
133 extern Mutex* MMUTracker_lock; // protects the MMU |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
134 // tracker data structures |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
135 extern Mutex* HotCardCache_lock; // protects the hot card cache |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
136 |
0 | 137 extern Mutex* Management_lock; // a lock used to serialize JVM management |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2152
diff
changeset
|
138 extern Monitor* Service_lock; // a lock used for service thread operation |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
3960
diff
changeset
|
139 extern Mutex* Stacktrace_lock; // used to guard access to the stacktrace table |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
3960
diff
changeset
|
140 |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
3960
diff
changeset
|
141 extern Monitor* JfrQuery_lock; // protects JFR use |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
3960
diff
changeset
|
142 extern Monitor* JfrMsg_lock; // protects JFR messaging |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
3960
diff
changeset
|
143 extern Mutex* JfrBuffer_lock; // protects JFR buffer operations |
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
3960
diff
changeset
|
144 extern Mutex* JfrStream_lock; // protects JFR stream access |
6939
c284cf4781f0
7127792: Add the ability to change an existing PeriodicTask's execution interval
rbackman
parents:
4840
diff
changeset
|
145 extern Monitor* PeriodicTask_lock; // protects the periodic task structure |
0 | 146 |
5129
51111665eda6
Support for recording a leaf graph id for each deoptimization point in the debug info.
Lukas Stadler <lukas.stadler@jku.at>
parents:
4840
diff
changeset
|
147 #ifdef GRAAL |
51111665eda6
Support for recording a leaf graph id for each deoptimization point in the debug info.
Lukas Stadler <lukas.stadler@jku.at>
parents:
4840
diff
changeset
|
148 extern Mutex* GraalDeoptLeafGraphIds_lock; // protects access to the global array of deopt'ed leaf graphs |
51111665eda6
Support for recording a leaf graph id for each deoptimization point in the debug info.
Lukas Stadler <lukas.stadler@jku.at>
parents:
4840
diff
changeset
|
149 #endif // GRAAL |
51111665eda6
Support for recording a leaf graph id for each deoptimization point in the debug info.
Lukas Stadler <lukas.stadler@jku.at>
parents:
4840
diff
changeset
|
150 |
0 | 151 // A MutexLocker provides mutual exclusion with respect to a given mutex |
152 // for the scope which contains the locker. The lock is an OS lock, not | |
153 // an object lock, and the two do not interoperate. Do not use Mutex-based | |
154 // locks to lock on Java objects, because they will not be respected if a | |
155 // that object is locked using the Java locking mechanism. | |
156 // | |
157 // NOTE WELL!! | |
158 // | |
159 // See orderAccess.hpp. We assume throughout the VM that MutexLocker's | |
160 // and friends constructors do a fence, a lock and an acquire *in that | |
161 // order*. And that their destructors do a release and unlock, in *that* | |
162 // order. If their implementations change such that these assumptions | |
163 // are violated, a whole lot of code will break. | |
164 | |
165 // Print all mutexes/monitors that are currently owned by a thread; called | |
166 // by fatal error handler. | |
167 void print_owned_locks_on_error(outputStream* st); | |
168 | |
169 char *lock_name(Mutex *mutex); | |
170 | |
171 class MutexLocker: StackObj { | |
172 private: | |
173 Monitor * _mutex; | |
174 public: | |
175 MutexLocker(Monitor * mutex) { | |
176 assert(mutex->rank() != Mutex::special, | |
177 "Special ranked mutex should only use MutexLockerEx"); | |
178 _mutex = mutex; | |
179 _mutex->lock(); | |
180 } | |
181 | |
182 // Overloaded constructor passing current thread | |
183 MutexLocker(Monitor * mutex, Thread *thread) { | |
184 assert(mutex->rank() != Mutex::special, | |
185 "Special ranked mutex should only use MutexLockerEx"); | |
186 _mutex = mutex; | |
187 _mutex->lock(thread); | |
188 } | |
189 | |
190 ~MutexLocker() { | |
191 _mutex->unlock(); | |
192 } | |
193 | |
194 }; | |
195 | |
196 // for debugging: check that we're already owning this lock (or are at a safepoint) | |
197 #ifdef ASSERT | |
198 void assert_locked_or_safepoint(const Monitor * lock); | |
199 void assert_lock_strong(const Monitor * lock); | |
200 #else | |
201 #define assert_locked_or_safepoint(lock) | |
202 #define assert_lock_strong(lock) | |
203 #endif | |
204 | |
205 // A MutexLockerEx behaves like a MutexLocker when its constructor is | |
206 // called with a Mutex. Unlike a MutexLocker, its constructor can also be | |
207 // called with NULL, in which case the MutexLockerEx is a no-op. There | |
208 // is also a corresponding MutexUnlockerEx. We want to keep the | |
209 // basic MutexLocker as fast as possible. MutexLockerEx can also lock | |
210 // without safepoint check. | |
211 | |
212 class MutexLockerEx: public StackObj { | |
213 private: | |
214 Monitor * _mutex; | |
215 public: | |
216 MutexLockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { | |
217 _mutex = mutex; | |
218 if (_mutex != NULL) { | |
219 assert(mutex->rank() > Mutex::special || no_safepoint_check, | |
220 "Mutexes with rank special or lower should not do safepoint checks"); | |
221 if (no_safepoint_check) | |
222 _mutex->lock_without_safepoint_check(); | |
223 else | |
224 _mutex->lock(); | |
225 } | |
226 } | |
227 | |
228 ~MutexLockerEx() { | |
229 if (_mutex != NULL) { | |
230 _mutex->unlock(); | |
231 } | |
232 } | |
233 }; | |
234 | |
235 // A MonitorLockerEx is like a MutexLockerEx above, except it takes | |
236 // a possibly null Monitor, and allows wait/notify as well which are | |
237 // delegated to the underlying Monitor. | |
238 | |
239 class MonitorLockerEx: public MutexLockerEx { | |
240 private: | |
241 Monitor * _monitor; | |
242 public: | |
243 MonitorLockerEx(Monitor* monitor, | |
244 bool no_safepoint_check = !Mutex::_no_safepoint_check_flag): | |
245 MutexLockerEx(monitor, no_safepoint_check), | |
246 _monitor(monitor) { | |
247 // Superclass constructor did locking | |
248 } | |
249 | |
250 ~MonitorLockerEx() { | |
251 #ifdef ASSERT | |
252 if (_monitor != NULL) { | |
253 assert_lock_strong(_monitor); | |
254 } | |
255 #endif // ASSERT | |
256 // Superclass destructor will do unlocking | |
257 } | |
258 | |
259 bool wait(bool no_safepoint_check = !Mutex::_no_safepoint_check_flag, | |
260 long timeout = 0, | |
261 bool as_suspend_equivalent = !Mutex::_as_suspend_equivalent_flag) { | |
262 if (_monitor != NULL) { | |
263 return _monitor->wait(no_safepoint_check, timeout, as_suspend_equivalent); | |
264 } | |
265 return false; | |
266 } | |
267 | |
268 bool notify_all() { | |
269 if (_monitor != NULL) { | |
270 return _monitor->notify_all(); | |
271 } | |
272 return true; | |
273 } | |
274 | |
275 bool notify() { | |
276 if (_monitor != NULL) { | |
277 return _monitor->notify(); | |
278 } | |
279 return true; | |
280 } | |
281 }; | |
282 | |
283 | |
284 | |
285 // A GCMutexLocker is usually initialized with a mutex that is | |
286 // automatically acquired in order to do GC. The function that | |
287 // synchronizes using a GCMutexLocker may be called both during and between | |
288 // GC's. Thus, it must acquire the mutex if GC is not in progress, but not | |
289 // if GC is in progress (since the mutex is already held on its behalf.) | |
290 | |
291 class GCMutexLocker: public StackObj { | |
292 private: | |
293 Monitor * _mutex; | |
294 bool _locked; | |
295 public: | |
296 GCMutexLocker(Monitor * mutex); | |
297 ~GCMutexLocker() { if (_locked) _mutex->unlock(); } | |
298 }; | |
299 | |
300 | |
301 | |
302 // A MutexUnlocker temporarily exits a previously | |
303 // entered mutex for the scope which contains the unlocker. | |
304 | |
305 class MutexUnlocker: StackObj { | |
306 private: | |
307 Monitor * _mutex; | |
308 | |
309 public: | |
310 MutexUnlocker(Monitor * mutex) { | |
311 _mutex = mutex; | |
312 _mutex->unlock(); | |
313 } | |
314 | |
315 ~MutexUnlocker() { | |
316 _mutex->lock(); | |
317 } | |
318 }; | |
319 | |
320 // A MutexUnlockerEx temporarily exits a previously | |
321 // entered mutex for the scope which contains the unlocker. | |
322 | |
323 class MutexUnlockerEx: StackObj { | |
324 private: | |
325 Monitor * _mutex; | |
326 bool _no_safepoint_check; | |
327 | |
328 public: | |
329 MutexUnlockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { | |
330 _mutex = mutex; | |
331 _no_safepoint_check = no_safepoint_check; | |
332 _mutex->unlock(); | |
333 } | |
334 | |
335 ~MutexUnlockerEx() { | |
336 if (_no_safepoint_check == Mutex::_no_safepoint_check_flag) { | |
337 _mutex->lock_without_safepoint_check(); | |
338 } else { | |
339 _mutex->lock(); | |
340 } | |
341 } | |
342 }; | |
343 | |
344 #ifndef PRODUCT | |
345 // | |
346 // A special MutexLocker that allows: | |
347 // - reentrant locking | |
348 // - locking out of order | |
349 // | |
350 // Only too be used for verify code, where we can relaxe out dead-lock | |
351 // dection code a bit (unsafe, but probably ok). This code is NEVER to | |
352 // be included in a product version. | |
353 // | |
354 class VerifyMutexLocker: StackObj { | |
355 private: | |
356 Monitor * _mutex; | |
357 bool _reentrant; | |
358 public: | |
359 VerifyMutexLocker(Monitor * mutex) { | |
360 _mutex = mutex; | |
361 _reentrant = mutex->owned_by_self(); | |
362 if (!_reentrant) { | |
363 // We temp. diable strict safepoint checking, while we require the lock | |
364 FlagSetting fs(StrictSafepointChecks, false); | |
365 _mutex->lock(); | |
366 } | |
367 } | |
368 | |
369 ~VerifyMutexLocker() { | |
370 if (!_reentrant) { | |
371 _mutex->unlock(); | |
372 } | |
373 } | |
374 }; | |
375 | |
376 #endif | |
1972 | 377 |
378 #endif // SHARE_VM_RUNTIME_MUTEXLOCKER_HPP |