Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/mutexLocker.hpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | bd02caa94611 |
children | 72f725c5a7be |
rev | line source |
---|---|
0 | 1 /* |
844 | 2 * Copyright 1997-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 // Mutexes used in the VM. | |
26 | |
27 extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code | |
28 extern Monitor* SystemDictionary_lock; // a lock on the system dictonary | |
29 extern Mutex* PackageTable_lock; // a lock on the class loader package table | |
30 extern Mutex* CompiledIC_lock; // a lock used to guard compiled IC patching and access | |
31 extern Mutex* InlineCacheBuffer_lock; // a lock used to guard the InlineCacheBuffer | |
32 extern Mutex* VMStatistic_lock; // a lock used to guard statistics count increment | |
33 extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles | |
34 extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list | |
35 extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke | |
36 extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers | |
37 extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers | |
38 extern Monitor* JNICritical_lock; // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in | |
39 extern Mutex* JvmtiThreadState_lock; // a lock on modification of JVMTI thread data | |
40 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
|
41 extern Monitor* Heap_lock; // a lock on the heap |
0 | 42 extern Mutex* ExpandHeap_lock; // a lock on expanding the heap |
43 extern Mutex* AdapterHandlerLibrary_lock; // a lock on the AdapterHandlerLibrary | |
44 extern Mutex* SignatureHandlerLibrary_lock; // a lock on the SignatureHandlerLibrary | |
45 extern Mutex* VtableStubs_lock; // a lock on the VtableStubs | |
46 extern Mutex* SymbolTable_lock; // a lock on the symbol table | |
47 extern Mutex* StringTable_lock; // a lock on the interned string table | |
48 extern Mutex* CodeCache_lock; // a lock on the CodeCache, rank is special, use MutexLockerEx | |
49 extern Mutex* MethodData_lock; // a lock on installation of method data | |
50 extern Mutex* RetData_lock; // a lock on installation of RetData inside method data | |
51 extern Mutex* DerivedPointerTableGC_lock; // a lock to protect the derived pointer table | |
52 extern Monitor* VMOperationQueue_lock; // a lock on queue of vm_operations waiting to execute | |
53 extern Monitor* VMOperationRequest_lock; // a lock on Threads waiting for a vm_operation to terminate | |
54 extern Monitor* Safepoint_lock; // a lock used by the safepoint abstraction | |
55 extern Monitor* Threads_lock; // a lock on the Threads table of active Java threads | |
56 // (also used by Safepoints too to block threads creation/destruction) | |
57 extern Monitor* CGC_lock; // used for coordination between | |
58 // fore- & background GC threads. | |
59 extern Mutex* STS_init_lock; // coordinate initialization of SuspendibleThreadSets. | |
60 extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL | |
61 extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification | |
62 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
|
63 extern Monitor* CMark_lock; // used for concurrent mark thread coordination |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
64 extern Monitor* ZF_mon; // used for G1 conc zero-fill. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
65 extern Monitor* Cleanup_mon; // used for G1 conc cleanup. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
66 extern Mutex* SATB_Q_FL_lock; // Protects SATB Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
67 // buffer free list. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
68 extern Monitor* SATB_Q_CBL_mon; // Protects SATB Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
69 // completed buffer queue. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
70 extern Mutex* Shared_SATB_Q_lock; // Lock protecting SATB |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
71 // queue shared by |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
72 // non-Java threads. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
73 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
74 extern Mutex* DirtyCardQ_FL_lock; // Protects dirty card Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
75 // buffer free list. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
76 extern Monitor* DirtyCardQ_CBL_mon; // Protects dirty card Q |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
77 // completed buffer queue. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
78 extern Mutex* Shared_DirtyCardQ_lock; // Lock protecting dirty card |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
79 // queue shared by |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
80 // non-Java threads. |
0 | 81 // (see option ExplicitGCInvokesConcurrent) |
82 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
|
83 extern Mutex* EvacFailureStack_lock; // guards the evac failure scan stack |
0 | 84 extern Mutex* Compile_lock; // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc) |
85 extern Monitor* MethodCompileQueue_lock; // a lock held when method compilations are enqueued, dequeued | |
86 #ifdef TIERED | |
87 extern Monitor* C1_lock; // a lock to ensure on single c1 compile is ever active | |
88 #endif // TIERED | |
89 extern Monitor* CompileThread_lock; // a lock held by compile threads during compilation system initialization | |
90 extern Mutex* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated | |
91 extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics | |
92 extern Mutex* MultiArray_lock; // a lock used to guard allocation of multi-dim arrays | |
93 extern Monitor* Terminator_lock; // a lock used to guard termination of the vm | |
94 extern Monitor* BeforeExit_lock; // a lock used to guard cleanups and shutdown hooks | |
95 extern Monitor* Notify_lock; // a lock used to synchronize the start-up of the vm | |
96 extern Monitor* Interrupt_lock; // a lock used for condition variable mediated interrupt processing | |
97 extern Monitor* ProfileVM_lock; // a lock used for profiling the VMThread | |
98 extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles | |
99 extern Mutex* ExceptionCache_lock; // a lock used to synchronize exception cache updates | |
100 extern Mutex* OsrList_lock; // a lock used to serialize access to OSR queues | |
101 | |
102 #ifndef PRODUCT | |
103 extern Mutex* FullGCALot_lock; // a lock to make FullGCALot MT safe | |
104 #endif | |
105 extern Mutex* Debug1_lock; // A bunch of pre-allocated locks that can be used for tracing | |
106 extern Mutex* Debug2_lock; // down synchronization related bugs! | |
107 extern Mutex* Debug3_lock; | |
108 | |
109 extern Mutex* RawMonitor_lock; | |
110 extern Mutex* PerfDataMemAlloc_lock; // a lock on the allocator for PerfData memory for performance data | |
111 extern Mutex* PerfDataManager_lock; // a long on access to PerfDataManager resources | |
112 extern Mutex* ParkerFreeList_lock; | |
113 extern Mutex* OopMapCacheAlloc_lock; // protects allocation of oop_map caches | |
114 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
115 extern Mutex* MMUTracker_lock; // protects the MMU |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
116 // tracker data structures |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
117 extern Mutex* HotCardCache_lock; // protects the hot card cache |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
55
diff
changeset
|
118 |
0 | 119 extern Mutex* Management_lock; // a lock used to serialize JVM management |
120 extern Monitor* LowMemory_lock; // a lock used for low memory detection | |
121 | |
122 // A MutexLocker provides mutual exclusion with respect to a given mutex | |
123 // for the scope which contains the locker. The lock is an OS lock, not | |
124 // an object lock, and the two do not interoperate. Do not use Mutex-based | |
125 // locks to lock on Java objects, because they will not be respected if a | |
126 // that object is locked using the Java locking mechanism. | |
127 // | |
128 // NOTE WELL!! | |
129 // | |
130 // See orderAccess.hpp. We assume throughout the VM that MutexLocker's | |
131 // and friends constructors do a fence, a lock and an acquire *in that | |
132 // order*. And that their destructors do a release and unlock, in *that* | |
133 // order. If their implementations change such that these assumptions | |
134 // are violated, a whole lot of code will break. | |
135 | |
136 // Print all mutexes/monitors that are currently owned by a thread; called | |
137 // by fatal error handler. | |
138 void print_owned_locks_on_error(outputStream* st); | |
139 | |
140 char *lock_name(Mutex *mutex); | |
141 | |
142 class MutexLocker: StackObj { | |
143 private: | |
144 Monitor * _mutex; | |
145 public: | |
146 MutexLocker(Monitor * mutex) { | |
147 assert(mutex->rank() != Mutex::special, | |
148 "Special ranked mutex should only use MutexLockerEx"); | |
149 _mutex = mutex; | |
150 _mutex->lock(); | |
151 } | |
152 | |
153 // Overloaded constructor passing current thread | |
154 MutexLocker(Monitor * mutex, Thread *thread) { | |
155 assert(mutex->rank() != Mutex::special, | |
156 "Special ranked mutex should only use MutexLockerEx"); | |
157 _mutex = mutex; | |
158 _mutex->lock(thread); | |
159 } | |
160 | |
161 ~MutexLocker() { | |
162 _mutex->unlock(); | |
163 } | |
164 | |
165 }; | |
166 | |
167 // for debugging: check that we're already owning this lock (or are at a safepoint) | |
168 #ifdef ASSERT | |
169 void assert_locked_or_safepoint(const Monitor * lock); | |
170 void assert_lock_strong(const Monitor * lock); | |
171 #else | |
172 #define assert_locked_or_safepoint(lock) | |
173 #define assert_lock_strong(lock) | |
174 #endif | |
175 | |
176 // A MutexLockerEx behaves like a MutexLocker when its constructor is | |
177 // called with a Mutex. Unlike a MutexLocker, its constructor can also be | |
178 // called with NULL, in which case the MutexLockerEx is a no-op. There | |
179 // is also a corresponding MutexUnlockerEx. We want to keep the | |
180 // basic MutexLocker as fast as possible. MutexLockerEx can also lock | |
181 // without safepoint check. | |
182 | |
183 class MutexLockerEx: public StackObj { | |
184 private: | |
185 Monitor * _mutex; | |
186 public: | |
187 MutexLockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { | |
188 _mutex = mutex; | |
189 if (_mutex != NULL) { | |
190 assert(mutex->rank() > Mutex::special || no_safepoint_check, | |
191 "Mutexes with rank special or lower should not do safepoint checks"); | |
192 if (no_safepoint_check) | |
193 _mutex->lock_without_safepoint_check(); | |
194 else | |
195 _mutex->lock(); | |
196 } | |
197 } | |
198 | |
199 ~MutexLockerEx() { | |
200 if (_mutex != NULL) { | |
201 _mutex->unlock(); | |
202 } | |
203 } | |
204 }; | |
205 | |
206 // A MonitorLockerEx is like a MutexLockerEx above, except it takes | |
207 // a possibly null Monitor, and allows wait/notify as well which are | |
208 // delegated to the underlying Monitor. | |
209 | |
210 class MonitorLockerEx: public MutexLockerEx { | |
211 private: | |
212 Monitor * _monitor; | |
213 public: | |
214 MonitorLockerEx(Monitor* monitor, | |
215 bool no_safepoint_check = !Mutex::_no_safepoint_check_flag): | |
216 MutexLockerEx(monitor, no_safepoint_check), | |
217 _monitor(monitor) { | |
218 // Superclass constructor did locking | |
219 } | |
220 | |
221 ~MonitorLockerEx() { | |
222 #ifdef ASSERT | |
223 if (_monitor != NULL) { | |
224 assert_lock_strong(_monitor); | |
225 } | |
226 #endif // ASSERT | |
227 // Superclass destructor will do unlocking | |
228 } | |
229 | |
230 bool wait(bool no_safepoint_check = !Mutex::_no_safepoint_check_flag, | |
231 long timeout = 0, | |
232 bool as_suspend_equivalent = !Mutex::_as_suspend_equivalent_flag) { | |
233 if (_monitor != NULL) { | |
234 return _monitor->wait(no_safepoint_check, timeout, as_suspend_equivalent); | |
235 } | |
236 return false; | |
237 } | |
238 | |
239 bool notify_all() { | |
240 if (_monitor != NULL) { | |
241 return _monitor->notify_all(); | |
242 } | |
243 return true; | |
244 } | |
245 | |
246 bool notify() { | |
247 if (_monitor != NULL) { | |
248 return _monitor->notify(); | |
249 } | |
250 return true; | |
251 } | |
252 }; | |
253 | |
254 | |
255 | |
256 // A GCMutexLocker is usually initialized with a mutex that is | |
257 // automatically acquired in order to do GC. The function that | |
258 // synchronizes using a GCMutexLocker may be called both during and between | |
259 // GC's. Thus, it must acquire the mutex if GC is not in progress, but not | |
260 // if GC is in progress (since the mutex is already held on its behalf.) | |
261 | |
262 class GCMutexLocker: public StackObj { | |
263 private: | |
264 Monitor * _mutex; | |
265 bool _locked; | |
266 public: | |
267 GCMutexLocker(Monitor * mutex); | |
268 ~GCMutexLocker() { if (_locked) _mutex->unlock(); } | |
269 }; | |
270 | |
271 | |
272 | |
273 // A MutexUnlocker temporarily exits a previously | |
274 // entered mutex for the scope which contains the unlocker. | |
275 | |
276 class MutexUnlocker: StackObj { | |
277 private: | |
278 Monitor * _mutex; | |
279 | |
280 public: | |
281 MutexUnlocker(Monitor * mutex) { | |
282 _mutex = mutex; | |
283 _mutex->unlock(); | |
284 } | |
285 | |
286 ~MutexUnlocker() { | |
287 _mutex->lock(); | |
288 } | |
289 }; | |
290 | |
291 // A MutexUnlockerEx temporarily exits a previously | |
292 // entered mutex for the scope which contains the unlocker. | |
293 | |
294 class MutexUnlockerEx: StackObj { | |
295 private: | |
296 Monitor * _mutex; | |
297 bool _no_safepoint_check; | |
298 | |
299 public: | |
300 MutexUnlockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { | |
301 _mutex = mutex; | |
302 _no_safepoint_check = no_safepoint_check; | |
303 _mutex->unlock(); | |
304 } | |
305 | |
306 ~MutexUnlockerEx() { | |
307 if (_no_safepoint_check == Mutex::_no_safepoint_check_flag) { | |
308 _mutex->lock_without_safepoint_check(); | |
309 } else { | |
310 _mutex->lock(); | |
311 } | |
312 } | |
313 }; | |
314 | |
315 #ifndef PRODUCT | |
316 // | |
317 // A special MutexLocker that allows: | |
318 // - reentrant locking | |
319 // - locking out of order | |
320 // | |
321 // Only too be used for verify code, where we can relaxe out dead-lock | |
322 // dection code a bit (unsafe, but probably ok). This code is NEVER to | |
323 // be included in a product version. | |
324 // | |
325 class VerifyMutexLocker: StackObj { | |
326 private: | |
327 Monitor * _mutex; | |
328 bool _reentrant; | |
329 public: | |
330 VerifyMutexLocker(Monitor * mutex) { | |
331 _mutex = mutex; | |
332 _reentrant = mutex->owned_by_self(); | |
333 if (!_reentrant) { | |
334 // We temp. diable strict safepoint checking, while we require the lock | |
335 FlagSetting fs(StrictSafepointChecks, false); | |
336 _mutex->lock(); | |
337 } | |
338 } | |
339 | |
340 ~VerifyMutexLocker() { | |
341 if (!_reentrant) { | |
342 _mutex->unlock(); | |
343 } | |
344 } | |
345 }; | |
346 | |
347 #endif |