Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/synchronizer.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | 1d1603768966 |
children | 0654ee04b214 f08d439fab8c |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 1998, 2011, 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:
702
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
702
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:
702
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/vmSymbols.hpp" | |
27 #include "memory/resourceArea.hpp" | |
28 #include "oops/markOop.hpp" | |
29 #include "oops/oop.inline.hpp" | |
30 #include "runtime/biasedLocking.hpp" | |
31 #include "runtime/handles.inline.hpp" | |
32 #include "runtime/interfaceSupport.hpp" | |
33 #include "runtime/mutexLocker.hpp" | |
34 #include "runtime/objectMonitor.hpp" | |
35 #include "runtime/objectMonitor.inline.hpp" | |
36 #include "runtime/osThread.hpp" | |
37 #include "runtime/stubRoutines.hpp" | |
38 #include "runtime/synchronizer.hpp" | |
39 #include "utilities/dtrace.hpp" | |
40 #include "utilities/events.hpp" | |
41 #include "utilities/preserveException.hpp" | |
42 #ifdef TARGET_OS_FAMILY_linux | |
43 # include "os_linux.inline.hpp" | |
44 # include "thread_linux.inline.hpp" | |
45 #endif | |
46 #ifdef TARGET_OS_FAMILY_solaris | |
47 # include "os_solaris.inline.hpp" | |
48 # include "thread_solaris.inline.hpp" | |
49 #endif | |
50 #ifdef TARGET_OS_FAMILY_windows | |
51 # include "os_windows.inline.hpp" | |
52 # include "thread_windows.inline.hpp" | |
53 #endif | |
0 | 54 |
55 #if defined(__GNUC__) && !defined(IA64) | |
56 // Need to inhibit inlining for older versions of GCC to avoid build-time failures | |
57 #define ATTR __attribute__((noinline)) | |
58 #else | |
59 #define ATTR | |
60 #endif | |
61 | |
62 // The "core" versions of monitor enter and exit reside in this file. | |
63 // The interpreter and compilers contain specialized transliterated | |
64 // variants of the enter-exit fast-path operations. See i486.ad fast_lock(), | |
65 // for instance. If you make changes here, make sure to modify the | |
66 // interpreter, and both C1 and C2 fast-path inline locking code emission. | |
67 // | |
68 // | |
69 // ----------------------------------------------------------------------------- | |
70 | |
71 #ifdef DTRACE_ENABLED | |
72 | |
73 // Only bother with this argument setup if dtrace is available | |
74 // TODO-FIXME: probes should not fire when caller is _blocked. assert() accordingly. | |
75 | |
76 HS_DTRACE_PROBE_DECL5(hotspot, monitor__wait, | |
77 jlong, uintptr_t, char*, int, long); | |
78 HS_DTRACE_PROBE_DECL4(hotspot, monitor__waited, | |
79 jlong, uintptr_t, char*, int); | |
80 | |
81 #define DTRACE_MONITOR_PROBE_COMMON(klassOop, thread) \ | |
82 char* bytes = NULL; \ | |
83 int len = 0; \ | |
84 jlong jtid = SharedRuntime::get_java_tid(thread); \ | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
85 Symbol* klassname = ((oop)(klassOop))->klass()->klass_part()->name(); \ |
0 | 86 if (klassname != NULL) { \ |
87 bytes = (char*)klassname->bytes(); \ | |
88 len = klassname->utf8_length(); \ | |
89 } | |
90 | |
91 #define DTRACE_MONITOR_WAIT_PROBE(monitor, klassOop, thread, millis) \ | |
92 { \ | |
93 if (DTraceMonitorProbes) { \ | |
94 DTRACE_MONITOR_PROBE_COMMON(klassOop, thread); \ | |
95 HS_DTRACE_PROBE5(hotspot, monitor__wait, jtid, \ | |
96 (monitor), bytes, len, (millis)); \ | |
97 } \ | |
98 } | |
99 | |
100 #define DTRACE_MONITOR_PROBE(probe, monitor, klassOop, thread) \ | |
101 { \ | |
102 if (DTraceMonitorProbes) { \ | |
103 DTRACE_MONITOR_PROBE_COMMON(klassOop, thread); \ | |
104 HS_DTRACE_PROBE4(hotspot, monitor__##probe, jtid, \ | |
105 (uintptr_t)(monitor), bytes, len); \ | |
106 } \ | |
107 } | |
108 | |
109 #else // ndef DTRACE_ENABLED | |
110 | |
111 #define DTRACE_MONITOR_WAIT_PROBE(klassOop, thread, millis, mon) {;} | |
112 #define DTRACE_MONITOR_PROBE(probe, klassOop, thread, mon) {;} | |
113 | |
114 #endif // ndef DTRACE_ENABLED | |
115 | |
1878 | 116 // This exists only as a workaround of dtrace bug 6254741 |
117 int dtrace_waited_probe(ObjectMonitor* monitor, Handle obj, Thread* thr) { | |
118 DTRACE_MONITOR_PROBE(waited, monitor, obj(), thr); | |
119 return 0; | |
120 } | |
121 | |
122 #define NINFLATIONLOCKS 256 | |
123 static volatile intptr_t InflationLocks [NINFLATIONLOCKS] ; | |
124 | |
125 ObjectMonitor * ObjectSynchronizer::gBlockList = NULL ; | |
126 ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL ; | |
127 ObjectMonitor * volatile ObjectSynchronizer::gOmInUseList = NULL ; | |
128 int ObjectSynchronizer::gOmInUseCount = 0; | |
129 static volatile intptr_t ListLock = 0 ; // protects global monitor free-list cache | |
130 static volatile int MonitorFreeCount = 0 ; // # on gFreeList | |
131 static volatile int MonitorPopulation = 0 ; // # Extant -- in circulation | |
132 #define CHAINMARKER ((oop)-1) | |
133 | |
134 // ----------------------------------------------------------------------------- | |
135 // Fast Monitor Enter/Exit | |
136 // This the fast monitor enter. The interpreter and compiler use | |
137 // some assembly copies of this code. Make sure update those code | |
138 // if the following function is changed. The implementation is | |
139 // extremely sensitive to race condition. Be careful. | |
140 | |
141 void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS) { | |
142 if (UseBiasedLocking) { | |
143 if (!SafepointSynchronize::is_at_safepoint()) { | |
144 BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD); | |
145 if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) { | |
146 return; | |
147 } | |
148 } else { | |
149 assert(!attempt_rebias, "can not rebias toward VM thread"); | |
150 BiasedLocking::revoke_at_safepoint(obj); | |
151 } | |
152 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
153 } | |
154 | |
155 slow_enter (obj, lock, THREAD) ; | |
156 } | |
157 | |
158 void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) { | |
159 assert(!object->mark()->has_bias_pattern(), "should not see bias pattern here"); | |
160 // if displaced header is null, the previous enter is recursive enter, no-op | |
161 markOop dhw = lock->displaced_header(); | |
162 markOop mark ; | |
163 if (dhw == NULL) { | |
164 // Recursive stack-lock. | |
165 // Diagnostics -- Could be: stack-locked, inflating, inflated. | |
166 mark = object->mark() ; | |
167 assert (!mark->is_neutral(), "invariant") ; | |
168 if (mark->has_locker() && mark != markOopDesc::INFLATING()) { | |
169 assert(THREAD->is_lock_owned((address)mark->locker()), "invariant") ; | |
170 } | |
171 if (mark->has_monitor()) { | |
172 ObjectMonitor * m = mark->monitor() ; | |
173 assert(((oop)(m->object()))->mark() == mark, "invariant") ; | |
174 assert(m->is_entered(THREAD), "invariant") ; | |
175 } | |
176 return ; | |
177 } | |
178 | |
179 mark = object->mark() ; | |
0 | 180 |
1878 | 181 // If the object is stack-locked by the current thread, try to |
182 // swing the displaced header from the box back to the mark. | |
183 if (mark == (markOop) lock) { | |
184 assert (dhw->is_neutral(), "invariant") ; | |
185 if ((markOop) Atomic::cmpxchg_ptr (dhw, object->mark_addr(), mark) == mark) { | |
186 TEVENT (fast_exit: release stacklock) ; | |
187 return; | |
188 } | |
189 } | |
190 | |
191 ObjectSynchronizer::inflate(THREAD, object)->exit (THREAD) ; | |
192 } | |
193 | |
194 // ----------------------------------------------------------------------------- | |
195 // Interpreter/Compiler Slow Case | |
196 // This routine is used to handle interpreter/compiler slow case | |
197 // We don't need to use fast path here, because it must have been | |
198 // failed in the interpreter/compiler code. | |
199 void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) { | |
200 markOop mark = obj->mark(); | |
201 assert(!mark->has_bias_pattern(), "should not see bias pattern here"); | |
202 | |
203 if (mark->is_neutral()) { | |
204 // Anticipate successful CAS -- the ST of the displaced mark must | |
205 // be visible <= the ST performed by the CAS. | |
206 lock->set_displaced_header(mark); | |
207 if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) { | |
208 TEVENT (slow_enter: release stacklock) ; | |
209 return ; | |
210 } | |
211 // Fall through to inflate() ... | |
212 } else | |
213 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { | |
214 assert(lock != mark->locker(), "must not re-lock the same lock"); | |
215 assert(lock != (BasicLock*)obj->mark(), "don't relock with same BasicLock"); | |
216 lock->set_displaced_header(NULL); | |
217 return; | |
218 } | |
219 | |
220 #if 0 | |
221 // The following optimization isn't particularly useful. | |
222 if (mark->has_monitor() && mark->monitor()->is_entered(THREAD)) { | |
223 lock->set_displaced_header (NULL) ; | |
224 return ; | |
225 } | |
226 #endif | |
227 | |
228 // The object header will never be displaced to this lock, | |
229 // so it does not matter what the value is, except that it | |
230 // must be non-zero to avoid looking like a re-entrant lock, | |
231 // and must not look locked either. | |
232 lock->set_displaced_header(markOopDesc::unused_mark()); | |
233 ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); | |
234 } | |
235 | |
236 // This routine is used to handle interpreter/compiler slow case | |
237 // We don't need to use fast path here, because it must have | |
238 // failed in the interpreter/compiler code. Simply use the heavy | |
239 // weight monitor should be ok, unless someone find otherwise. | |
240 void ObjectSynchronizer::slow_exit(oop object, BasicLock* lock, TRAPS) { | |
241 fast_exit (object, lock, THREAD) ; | |
242 } | |
243 | |
244 // ----------------------------------------------------------------------------- | |
245 // Class Loader support to workaround deadlocks on the class loader lock objects | |
246 // Also used by GC | |
247 // complete_exit()/reenter() are used to wait on a nested lock | |
248 // i.e. to give up an outer lock completely and then re-enter | |
249 // Used when holding nested locks - lock acquisition order: lock1 then lock2 | |
250 // 1) complete_exit lock1 - saving recursion count | |
251 // 2) wait on lock2 | |
252 // 3) when notified on lock2, unlock lock2 | |
253 // 4) reenter lock1 with original recursion count | |
254 // 5) lock lock2 | |
255 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() | |
256 intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { | |
257 TEVENT (complete_exit) ; | |
258 if (UseBiasedLocking) { | |
259 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
260 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
0 | 261 } |
262 | |
1878 | 263 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); |
264 | |
265 return monitor->complete_exit(THREAD); | |
266 } | |
267 | |
268 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() | |
269 void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) { | |
270 TEVENT (reenter) ; | |
271 if (UseBiasedLocking) { | |
272 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
273 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
274 } | |
275 | |
276 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); | |
277 | |
278 monitor->reenter(recursion, THREAD); | |
279 } | |
280 // ----------------------------------------------------------------------------- | |
281 // JNI locks on java objects | |
282 // NOTE: must use heavy weight monitor to handle jni monitor enter | |
283 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { // possible entry from jni enter | |
284 // the current locking is from JNI instead of Java code | |
285 TEVENT (jni_enter) ; | |
286 if (UseBiasedLocking) { | |
287 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
288 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
289 } | |
290 THREAD->set_current_pending_monitor_is_from_java(false); | |
291 ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); | |
292 THREAD->set_current_pending_monitor_is_from_java(true); | |
293 } | |
294 | |
295 // NOTE: must use heavy weight monitor to handle jni monitor enter | |
296 bool ObjectSynchronizer::jni_try_enter(Handle obj, Thread* THREAD) { | |
297 if (UseBiasedLocking) { | |
298 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
299 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
0 | 300 } |
301 | |
1878 | 302 ObjectMonitor* monitor = ObjectSynchronizer::inflate_helper(obj()); |
303 return monitor->try_enter(THREAD); | |
304 } | |
305 | |
306 | |
307 // NOTE: must use heavy weight monitor to handle jni monitor exit | |
308 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { | |
309 TEVENT (jni_exit) ; | |
310 if (UseBiasedLocking) { | |
311 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
312 } | |
313 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
314 | |
315 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj); | |
316 // If this thread has locked the object, exit the monitor. Note: can't use | |
317 // monitor->check(CHECK); must exit even if an exception is pending. | |
318 if (monitor->check(THREAD)) { | |
319 monitor->exit(THREAD); | |
0 | 320 } |
1878 | 321 } |
322 | |
323 // ----------------------------------------------------------------------------- | |
324 // Internal VM locks on java objects | |
325 // standard constructor, allows locking failures | |
326 ObjectLocker::ObjectLocker(Handle obj, Thread* thread, bool doLock) { | |
327 _dolock = doLock; | |
328 _thread = thread; | |
329 debug_only(if (StrictSafepointChecks) _thread->check_for_valid_safepoint_state(false);) | |
330 _obj = obj; | |
0 | 331 |
1878 | 332 if (_dolock) { |
333 TEVENT (ObjectLocker) ; | |
334 | |
335 ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread); | |
336 } | |
337 } | |
338 | |
339 ObjectLocker::~ObjectLocker() { | |
340 if (_dolock) { | |
341 ObjectSynchronizer::fast_exit(_obj(), &_lock, _thread); | |
342 } | |
343 } | |
0 | 344 |
345 | |
1878 | 346 // ----------------------------------------------------------------------------- |
347 // Wait/Notify/NotifyAll | |
348 // NOTE: must use heavy weight monitor to handle wait() | |
349 void ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) { | |
350 if (UseBiasedLocking) { | |
351 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
352 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
353 } | |
354 if (millis < 0) { | |
355 TEVENT (wait - throw IAX) ; | |
356 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); | |
357 } | |
358 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); | |
359 DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis); | |
360 monitor->wait(millis, true, THREAD); | |
361 | |
362 /* This dummy call is in place to get around dtrace bug 6254741. Once | |
363 that's fixed we can uncomment the following line and remove the call */ | |
364 // DTRACE_MONITOR_PROBE(waited, monitor, obj(), THREAD); | |
365 dtrace_waited_probe(monitor, obj, THREAD); | |
366 } | |
0 | 367 |
1878 | 368 void ObjectSynchronizer::waitUninterruptibly (Handle obj, jlong millis, TRAPS) { |
369 if (UseBiasedLocking) { | |
370 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
371 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
372 } | |
373 if (millis < 0) { | |
374 TEVENT (wait - throw IAX) ; | |
375 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); | |
376 } | |
377 ObjectSynchronizer::inflate(THREAD, obj()) -> wait(millis, false, THREAD) ; | |
378 } | |
379 | |
380 void ObjectSynchronizer::notify(Handle obj, TRAPS) { | |
381 if (UseBiasedLocking) { | |
382 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
383 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
384 } | |
0 | 385 |
1878 | 386 markOop mark = obj->mark(); |
387 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { | |
388 return; | |
389 } | |
390 ObjectSynchronizer::inflate(THREAD, obj())->notify(THREAD); | |
391 } | |
0 | 392 |
1878 | 393 // NOTE: see comment of notify() |
394 void ObjectSynchronizer::notifyall(Handle obj, TRAPS) { | |
395 if (UseBiasedLocking) { | |
396 BiasedLocking::revoke_and_rebias(obj, false, THREAD); | |
397 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
398 } | |
399 | |
400 markOop mark = obj->mark(); | |
401 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { | |
402 return; | |
403 } | |
404 ObjectSynchronizer::inflate(THREAD, obj())->notifyAll(THREAD); | |
405 } | |
406 | |
407 // ----------------------------------------------------------------------------- | |
408 // Hash Code handling | |
409 // | |
0 | 410 // Performance concern: |
411 // OrderAccess::storestore() calls release() which STs 0 into the global volatile | |
412 // OrderAccess::Dummy variable. This store is unnecessary for correctness. | |
413 // Many threads STing into a common location causes considerable cache migration | |
414 // or "sloshing" on large SMP system. As such, I avoid using OrderAccess::storestore() | |
415 // until it's repaired. In some cases OrderAccess::fence() -- which incurs local | |
416 // latency on the executing processor -- is a better choice as it scales on SMP | |
417 // systems. See http://blogs.sun.com/dave/entry/biased_locking_in_hotspot for a | |
418 // discussion of coherency costs. Note that all our current reference platforms | |
419 // provide strong ST-ST order, so the issue is moot on IA32, x64, and SPARC. | |
420 // | |
421 // As a general policy we use "volatile" to control compiler-based reordering | |
422 // and explicit fences (barriers) to control for architectural reordering performed | |
423 // by the CPU(s) or platform. | |
424 | |
425 static int MBFence (int x) { OrderAccess::fence(); return x; } | |
426 | |
427 struct SharedGlobals { | |
428 // These are highly shared mostly-read variables. | |
429 // To avoid false-sharing they need to be the sole occupants of a $ line. | |
430 double padPrefix [8]; | |
431 volatile int stwRandom ; | |
432 volatile int stwCycle ; | |
433 | |
434 // Hot RW variables -- Sequester to avoid false-sharing | |
435 double padSuffix [16]; | |
436 volatile int hcSequence ; | |
437 double padFinal [8] ; | |
438 } ; | |
439 | |
440 static SharedGlobals GVars ; | |
1587 | 441 static int MonitorScavengeThreshold = 1000000 ; |
442 static volatile int ForceMonitorScavenge = 0 ; // Scavenge required and pending | |
0 | 443 |
1878 | 444 static markOop ReadStableMark (oop obj) { |
445 markOop mark = obj->mark() ; | |
446 if (!mark->is_being_inflated()) { | |
447 return mark ; // normal fast-path return | |
448 } | |
0 | 449 |
1878 | 450 int its = 0 ; |
451 for (;;) { | |
452 markOop mark = obj->mark() ; | |
453 if (!mark->is_being_inflated()) { | |
454 return mark ; // normal fast-path return | |
455 } | |
456 | |
457 // The object is being inflated by some other thread. | |
458 // The caller of ReadStableMark() must wait for inflation to complete. | |
459 // Avoid live-lock | |
460 // TODO: consider calling SafepointSynchronize::do_call_back() while | |
461 // spinning to see if there's a safepoint pending. If so, immediately | |
462 // yielding or blocking would be appropriate. Avoid spinning while | |
463 // there is a safepoint pending. | |
464 // TODO: add inflation contention performance counters. | |
465 // TODO: restrict the aggregate number of spinners. | |
0 | 466 |
1878 | 467 ++its ; |
468 if (its > 10000 || !os::is_MP()) { | |
469 if (its & 1) { | |
470 os::NakedYield() ; | |
471 TEVENT (Inflate: INFLATING - yield) ; | |
472 } else { | |
473 // Note that the following code attenuates the livelock problem but is not | |
474 // a complete remedy. A more complete solution would require that the inflating | |
475 // thread hold the associated inflation lock. The following code simply restricts | |
476 // the number of spinners to at most one. We'll have N-2 threads blocked | |
477 // on the inflationlock, 1 thread holding the inflation lock and using | |
478 // a yield/park strategy, and 1 thread in the midst of inflation. | |
479 // A more refined approach would be to change the encoding of INFLATING | |
480 // to allow encapsulation of a native thread pointer. Threads waiting for | |
481 // inflation to complete would use CAS to push themselves onto a singly linked | |
482 // list rooted at the markword. Once enqueued, they'd loop, checking a per-thread flag | |
483 // and calling park(). When inflation was complete the thread that accomplished inflation | |
484 // would detach the list and set the markword to inflated with a single CAS and | |
485 // then for each thread on the list, set the flag and unpark() the thread. | |
486 // This is conceptually similar to muxAcquire-muxRelease, except that muxRelease | |
487 // wakes at most one thread whereas we need to wake the entire list. | |
488 int ix = (intptr_t(obj) >> 5) & (NINFLATIONLOCKS-1) ; | |
489 int YieldThenBlock = 0 ; | |
490 assert (ix >= 0 && ix < NINFLATIONLOCKS, "invariant") ; | |
491 assert ((NINFLATIONLOCKS & (NINFLATIONLOCKS-1)) == 0, "invariant") ; | |
492 Thread::muxAcquire (InflationLocks + ix, "InflationLock") ; | |
493 while (obj->mark() == markOopDesc::INFLATING()) { | |
494 // Beware: NakedYield() is advisory and has almost no effect on some platforms | |
495 // so we periodically call Self->_ParkEvent->park(1). | |
496 // We use a mixed spin/yield/block mechanism. | |
497 if ((YieldThenBlock++) >= 16) { | |
498 Thread::current()->_ParkEvent->park(1) ; | |
499 } else { | |
500 os::NakedYield() ; | |
501 } | |
502 } | |
503 Thread::muxRelease (InflationLocks + ix ) ; | |
504 TEVENT (Inflate: INFLATING - yield/park) ; | |
505 } | |
506 } else { | |
507 SpinPause() ; // SMP-polite spinning | |
508 } | |
509 } | |
510 } | |
0 | 511 |
512 // hashCode() generation : | |
513 // | |
514 // Possibilities: | |
515 // * MD5Digest of {obj,stwRandom} | |
516 // * CRC32 of {obj,stwRandom} or any linear-feedback shift register function. | |
517 // * A DES- or AES-style SBox[] mechanism | |
518 // * One of the Phi-based schemes, such as: | |
519 // 2654435761 = 2^32 * Phi (golden ratio) | |
520 // HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stwRandom ; | |
521 // * A variation of Marsaglia's shift-xor RNG scheme. | |
522 // * (obj ^ stwRandom) is appealing, but can result | |
523 // in undesirable regularity in the hashCode values of adjacent objects | |
524 // (objects allocated back-to-back, in particular). This could potentially | |
525 // result in hashtable collisions and reduced hashtable efficiency. | |
526 // There are simple ways to "diffuse" the middle address bits over the | |
527 // generated hashCode values: | |
528 // | |
529 | |
530 static inline intptr_t get_next_hash(Thread * Self, oop obj) { | |
531 intptr_t value = 0 ; | |
532 if (hashCode == 0) { | |
533 // This form uses an unguarded global Park-Miller RNG, | |
534 // so it's possible for two threads to race and generate the same RNG. | |
535 // On MP system we'll have lots of RW access to a global, so the | |
536 // mechanism induces lots of coherency traffic. | |
537 value = os::random() ; | |
538 } else | |
539 if (hashCode == 1) { | |
540 // This variation has the property of being stable (idempotent) | |
541 // between STW operations. This can be useful in some of the 1-0 | |
542 // synchronization schemes. | |
543 intptr_t addrBits = intptr_t(obj) >> 3 ; | |
544 value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ; | |
545 } else | |
546 if (hashCode == 2) { | |
547 value = 1 ; // for sensitivity testing | |
548 } else | |
549 if (hashCode == 3) { | |
550 value = ++GVars.hcSequence ; | |
551 } else | |
552 if (hashCode == 4) { | |
553 value = intptr_t(obj) ; | |
554 } else { | |
555 // Marsaglia's xor-shift scheme with thread-specific state | |
556 // This is probably the best overall implementation -- we'll | |
557 // likely make this the default in future releases. | |
558 unsigned t = Self->_hashStateX ; | |
559 t ^= (t << 11) ; | |
560 Self->_hashStateX = Self->_hashStateY ; | |
561 Self->_hashStateY = Self->_hashStateZ ; | |
562 Self->_hashStateZ = Self->_hashStateW ; | |
563 unsigned v = Self->_hashStateW ; | |
564 v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ; | |
565 Self->_hashStateW = v ; | |
566 value = v ; | |
567 } | |
568 | |
569 value &= markOopDesc::hash_mask; | |
570 if (value == 0) value = 0xBAD ; | |
571 assert (value != markOopDesc::no_hash, "invariant") ; | |
572 TEVENT (hashCode: GENERATE) ; | |
573 return value; | |
574 } | |
1878 | 575 // |
576 intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) { | |
577 if (UseBiasedLocking) { | |
578 // NOTE: many places throughout the JVM do not expect a safepoint | |
579 // to be taken here, in particular most operations on perm gen | |
580 // objects. However, we only ever bias Java instances and all of | |
581 // the call sites of identity_hash that might revoke biases have | |
582 // been checked to make sure they can handle a safepoint. The | |
583 // added check of the bias pattern is to avoid useless calls to | |
584 // thread-local storage. | |
585 if (obj->mark()->has_bias_pattern()) { | |
586 // Box and unbox the raw reference just in case we cause a STW safepoint. | |
587 Handle hobj (Self, obj) ; | |
588 // Relaxing assertion for bug 6320749. | |
589 assert (Universe::verify_in_progress() || | |
590 !SafepointSynchronize::is_at_safepoint(), | |
591 "biases should not be seen by VM thread here"); | |
592 BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current()); | |
593 obj = hobj() ; | |
594 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
595 } | |
596 } | |
0 | 597 |
1878 | 598 // hashCode() is a heap mutator ... |
599 // Relaxing assertion for bug 6320749. | |
600 assert (Universe::verify_in_progress() || | |
601 !SafepointSynchronize::is_at_safepoint(), "invariant") ; | |
602 assert (Universe::verify_in_progress() || | |
603 Self->is_Java_thread() , "invariant") ; | |
604 assert (Universe::verify_in_progress() || | |
605 ((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant") ; | |
606 | |
607 ObjectMonitor* monitor = NULL; | |
608 markOop temp, test; | |
609 intptr_t hash; | |
610 markOop mark = ReadStableMark (obj); | |
611 | |
612 // object should remain ineligible for biased locking | |
613 assert (!mark->has_bias_pattern(), "invariant") ; | |
614 | |
615 if (mark->is_neutral()) { | |
616 hash = mark->hash(); // this is a normal header | |
617 if (hash) { // if it has hash, just return it | |
618 return hash; | |
619 } | |
620 hash = get_next_hash(Self, obj); // allocate a new hash code | |
621 temp = mark->copy_set_hash(hash); // merge the hash code into header | |
622 // use (machine word version) atomic operation to install the hash | |
623 test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark); | |
624 if (test == mark) { | |
625 return hash; | |
626 } | |
627 // If atomic operation failed, we must inflate the header | |
628 // into heavy weight monitor. We could add more code here | |
629 // for fast path, but it does not worth the complexity. | |
630 } else if (mark->has_monitor()) { | |
631 monitor = mark->monitor(); | |
632 temp = monitor->header(); | |
633 assert (temp->is_neutral(), "invariant") ; | |
634 hash = temp->hash(); | |
635 if (hash) { | |
636 return hash; | |
637 } | |
638 // Skip to the following code to reduce code size | |
639 } else if (Self->is_lock_owned((address)mark->locker())) { | |
640 temp = mark->displaced_mark_helper(); // this is a lightweight monitor owned | |
641 assert (temp->is_neutral(), "invariant") ; | |
642 hash = temp->hash(); // by current thread, check if the displaced | |
643 if (hash) { // header contains hash code | |
644 return hash; | |
645 } | |
646 // WARNING: | |
647 // The displaced header is strictly immutable. | |
648 // It can NOT be changed in ANY cases. So we have | |
649 // to inflate the header into heavyweight monitor | |
650 // even the current thread owns the lock. The reason | |
651 // is the BasicLock (stack slot) will be asynchronously | |
652 // read by other threads during the inflate() function. | |
653 // Any change to stack may not propagate to other threads | |
654 // correctly. | |
655 } | |
656 | |
657 // Inflate the monitor to set hash code | |
658 monitor = ObjectSynchronizer::inflate(Self, obj); | |
659 // Load displaced header and check it has hash code | |
660 mark = monitor->header(); | |
661 assert (mark->is_neutral(), "invariant") ; | |
662 hash = mark->hash(); | |
663 if (hash == 0) { | |
664 hash = get_next_hash(Self, obj); | |
665 temp = mark->copy_set_hash(hash); // merge hash code into header | |
666 assert (temp->is_neutral(), "invariant") ; | |
667 test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark); | |
668 if (test != mark) { | |
669 // The only update to the header in the monitor (outside GC) | |
670 // is install the hash code. If someone add new usage of | |
671 // displaced header, please update this code | |
672 hash = test->hash(); | |
673 assert (test->is_neutral(), "invariant") ; | |
674 assert (hash != 0, "Trivial unexpected object/monitor header usage."); | |
675 } | |
676 } | |
677 // We finally get the hash | |
678 return hash; | |
0 | 679 } |
680 | |
1878 | 681 // Deprecated -- use FastHashCode() instead. |
0 | 682 |
1878 | 683 intptr_t ObjectSynchronizer::identity_hash_value_for(Handle obj) { |
684 return FastHashCode (Thread::current(), obj()) ; | |
0 | 685 } |
686 | |
687 | |
1878 | 688 bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread, |
689 Handle h_obj) { | |
690 if (UseBiasedLocking) { | |
691 BiasedLocking::revoke_and_rebias(h_obj, false, thread); | |
692 assert(!h_obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
693 } | |
694 | |
695 assert(thread == JavaThread::current(), "Can only be called on current thread"); | |
696 oop obj = h_obj(); | |
697 | |
698 markOop mark = ReadStableMark (obj) ; | |
0 | 699 |
1878 | 700 // Uncontended case, header points to stack |
701 if (mark->has_locker()) { | |
702 return thread->is_lock_owned((address)mark->locker()); | |
0 | 703 } |
1878 | 704 // Contended case, header points to ObjectMonitor (tagged pointer) |
705 if (mark->has_monitor()) { | |
706 ObjectMonitor* monitor = mark->monitor(); | |
707 return monitor->is_entered(thread) != 0 ; | |
0 | 708 } |
1878 | 709 // Unlocked case, header in place |
710 assert(mark->is_neutral(), "sanity check"); | |
711 return false; | |
0 | 712 } |
713 | |
1878 | 714 // Be aware of this method could revoke bias of the lock object. |
715 // This method querys the ownership of the lock handle specified by 'h_obj'. | |
716 // If the current thread owns the lock, it returns owner_self. If no | |
717 // thread owns the lock, it returns owner_none. Otherwise, it will return | |
718 // ower_other. | |
719 ObjectSynchronizer::LockOwnership ObjectSynchronizer::query_lock_ownership | |
720 (JavaThread *self, Handle h_obj) { | |
721 // The caller must beware this method can revoke bias, and | |
722 // revocation can result in a safepoint. | |
723 assert (!SafepointSynchronize::is_at_safepoint(), "invariant") ; | |
724 assert (self->thread_state() != _thread_blocked , "invariant") ; | |
0 | 725 |
1878 | 726 // Possible mark states: neutral, biased, stack-locked, inflated |
727 | |
728 if (UseBiasedLocking && h_obj()->mark()->has_bias_pattern()) { | |
729 // CASE: biased | |
730 BiasedLocking::revoke_and_rebias(h_obj, false, self); | |
731 assert(!h_obj->mark()->has_bias_pattern(), | |
732 "biases should be revoked by now"); | |
733 } | |
0 | 734 |
1878 | 735 assert(self == JavaThread::current(), "Can only be called on current thread"); |
736 oop obj = h_obj(); | |
737 markOop mark = ReadStableMark (obj) ; | |
738 | |
739 // CASE: stack-locked. Mark points to a BasicLock on the owner's stack. | |
740 if (mark->has_locker()) { | |
741 return self->is_lock_owned((address)mark->locker()) ? | |
742 owner_self : owner_other; | |
743 } | |
0 | 744 |
1878 | 745 // CASE: inflated. Mark (tagged pointer) points to an objectMonitor. |
746 // The Object:ObjectMonitor relationship is stable as long as we're | |
747 // not at a safepoint. | |
748 if (mark->has_monitor()) { | |
749 void * owner = mark->monitor()->_owner ; | |
750 if (owner == NULL) return owner_none ; | |
751 return (owner == self || | |
752 self->is_lock_owned((address)owner)) ? owner_self : owner_other; | |
753 } | |
754 | |
755 // CASE: neutral | |
756 assert(mark->is_neutral(), "sanity check"); | |
757 return owner_none ; // it's unlocked | |
758 } | |
0 | 759 |
1878 | 760 // FIXME: jvmti should call this |
761 JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) { | |
762 if (UseBiasedLocking) { | |
763 if (SafepointSynchronize::is_at_safepoint()) { | |
764 BiasedLocking::revoke_at_safepoint(h_obj); | |
765 } else { | |
766 BiasedLocking::revoke_and_rebias(h_obj, false, JavaThread::current()); | |
767 } | |
768 assert(!h_obj->mark()->has_bias_pattern(), "biases should be revoked by now"); | |
769 } | |
770 | |
771 oop obj = h_obj(); | |
772 address owner = NULL; | |
773 | |
774 markOop mark = ReadStableMark (obj) ; | |
775 | |
776 // Uncontended case, header points to stack | |
777 if (mark->has_locker()) { | |
778 owner = (address) mark->locker(); | |
779 } | |
780 | |
781 // Contended case, header points to ObjectMonitor (tagged pointer) | |
782 if (mark->has_monitor()) { | |
783 ObjectMonitor* monitor = mark->monitor(); | |
784 assert(monitor != NULL, "monitor should be non-null"); | |
785 owner = (address) monitor->owner(); | |
786 } | |
787 | |
788 if (owner != NULL) { | |
789 return Threads::owning_thread_from_monitor_owner(owner, doLock); | |
790 } | |
791 | |
792 // Unlocked case, header in place | |
793 // Cannot have assertion since this object may have been | |
794 // locked by another thread when reaching here. | |
795 // assert(mark->is_neutral(), "sanity check"); | |
796 | |
797 return NULL; | |
798 } | |
799 // Visitors ... | |
800 | |
801 void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) { | |
802 ObjectMonitor* block = gBlockList; | |
803 ObjectMonitor* mid; | |
804 while (block) { | |
805 assert(block->object() == CHAINMARKER, "must be a block header"); | |
806 for (int i = _BLOCKSIZE - 1; i > 0; i--) { | |
807 mid = block + i; | |
808 oop object = (oop) mid->object(); | |
809 if (object != NULL) { | |
810 closure->do_monitor(mid); | |
811 } | |
812 } | |
813 block = (ObjectMonitor*) block->FreeNext; | |
0 | 814 } |
815 } | |
816 | |
1878 | 817 // Get the next block in the block list. |
818 static inline ObjectMonitor* next(ObjectMonitor* block) { | |
819 assert(block->object() == CHAINMARKER, "must be a block header"); | |
820 block = block->FreeNext ; | |
821 assert(block == NULL || block->object() == CHAINMARKER, "must be a block header"); | |
822 return block; | |
0 | 823 } |
824 | |
825 | |
1878 | 826 void ObjectSynchronizer::oops_do(OopClosure* f) { |
827 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
828 for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) { | |
829 assert(block->object() == CHAINMARKER, "must be a block header"); | |
830 for (int i = 1; i < _BLOCKSIZE; i++) { | |
831 ObjectMonitor* mid = &block[i]; | |
832 if (mid->object() != NULL) { | |
833 f->do_oop((oop*)mid->object_addr()); | |
0 | 834 } |
835 } | |
836 } | |
837 } | |
838 | |
839 | |
1878 | 840 // ----------------------------------------------------------------------------- |
0 | 841 // ObjectMonitor Lifecycle |
842 // ----------------------- | |
843 // Inflation unlinks monitors from the global gFreeList and | |
844 // associates them with objects. Deflation -- which occurs at | |
845 // STW-time -- disassociates idle monitors from objects. Such | |
846 // scavenged monitors are returned to the gFreeList. | |
847 // | |
848 // The global list is protected by ListLock. All the critical sections | |
849 // are short and operate in constant-time. | |
850 // | |
851 // ObjectMonitors reside in type-stable memory (TSM) and are immortal. | |
852 // | |
853 // Lifecycle: | |
854 // -- unassigned and on the global free list | |
855 // -- unassigned and on a thread's private omFreeList | |
856 // -- assigned to an object. The object is inflated and the mark refers | |
857 // to the objectmonitor. | |
858 // | |
859 | |
860 | |
1587 | 861 // Constraining monitor pool growth via MonitorBound ... |
862 // | |
863 // The monitor pool is grow-only. We scavenge at STW safepoint-time, but the | |
864 // the rate of scavenging is driven primarily by GC. As such, we can find | |
865 // an inordinate number of monitors in circulation. | |
866 // To avoid that scenario we can artificially induce a STW safepoint | |
867 // if the pool appears to be growing past some reasonable bound. | |
868 // Generally we favor time in space-time tradeoffs, but as there's no | |
869 // natural back-pressure on the # of extant monitors we need to impose some | |
870 // type of limit. Beware that if MonitorBound is set to too low a value | |
871 // we could just loop. In addition, if MonitorBound is set to a low value | |
872 // we'll incur more safepoints, which are harmful to performance. | |
873 // See also: GuaranteedSafepointInterval | |
874 // | |
875 // The current implementation uses asynchronous VM operations. | |
876 // | |
877 | |
878 static void InduceScavenge (Thread * Self, const char * Whence) { | |
879 // Induce STW safepoint to trim monitors | |
880 // Ultimately, this results in a call to deflate_idle_monitors() in the near future. | |
881 // More precisely, trigger an asynchronous STW safepoint as the number | |
882 // of active monitors passes the specified threshold. | |
883 // TODO: assert thread state is reasonable | |
884 | |
885 if (ForceMonitorScavenge == 0 && Atomic::xchg (1, &ForceMonitorScavenge) == 0) { | |
1878 | 886 if (ObjectMonitor::Knob_Verbose) { |
1587 | 887 ::printf ("Monitor scavenge - Induced STW @%s (%d)\n", Whence, ForceMonitorScavenge) ; |
888 ::fflush(stdout) ; | |
889 } | |
890 // Induce a 'null' safepoint to scavenge monitors | |
891 // Must VM_Operation instance be heap allocated as the op will be enqueue and posted | |
892 // to the VMthread and have a lifespan longer than that of this activation record. | |
893 // The VMThread will delete the op when completed. | |
894 VMThread::execute (new VM_ForceAsyncSafepoint()) ; | |
895 | |
1878 | 896 if (ObjectMonitor::Knob_Verbose) { |
1587 | 897 ::printf ("Monitor scavenge - STW posted @%s (%d)\n", Whence, ForceMonitorScavenge) ; |
898 ::fflush(stdout) ; | |
899 } | |
900 } | |
901 } | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
902 /* Too slow for general assert or debug |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
903 void ObjectSynchronizer::verifyInUse (Thread *Self) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
904 ObjectMonitor* mid; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
905 int inusetally = 0; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
906 for (mid = Self->omInUseList; mid != NULL; mid = mid->FreeNext) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
907 inusetally ++; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
908 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
909 assert(inusetally == Self->omInUseCount, "inuse count off"); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
910 |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
911 int freetally = 0; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
912 for (mid = Self->omFreeList; mid != NULL; mid = mid->FreeNext) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
913 freetally ++; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
914 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
915 assert(freetally == Self->omFreeCount, "free count off"); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
916 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
917 */ |
0 | 918 ObjectMonitor * ATTR ObjectSynchronizer::omAlloc (Thread * Self) { |
919 // A large MAXPRIVATE value reduces both list lock contention | |
920 // and list coherency traffic, but also tends to increase the | |
921 // number of objectMonitors in circulation as well as the STW | |
922 // scavenge costs. As usual, we lean toward time in space-time | |
923 // tradeoffs. | |
924 const int MAXPRIVATE = 1024 ; | |
925 for (;;) { | |
926 ObjectMonitor * m ; | |
927 | |
928 // 1: try to allocate from the thread's local omFreeList. | |
929 // Threads will attempt to allocate first from their local list, then | |
930 // from the global list, and only after those attempts fail will the thread | |
931 // attempt to instantiate new monitors. Thread-local free lists take | |
932 // heat off the ListLock and improve allocation latency, as well as reducing | |
933 // coherency traffic on the shared global list. | |
934 m = Self->omFreeList ; | |
935 if (m != NULL) { | |
936 Self->omFreeList = m->FreeNext ; | |
937 Self->omFreeCount -- ; | |
938 // CONSIDER: set m->FreeNext = BAD -- diagnostic hygiene | |
939 guarantee (m->object() == NULL, "invariant") ; | |
1587 | 940 if (MonitorInUseLists) { |
941 m->FreeNext = Self->omInUseList; | |
942 Self->omInUseList = m; | |
943 Self->omInUseCount ++; | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
944 // verifyInUse(Self); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
945 } else { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
946 m->FreeNext = NULL; |
1587 | 947 } |
0 | 948 return m ; |
949 } | |
950 | |
951 // 2: try to allocate from the global gFreeList | |
952 // CONSIDER: use muxTry() instead of muxAcquire(). | |
953 // If the muxTry() fails then drop immediately into case 3. | |
954 // If we're using thread-local free lists then try | |
955 // to reprovision the caller's free list. | |
956 if (gFreeList != NULL) { | |
957 // Reprovision the thread's omFreeList. | |
958 // Use bulk transfers to reduce the allocation rate and heat | |
959 // on various locks. | |
960 Thread::muxAcquire (&ListLock, "omAlloc") ; | |
961 for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL; ) { | |
1587 | 962 MonitorFreeCount --; |
0 | 963 ObjectMonitor * take = gFreeList ; |
964 gFreeList = take->FreeNext ; | |
965 guarantee (take->object() == NULL, "invariant") ; | |
966 guarantee (!take->is_busy(), "invariant") ; | |
967 take->Recycle() ; | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
968 omRelease (Self, take, false) ; |
0 | 969 } |
970 Thread::muxRelease (&ListLock) ; | |
971 Self->omFreeProvision += 1 + (Self->omFreeProvision/2) ; | |
972 if (Self->omFreeProvision > MAXPRIVATE ) Self->omFreeProvision = MAXPRIVATE ; | |
973 TEVENT (omFirst - reprovision) ; | |
1587 | 974 |
975 const int mx = MonitorBound ; | |
976 if (mx > 0 && (MonitorPopulation-MonitorFreeCount) > mx) { | |
977 // We can't safely induce a STW safepoint from omAlloc() as our thread | |
978 // state may not be appropriate for such activities and callers may hold | |
979 // naked oops, so instead we defer the action. | |
980 InduceScavenge (Self, "omAlloc") ; | |
981 } | |
982 continue; | |
0 | 983 } |
984 | |
985 // 3: allocate a block of new ObjectMonitors | |
986 // Both the local and global free lists are empty -- resort to malloc(). | |
987 // In the current implementation objectMonitors are TSM - immortal. | |
988 assert (_BLOCKSIZE > 1, "invariant") ; | |
989 ObjectMonitor * temp = new ObjectMonitor[_BLOCKSIZE]; | |
990 | |
991 // NOTE: (almost) no way to recover if allocation failed. | |
992 // We might be able to induce a STW safepoint and scavenge enough | |
993 // objectMonitors to permit progress. | |
994 if (temp == NULL) { | |
995 vm_exit_out_of_memory (sizeof (ObjectMonitor[_BLOCKSIZE]), "Allocate ObjectMonitors") ; | |
996 } | |
997 | |
998 // Format the block. | |
999 // initialize the linked list, each monitor points to its next | |
1000 // forming the single linked free list, the very first monitor | |
1001 // will points to next block, which forms the block list. | |
1002 // The trick of using the 1st element in the block as gBlockList | |
1003 // linkage should be reconsidered. A better implementation would | |
1004 // look like: class Block { Block * next; int N; ObjectMonitor Body [N] ; } | |
1005 | |
1006 for (int i = 1; i < _BLOCKSIZE ; i++) { | |
1007 temp[i].FreeNext = &temp[i+1]; | |
1008 } | |
1009 | |
1010 // terminate the last monitor as the end of list | |
1011 temp[_BLOCKSIZE - 1].FreeNext = NULL ; | |
1012 | |
1013 // Element [0] is reserved for global list linkage | |
1014 temp[0].set_object(CHAINMARKER); | |
1015 | |
1016 // Consider carving out this thread's current request from the | |
1017 // block in hand. This avoids some lock traffic and redundant | |
1018 // list activity. | |
1019 | |
1020 // Acquire the ListLock to manipulate BlockList and FreeList. | |
1021 // An Oyama-Taura-Yonezawa scheme might be more efficient. | |
1022 Thread::muxAcquire (&ListLock, "omAlloc [2]") ; | |
1587 | 1023 MonitorPopulation += _BLOCKSIZE-1; |
1024 MonitorFreeCount += _BLOCKSIZE-1; | |
0 | 1025 |
1026 // Add the new block to the list of extant blocks (gBlockList). | |
1027 // The very first objectMonitor in a block is reserved and dedicated. | |
1028 // It serves as blocklist "next" linkage. | |
1029 temp[0].FreeNext = gBlockList; | |
1030 gBlockList = temp; | |
1031 | |
1032 // Add the new string of objectMonitors to the global free list | |
1033 temp[_BLOCKSIZE - 1].FreeNext = gFreeList ; | |
1034 gFreeList = temp + 1; | |
1035 Thread::muxRelease (&ListLock) ; | |
1036 TEVENT (Allocate block of monitors) ; | |
1037 } | |
1038 } | |
1039 | |
1040 // Place "m" on the caller's private per-thread omFreeList. | |
1041 // In practice there's no need to clamp or limit the number of | |
1042 // monitors on a thread's omFreeList as the only time we'll call | |
1043 // omRelease is to return a monitor to the free list after a CAS | |
1044 // attempt failed. This doesn't allow unbounded #s of monitors to | |
1045 // accumulate on a thread's free list. | |
1046 // | |
1047 | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1048 void ObjectSynchronizer::omRelease (Thread * Self, ObjectMonitor * m, bool fromPerThreadAlloc) { |
0 | 1049 guarantee (m->object() == NULL, "invariant") ; |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1050 |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1051 // Remove from omInUseList |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1052 if (MonitorInUseLists && fromPerThreadAlloc) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1053 ObjectMonitor* curmidinuse = NULL; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1054 for (ObjectMonitor* mid = Self->omInUseList; mid != NULL; ) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1055 if (m == mid) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1056 // extract from per-thread in-use-list |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1057 if (mid == Self->omInUseList) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1058 Self->omInUseList = mid->FreeNext; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1059 } else if (curmidinuse != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1060 curmidinuse->FreeNext = mid->FreeNext; // maintain the current thread inuselist |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1061 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1062 Self->omInUseCount --; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1063 // verifyInUse(Self); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1064 break; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1065 } else { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1066 curmidinuse = mid; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1067 mid = mid->FreeNext; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1068 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1069 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1070 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1071 |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1072 // FreeNext is used for both onInUseList and omFreeList, so clear old before setting new |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1073 m->FreeNext = Self->omFreeList ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1074 Self->omFreeList = m ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1075 Self->omFreeCount ++ ; |
0 | 1076 } |
1077 | |
1078 // Return the monitors of a moribund thread's local free list to | |
1079 // the global free list. Typically a thread calls omFlush() when | |
1080 // it's dying. We could also consider having the VM thread steal | |
1081 // monitors from threads that have not run java code over a few | |
1082 // consecutive STW safepoints. Relatedly, we might decay | |
1083 // omFreeProvision at STW safepoints. | |
1084 // | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1085 // Also return the monitors of a moribund thread"s omInUseList to |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1086 // a global gOmInUseList under the global list lock so these |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1087 // will continue to be scanned. |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1088 // |
0 | 1089 // We currently call omFlush() from the Thread:: dtor _after the thread |
1090 // has been excised from the thread list and is no longer a mutator. | |
1091 // That means that omFlush() can run concurrently with a safepoint and | |
1092 // the scavenge operator. Calling omFlush() from JavaThread::exit() might | |
1093 // be a better choice as we could safely reason that that the JVM is | |
1094 // not at a safepoint at the time of the call, and thus there could | |
1095 // be not inopportune interleavings between omFlush() and the scavenge | |
1096 // operator. | |
1097 | |
1098 void ObjectSynchronizer::omFlush (Thread * Self) { | |
1099 ObjectMonitor * List = Self->omFreeList ; // Null-terminated SLL | |
1100 Self->omFreeList = NULL ; | |
1101 ObjectMonitor * Tail = NULL ; | |
1587 | 1102 int Tally = 0; |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1103 if (List != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1104 ObjectMonitor * s ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1105 for (s = List ; s != NULL ; s = s->FreeNext) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1106 Tally ++ ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1107 Tail = s ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1108 guarantee (s->object() == NULL, "invariant") ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1109 guarantee (!s->is_busy(), "invariant") ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1110 s->set_owner (NULL) ; // redundant but good hygiene |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1111 TEVENT (omFlush - Move one) ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1112 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1113 guarantee (Tail != NULL && List != NULL, "invariant") ; |
0 | 1114 } |
1115 | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1116 ObjectMonitor * InUseList = Self->omInUseList; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1117 ObjectMonitor * InUseTail = NULL ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1118 int InUseTally = 0; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1119 if (InUseList != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1120 Self->omInUseList = NULL; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1121 ObjectMonitor *curom; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1122 for (curom = InUseList; curom != NULL; curom = curom->FreeNext) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1123 InUseTail = curom; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1124 InUseTally++; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1125 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1126 // TODO debug |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1127 assert(Self->omInUseCount == InUseTally, "inuse count off"); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1128 Self->omInUseCount = 0; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1129 guarantee (InUseTail != NULL && InUseList != NULL, "invariant"); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1130 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1131 |
0 | 1132 Thread::muxAcquire (&ListLock, "omFlush") ; |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1133 if (Tail != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1134 Tail->FreeNext = gFreeList ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1135 gFreeList = List ; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1136 MonitorFreeCount += Tally; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1137 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1138 |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1139 if (InUseTail != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1140 InUseTail->FreeNext = gOmInUseList; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1141 gOmInUseList = InUseList; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1142 gOmInUseCount += InUseTally; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1143 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1144 |
0 | 1145 Thread::muxRelease (&ListLock) ; |
1146 TEVENT (omFlush) ; | |
1147 } | |
1148 | |
1149 // Fast path code shared by multiple functions | |
1150 ObjectMonitor* ObjectSynchronizer::inflate_helper(oop obj) { | |
1151 markOop mark = obj->mark(); | |
1152 if (mark->has_monitor()) { | |
1153 assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid"); | |
1154 assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header"); | |
1155 return mark->monitor(); | |
1156 } | |
1157 return ObjectSynchronizer::inflate(Thread::current(), obj); | |
1158 } | |
1159 | |
1878 | 1160 |
0 | 1161 // Note that we could encounter some performance loss through false-sharing as |
1162 // multiple locks occupy the same $ line. Padding might be appropriate. | |
1163 | |
1164 | |
1165 ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) { | |
1166 // Inflate mutates the heap ... | |
1167 // Relaxing assertion for bug 6320749. | |
1168 assert (Universe::verify_in_progress() || | |
1169 !SafepointSynchronize::is_at_safepoint(), "invariant") ; | |
1170 | |
1171 for (;;) { | |
1172 const markOop mark = object->mark() ; | |
1173 assert (!mark->has_bias_pattern(), "invariant") ; | |
1174 | |
1175 // The mark can be in one of the following states: | |
1176 // * Inflated - just return | |
1177 // * Stack-locked - coerce it to inflated | |
1178 // * INFLATING - busy wait for conversion to complete | |
1179 // * Neutral - aggressively inflate the object. | |
1180 // * BIASED - Illegal. We should never see this | |
1181 | |
1182 // CASE: inflated | |
1183 if (mark->has_monitor()) { | |
1184 ObjectMonitor * inf = mark->monitor() ; | |
1185 assert (inf->header()->is_neutral(), "invariant"); | |
1186 assert (inf->object() == object, "invariant") ; | |
1187 assert (ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid"); | |
1188 return inf ; | |
1189 } | |
1190 | |
1191 // CASE: inflation in progress - inflating over a stack-lock. | |
1192 // Some other thread is converting from stack-locked to inflated. | |
1193 // Only that thread can complete inflation -- other threads must wait. | |
1194 // The INFLATING value is transient. | |
1195 // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish. | |
1196 // We could always eliminate polling by parking the thread on some auxiliary list. | |
1197 if (mark == markOopDesc::INFLATING()) { | |
1198 TEVENT (Inflate: spin while INFLATING) ; | |
1199 ReadStableMark(object) ; | |
1200 continue ; | |
1201 } | |
1202 | |
1203 // CASE: stack-locked | |
1204 // Could be stack-locked either by this thread or by some other thread. | |
1205 // | |
1206 // Note that we allocate the objectmonitor speculatively, _before_ attempting | |
1207 // to install INFLATING into the mark word. We originally installed INFLATING, | |
1208 // allocated the objectmonitor, and then finally STed the address of the | |
1209 // objectmonitor into the mark. This was correct, but artificially lengthened | |
1210 // the interval in which INFLATED appeared in the mark, thus increasing | |
1211 // the odds of inflation contention. | |
1212 // | |
1213 // We now use per-thread private objectmonitor free lists. | |
1214 // These list are reprovisioned from the global free list outside the | |
1215 // critical INFLATING...ST interval. A thread can transfer | |
1216 // multiple objectmonitors en-mass from the global free list to its local free list. | |
1217 // This reduces coherency traffic and lock contention on the global free list. | |
1218 // Using such local free lists, it doesn't matter if the omAlloc() call appears | |
1219 // before or after the CAS(INFLATING) operation. | |
1220 // See the comments in omAlloc(). | |
1221 | |
1222 if (mark->has_locker()) { | |
1223 ObjectMonitor * m = omAlloc (Self) ; | |
1224 // Optimistically prepare the objectmonitor - anticipate successful CAS | |
1225 // We do this before the CAS in order to minimize the length of time | |
1226 // in which INFLATING appears in the mark. | |
1227 m->Recycle(); | |
1228 m->_Responsible = NULL ; | |
1229 m->OwnerIsThread = 0 ; | |
1230 m->_recursions = 0 ; | |
1878 | 1231 m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // Consider: maintain by type/class |
0 | 1232 |
1233 markOop cmp = (markOop) Atomic::cmpxchg_ptr (markOopDesc::INFLATING(), object->mark_addr(), mark) ; | |
1234 if (cmp != mark) { | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1235 omRelease (Self, m, true) ; |
0 | 1236 continue ; // Interference -- just retry |
1237 } | |
1238 | |
1239 // We've successfully installed INFLATING (0) into the mark-word. | |
1240 // This is the only case where 0 will appear in a mark-work. | |
1241 // Only the singular thread that successfully swings the mark-word | |
1242 // to 0 can perform (or more precisely, complete) inflation. | |
1243 // | |
1244 // Why do we CAS a 0 into the mark-word instead of just CASing the | |
1245 // mark-word from the stack-locked value directly to the new inflated state? | |
1246 // Consider what happens when a thread unlocks a stack-locked object. | |
1247 // It attempts to use CAS to swing the displaced header value from the | |
1248 // on-stack basiclock back into the object header. Recall also that the | |
1249 // header value (hashcode, etc) can reside in (a) the object header, or | |
1250 // (b) a displaced header associated with the stack-lock, or (c) a displaced | |
1251 // header in an objectMonitor. The inflate() routine must copy the header | |
1252 // value from the basiclock on the owner's stack to the objectMonitor, all | |
1253 // the while preserving the hashCode stability invariants. If the owner | |
1254 // decides to release the lock while the value is 0, the unlock will fail | |
1255 // and control will eventually pass from slow_exit() to inflate. The owner | |
1256 // will then spin, waiting for the 0 value to disappear. Put another way, | |
1257 // the 0 causes the owner to stall if the owner happens to try to | |
1258 // drop the lock (restoring the header from the basiclock to the object) | |
1259 // while inflation is in-progress. This protocol avoids races that might | |
1260 // would otherwise permit hashCode values to change or "flicker" for an object. | |
1261 // Critically, while object->mark is 0 mark->displaced_mark_helper() is stable. | |
1262 // 0 serves as a "BUSY" inflate-in-progress indicator. | |
1263 | |
1264 | |
1265 // fetch the displaced mark from the owner's stack. | |
1266 // The owner can't die or unwind past the lock while our INFLATING | |
1267 // object is in the mark. Furthermore the owner can't complete | |
1268 // an unlock on the object, either. | |
1269 markOop dmw = mark->displaced_mark_helper() ; | |
1270 assert (dmw->is_neutral(), "invariant") ; | |
1271 | |
1272 // Setup monitor fields to proper values -- prepare the monitor | |
1273 m->set_header(dmw) ; | |
1274 | |
1275 // Optimization: if the mark->locker stack address is associated | |
1276 // with this thread we could simply set m->_owner = Self and | |
702
b9fba36710f2
6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents:
579
diff
changeset
|
1277 // m->OwnerIsThread = 1. Note that a thread can inflate an object |
0 | 1278 // that it has stack-locked -- as might happen in wait() -- directly |
1279 // with CAS. That is, we can avoid the xchg-NULL .... ST idiom. | |
702
b9fba36710f2
6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents:
579
diff
changeset
|
1280 m->set_owner(mark->locker()); |
0 | 1281 m->set_object(object); |
1282 // TODO-FIXME: assert BasicLock->dhw != 0. | |
1283 | |
1284 // Must preserve store ordering. The monitor state must | |
1285 // be stable at the time of publishing the monitor address. | |
1286 guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ; | |
1287 object->release_set_mark(markOopDesc::encode(m)); | |
1288 | |
1289 // Hopefully the performance counters are allocated on distinct cache lines | |
1290 // to avoid false sharing on MP systems ... | |
1878 | 1291 if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ; |
0 | 1292 TEVENT(Inflate: overwrite stacklock) ; |
1293 if (TraceMonitorInflation) { | |
1294 if (object->is_instance()) { | |
1295 ResourceMark rm; | |
1296 tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", | |
1297 (intptr_t) object, (intptr_t) object->mark(), | |
1298 Klass::cast(object->klass())->external_name()); | |
1299 } | |
1300 } | |
1301 return m ; | |
1302 } | |
1303 | |
1304 // CASE: neutral | |
1305 // TODO-FIXME: for entry we currently inflate and then try to CAS _owner. | |
1306 // If we know we're inflating for entry it's better to inflate by swinging a | |
1307 // pre-locked objectMonitor pointer into the object header. A successful | |
1308 // CAS inflates the object *and* confers ownership to the inflating thread. | |
1309 // In the current implementation we use a 2-step mechanism where we CAS() | |
1310 // to inflate and then CAS() again to try to swing _owner from NULL to Self. | |
1311 // An inflateTry() method that we could call from fast_enter() and slow_enter() | |
1312 // would be useful. | |
1313 | |
1314 assert (mark->is_neutral(), "invariant"); | |
1315 ObjectMonitor * m = omAlloc (Self) ; | |
1316 // prepare m for installation - set monitor to initial state | |
1317 m->Recycle(); | |
1318 m->set_header(mark); | |
1319 m->set_owner(NULL); | |
1320 m->set_object(object); | |
1321 m->OwnerIsThread = 1 ; | |
1322 m->_recursions = 0 ; | |
1323 m->_Responsible = NULL ; | |
1878 | 1324 m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // consider: keep metastats by type/class |
0 | 1325 |
1326 if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) { | |
1327 m->set_object (NULL) ; | |
1328 m->set_owner (NULL) ; | |
1329 m->OwnerIsThread = 0 ; | |
1330 m->Recycle() ; | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1331 omRelease (Self, m, true) ; |
0 | 1332 m = NULL ; |
1333 continue ; | |
1334 // interference - the markword changed - just retry. | |
1335 // The state-transitions are one-way, so there's no chance of | |
1336 // live-lock -- "Inflated" is an absorbing state. | |
1337 } | |
1338 | |
1339 // Hopefully the performance counters are allocated on distinct | |
1340 // cache lines to avoid false sharing on MP systems ... | |
1878 | 1341 if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ; |
0 | 1342 TEVENT(Inflate: overwrite neutral) ; |
1343 if (TraceMonitorInflation) { | |
1344 if (object->is_instance()) { | |
1345 ResourceMark rm; | |
1346 tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", | |
1347 (intptr_t) object, (intptr_t) object->mark(), | |
1348 Klass::cast(object->klass())->external_name()); | |
1349 } | |
1350 } | |
1351 return m ; | |
1352 } | |
1353 } | |
1354 | |
1878 | 1355 // Note that we could encounter some performance loss through false-sharing as |
1356 // multiple locks occupy the same $ line. Padding might be appropriate. | |
0 | 1357 |
1358 | |
1359 // Deflate_idle_monitors() is called at all safepoints, immediately | |
1360 // after all mutators are stopped, but before any objects have moved. | |
1361 // It traverses the list of known monitors, deflating where possible. | |
1362 // The scavenged monitor are returned to the monitor free list. | |
1363 // | |
1364 // Beware that we scavenge at *every* stop-the-world point. | |
1365 // Having a large number of monitors in-circulation negatively | |
1366 // impacts the performance of some applications (e.g., PointBase). | |
1367 // Broadly, we want to minimize the # of monitors in circulation. | |
1587 | 1368 // |
1369 // We have added a flag, MonitorInUseLists, which creates a list | |
1370 // of active monitors for each thread. deflate_idle_monitors() | |
1371 // only scans the per-thread inuse lists. omAlloc() puts all | |
1372 // assigned monitors on the per-thread list. deflate_idle_monitors() | |
1373 // returns the non-busy monitors to the global free list. | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1374 // When a thread dies, omFlush() adds the list of active monitors for |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1375 // that thread to a global gOmInUseList acquiring the |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1376 // global list lock. deflate_idle_monitors() acquires the global |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1377 // list lock to scan for non-busy monitors to the global free list. |
1587 | 1378 // An alternative could have used a single global inuse list. The |
1379 // downside would have been the additional cost of acquiring the global list lock | |
1380 // for every omAlloc(). | |
0 | 1381 // |
1382 // Perversely, the heap size -- and thus the STW safepoint rate -- | |
1383 // typically drives the scavenge rate. Large heaps can mean infrequent GC, | |
1384 // which in turn can mean large(r) numbers of objectmonitors in circulation. | |
1385 // This is an unfortunate aspect of this design. | |
1386 // | |
1387 | |
1878 | 1388 enum ManifestConstants { |
1389 ClearResponsibleAtSTW = 0, | |
1390 MaximumRecheckInterval = 1000 | |
1391 } ; | |
1587 | 1392 |
1393 // Deflate a single monitor if not in use | |
1394 // Return true if deflated, false if in use | |
1395 bool ObjectSynchronizer::deflate_monitor(ObjectMonitor* mid, oop obj, | |
1396 ObjectMonitor** FreeHeadp, ObjectMonitor** FreeTailp) { | |
1397 bool deflated; | |
1398 // Normal case ... The monitor is associated with obj. | |
1399 guarantee (obj->mark() == markOopDesc::encode(mid), "invariant") ; | |
1400 guarantee (mid == obj->mark()->monitor(), "invariant"); | |
1401 guarantee (mid->header()->is_neutral(), "invariant"); | |
1402 | |
1403 if (mid->is_busy()) { | |
1404 if (ClearResponsibleAtSTW) mid->_Responsible = NULL ; | |
1405 deflated = false; | |
1406 } else { | |
1407 // Deflate the monitor if it is no longer being used | |
1408 // It's idle - scavenge and return to the global free list | |
1409 // plain old deflation ... | |
1410 TEVENT (deflate_idle_monitors - scavenge1) ; | |
1411 if (TraceMonitorInflation) { | |
1412 if (obj->is_instance()) { | |
1413 ResourceMark rm; | |
1414 tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", | |
1415 (intptr_t) obj, (intptr_t) obj->mark(), Klass::cast(obj->klass())->external_name()); | |
1416 } | |
1417 } | |
1418 | |
1419 // Restore the header back to obj | |
1420 obj->release_set_mark(mid->header()); | |
1421 mid->clear(); | |
1422 | |
1423 assert (mid->object() == NULL, "invariant") ; | |
1424 | |
1425 // Move the object to the working free list defined by FreeHead,FreeTail. | |
1426 if (*FreeHeadp == NULL) *FreeHeadp = mid; | |
1427 if (*FreeTailp != NULL) { | |
1428 ObjectMonitor * prevtail = *FreeTailp; | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1429 assert(prevtail->FreeNext == NULL, "cleaned up deflated?"); // TODO KK |
1587 | 1430 prevtail->FreeNext = mid; |
1431 } | |
1432 *FreeTailp = mid; | |
1433 deflated = true; | |
1434 } | |
1435 return deflated; | |
1436 } | |
1437 | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1438 // Caller acquires ListLock |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1439 int ObjectSynchronizer::walk_monitor_list(ObjectMonitor** listheadp, |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1440 ObjectMonitor** FreeHeadp, ObjectMonitor** FreeTailp) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1441 ObjectMonitor* mid; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1442 ObjectMonitor* next; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1443 ObjectMonitor* curmidinuse = NULL; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1444 int deflatedcount = 0; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1445 |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1446 for (mid = *listheadp; mid != NULL; ) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1447 oop obj = (oop) mid->object(); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1448 bool deflated = false; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1449 if (obj != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1450 deflated = deflate_monitor(mid, obj, FreeHeadp, FreeTailp); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1451 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1452 if (deflated) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1453 // extract from per-thread in-use-list |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1454 if (mid == *listheadp) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1455 *listheadp = mid->FreeNext; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1456 } else if (curmidinuse != NULL) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1457 curmidinuse->FreeNext = mid->FreeNext; // maintain the current thread inuselist |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1458 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1459 next = mid->FreeNext; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1460 mid->FreeNext = NULL; // This mid is current tail in the FreeHead list |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1461 mid = next; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1462 deflatedcount++; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1463 } else { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1464 curmidinuse = mid; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1465 mid = mid->FreeNext; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1466 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1467 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1468 return deflatedcount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1469 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1470 |
0 | 1471 void ObjectSynchronizer::deflate_idle_monitors() { |
1472 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
1473 int nInuse = 0 ; // currently associated with objects | |
1474 int nInCirculation = 0 ; // extant | |
1475 int nScavenged = 0 ; // reclaimed | |
1587 | 1476 bool deflated = false; |
0 | 1477 |
1478 ObjectMonitor * FreeHead = NULL ; // Local SLL of scavenged monitors | |
1479 ObjectMonitor * FreeTail = NULL ; | |
1480 | |
1587 | 1481 TEVENT (deflate_idle_monitors) ; |
1482 // Prevent omFlush from changing mids in Thread dtor's during deflation | |
1483 // And in case the vm thread is acquiring a lock during a safepoint | |
1484 // See e.g. 6320749 | |
1485 Thread::muxAcquire (&ListLock, "scavenge - return") ; | |
1486 | |
1487 if (MonitorInUseLists) { | |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1488 int inUse = 0; |
1587 | 1489 for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) { |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1490 nInCirculation+= cur->omInUseCount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1491 int deflatedcount = walk_monitor_list(cur->omInUseList_addr(), &FreeHead, &FreeTail); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1492 cur->omInUseCount-= deflatedcount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1493 // verifyInUse(cur); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1494 nScavenged += deflatedcount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1495 nInuse += cur->omInUseCount; |
1587 | 1496 } |
1640
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1497 |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1498 // For moribund threads, scan gOmInUseList |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1499 if (gOmInUseList) { |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1500 nInCirculation += gOmInUseCount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1501 int deflatedcount = walk_monitor_list((ObjectMonitor **)&gOmInUseList, &FreeHead, &FreeTail); |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1502 gOmInUseCount-= deflatedcount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1503 nScavenged += deflatedcount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1504 nInuse += gOmInUseCount; |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1505 } |
bfc89697cccb
6964164: MonitorInUseLists leak of contended objects
acorn
parents:
1589
diff
changeset
|
1506 |
1587 | 1507 } else for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) { |
0 | 1508 // Iterate over all extant monitors - Scavenge all idle monitors. |
1509 assert(block->object() == CHAINMARKER, "must be a block header"); | |
1510 nInCirculation += _BLOCKSIZE ; | |
1511 for (int i = 1 ; i < _BLOCKSIZE; i++) { | |
1512 ObjectMonitor* mid = &block[i]; | |
1513 oop obj = (oop) mid->object(); | |
1514 | |
1515 if (obj == NULL) { | |
1516 // The monitor is not associated with an object. | |
1517 // The monitor should either be a thread-specific private | |
1518 // free list or the global free list. | |
1519 // obj == NULL IMPLIES mid->is_busy() == 0 | |
1520 guarantee (!mid->is_busy(), "invariant") ; | |
1521 continue ; | |
1522 } | |
1587 | 1523 deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail); |
1524 | |
1525 if (deflated) { | |
1526 mid->FreeNext = NULL ; | |
1527 nScavenged ++ ; | |
0 | 1528 } else { |
1587 | 1529 nInuse ++; |
0 | 1530 } |
1531 } | |
1532 } | |
1533 | |
1587 | 1534 MonitorFreeCount += nScavenged; |
1535 | |
1536 // Consider: audit gFreeList to ensure that MonitorFreeCount and list agree. | |
1537 | |
1878 | 1538 if (ObjectMonitor::Knob_Verbose) { |
1587 | 1539 ::printf ("Deflate: InCirc=%d InUse=%d Scavenged=%d ForceMonitorScavenge=%d : pop=%d free=%d\n", |
1540 nInCirculation, nInuse, nScavenged, ForceMonitorScavenge, | |
1541 MonitorPopulation, MonitorFreeCount) ; | |
1542 ::fflush(stdout) ; | |
1543 } | |
1544 | |
1545 ForceMonitorScavenge = 0; // Reset | |
1546 | |
0 | 1547 // Move the scavenged monitors back to the global free list. |
1548 if (FreeHead != NULL) { | |
1549 guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ; | |
1550 assert (FreeTail->FreeNext == NULL, "invariant") ; | |
1551 // constant-time list splice - prepend scavenged segment to gFreeList | |
1552 FreeTail->FreeNext = gFreeList ; | |
1553 gFreeList = FreeHead ; | |
1554 } | |
1587 | 1555 Thread::muxRelease (&ListLock) ; |
0 | 1556 |
1878 | 1557 if (ObjectMonitor::_sync_Deflations != NULL) ObjectMonitor::_sync_Deflations->inc(nScavenged) ; |
1558 if (ObjectMonitor::_sync_MonExtant != NULL) ObjectMonitor::_sync_MonExtant ->set_value(nInCirculation); | |
0 | 1559 |
1560 // TODO: Add objectMonitor leak detection. | |
1561 // Audit/inventory the objectMonitors -- make sure they're all accounted for. | |
1562 GVars.stwRandom = os::random() ; | |
1563 GVars.stwCycle ++ ; | |
1564 } | |
1565 | |
1878 | 1566 // Monitor cleanup on JavaThread::exit |
0 | 1567 |
1878 | 1568 // Iterate through monitor cache and attempt to release thread's monitors |
1569 // Gives up on a particular monitor if an exception occurs, but continues | |
1570 // the overall iteration, swallowing the exception. | |
1571 class ReleaseJavaMonitorsClosure: public MonitorClosure { | |
1572 private: | |
1573 TRAPS; | |
0 | 1574 |
1878 | 1575 public: |
1576 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {} | |
1577 void do_monitor(ObjectMonitor* mid) { | |
1578 if (mid->owner() == THREAD) { | |
1579 (void)mid->complete_exit(CHECK); | |
0 | 1580 } |
1581 } | |
1878 | 1582 }; |
0 | 1583 |
1878 | 1584 // Release all inflated monitors owned by THREAD. Lightweight monitors are |
1585 // ignored. This is meant to be called during JNI thread detach which assumes | |
1586 // all remaining monitors are heavyweight. All exceptions are swallowed. | |
1587 // Scanning the extant monitor list can be time consuming. | |
1588 // A simple optimization is to add a per-thread flag that indicates a thread | |
1589 // called jni_monitorenter() during its lifetime. | |
0 | 1590 // |
1878 | 1591 // Instead of No_Savepoint_Verifier it might be cheaper to |
1592 // use an idiom of the form: | |
1593 // auto int tmp = SafepointSynchronize::_safepoint_counter ; | |
1594 // <code that must not run at safepoint> | |
1595 // guarantee (((tmp ^ _safepoint_counter) | (tmp & 1)) == 0) ; | |
1596 // Since the tests are extremely cheap we could leave them enabled | |
1597 // for normal product builds. | |
0 | 1598 |
1878 | 1599 void ObjectSynchronizer::release_monitors_owned_by_thread(TRAPS) { |
1600 assert(THREAD == JavaThread::current(), "must be current Java thread"); | |
1601 No_Safepoint_Verifier nsv ; | |
1602 ReleaseJavaMonitorsClosure rjmc(THREAD); | |
1603 Thread::muxAcquire(&ListLock, "release_monitors_owned_by_thread"); | |
1604 ObjectSynchronizer::monitors_iterate(&rjmc); | |
1605 Thread::muxRelease(&ListLock); | |
1606 THREAD->clear_pending_exception(); | |
0 | 1607 } |
1608 | |
1609 //------------------------------------------------------------------------------ | |
1610 // Non-product code | |
1611 | |
1612 #ifndef PRODUCT | |
1613 | |
1614 void ObjectSynchronizer::trace_locking(Handle locking_obj, bool is_compiled, | |
1615 bool is_method, bool is_locking) { | |
1616 // Don't know what to do here | |
1617 } | |
1618 | |
1619 // Verify all monitors in the monitor cache, the verification is weak. | |
1620 void ObjectSynchronizer::verify() { | |
1621 ObjectMonitor* block = gBlockList; | |
1622 ObjectMonitor* mid; | |
1623 while (block) { | |
1624 assert(block->object() == CHAINMARKER, "must be a block header"); | |
1625 for (int i = 1; i < _BLOCKSIZE; i++) { | |
1626 mid = block + i; | |
1627 oop object = (oop) mid->object(); | |
1628 if (object != NULL) { | |
1629 mid->verify(); | |
1630 } | |
1631 } | |
1632 block = (ObjectMonitor*) block->FreeNext; | |
1633 } | |
1634 } | |
1635 | |
1636 // Check if monitor belongs to the monitor cache | |
1637 // The list is grow-only so it's *relatively* safe to traverse | |
1638 // the list of extant blocks without taking a lock. | |
1639 | |
1640 int ObjectSynchronizer::verify_objmon_isinpool(ObjectMonitor *monitor) { | |
1641 ObjectMonitor* block = gBlockList; | |
1642 | |
1643 while (block) { | |
1644 assert(block->object() == CHAINMARKER, "must be a block header"); | |
1645 if (monitor > &block[0] && monitor < &block[_BLOCKSIZE]) { | |
1646 address mon = (address) monitor; | |
1647 address blk = (address) block; | |
1648 size_t diff = mon - blk; | |
1649 assert((diff % sizeof(ObjectMonitor)) == 0, "check"); | |
1650 return 1; | |
1651 } | |
1652 block = (ObjectMonitor*) block->FreeNext; | |
1653 } | |
1654 return 0; | |
1655 } | |
1656 | |
1657 #endif |