annotate src/share/vm/runtime/synchronizer.cpp @ 9126:bc26f978b0ce

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