annotate src/share/vm/runtime/synchronizer.cpp @ 6862:8a5ea0a9ccc4

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