annotate src/share/vm/runtime/biasedLocking.hpp @ 4155:394404b2d9bd

Removed strict requirement for GRAAL environment variable. It only needs to be set now if the graal directory is not in the directory hierarchy of GraalVM JDK.
author Doug Simon <doug.simon@oracle.com>
date Wed, 21 Dec 2011 11:25:27 +0100
parents f95d63e2154a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
2 * Copyright (c) 2005, 2010, 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: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
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: 0
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: 1552
diff changeset
25 #ifndef SHARE_VM_RUNTIME_BIASEDLOCKING_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define SHARE_VM_RUNTIME_BIASEDLOCKING_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "runtime/handles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "utilities/growableArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30
0
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // This class describes operations to implement Store-Free Biased
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Locking. The high-level properties of the scheme are similar to
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // IBM's lock reservation, Dice-Moir-Scherer QR locks, and other biased
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // locking mechanisms. The principal difference is in the handling of
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // recursive locking which is how this technique achieves a more
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // efficient fast path than these other schemes.
a61af66fc99e Initial load
duke
parents:
diff changeset
37 //
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // The basic observation is that in HotSpot's current fast locking
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // scheme, recursive locking (in the fast path) causes no update to
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // the object header. The recursion is described simply by stack
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // records containing a specific value (NULL). Only the last unlock by
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // a given thread causes an update to the object header.
a61af66fc99e Initial load
duke
parents:
diff changeset
43 //
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // This observation, coupled with the fact that HotSpot only compiles
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // methods for which monitor matching is obeyed (and which therefore
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // can not throw IllegalMonitorStateException), implies that we can
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // completely eliminate modifications to the object header for
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // recursive locking in compiled code, and perform similar recursion
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // checks and throwing of IllegalMonitorStateException in the
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // interpreter with little or no impact on the performance of the fast
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // path.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 //
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // The basic algorithm is as follows (note, see below for more details
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // and information). A pattern in the low three bits is reserved in
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // the object header to indicate whether biasing of a given object's
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // lock is currently being done or is allowed at all. If the bias
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // pattern is present, the contents of the rest of the header are
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // either the JavaThread* of the thread to which the lock is biased,
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // or NULL, indicating that the lock is "anonymously biased". The
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // first thread which locks an anonymously biased object biases the
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // lock toward that thread. If another thread subsequently attempts to
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // lock the same object, the bias is revoked.
a61af66fc99e Initial load
duke
parents:
diff changeset
63 //
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // Because there are no updates to the object header at all during
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // recursive locking while the lock is biased, the biased lock entry
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // code is simply a test of the object header's value. If this test
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // succeeds, the lock has been acquired by the thread. If this test
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // fails, a bit test is done to see whether the bias bit is still
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // set. If not, we fall back to HotSpot's original CAS-based locking
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // scheme. If it is set, we attempt to CAS in a bias toward this
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // thread. The latter operation is expected to be the rarest operation
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // performed on these locks. We optimistically expect the biased lock
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // entry to hit most of the time, and want the CAS-based fallthrough
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // to occur quickly in the situations where the bias has been revoked.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 //
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Revocation of the lock's bias is fairly straightforward. We want to
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // restore the object's header and stack-based BasicObjectLocks and
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // BasicLocks to the state they would have been in had the object been
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // locked by HotSpot's usual fast locking scheme. To do this, we bring
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // the system to a safepoint and walk the stack of the thread toward
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // which the lock is biased. We find all of the lock records on the
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // stack corresponding to this object, in particular the first /
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // "highest" record. We fill in the highest lock record with the
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // object's displaced header (which is a well-known value given that
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // we don't maintain an identity hash nor age bits for the object
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // while it's in the biased state) and all other lock records with 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // the value for recursive locks. When the safepoint is released, the
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // formerly-biased thread and all other threads revert back to
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // HotSpot's CAS-based locking.
a61af66fc99e Initial load
duke
parents:
diff changeset
90 //
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // This scheme can not handle transfers of biases of single objects
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // from thread to thread efficiently, but it can handle bulk transfers
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // of such biases, which is a usage pattern showing up in some
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // applications and benchmarks. We implement "bulk rebias" and "bulk
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // revoke" operations using a "bias epoch" on a per-data-type basis.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // If too many bias revocations are occurring for a particular data
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // type, the bias epoch for the data type is incremented at a
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // safepoint, effectively meaning that all previous biases are
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // invalid. The fast path locking case checks for an invalid epoch in
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // the object header and attempts to rebias the object with a CAS if
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // found, avoiding safepoints or bulk heap sweeps (the latter which
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // was used in a prior version of this algorithm and did not scale
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // well). If too many bias revocations persist, biasing is completely
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // disabled for the data type by resetting the prototype header to the
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // unbiased markOop. The fast-path locking code checks to see whether
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // the instance's bias pattern differs from the prototype header's and
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // causes the bias to be revoked without reaching a safepoint or,
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // again, a bulk heap sweep.
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // Biased locking counters
a61af66fc99e Initial load
duke
parents:
diff changeset
111 class BiasedLockingCounters VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
113 int _total_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 int _biased_lock_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 int _anonymously_biased_lock_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 int _rebiased_lock_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 int _revoked_lock_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 int _fast_path_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 int _slow_path_entry_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
122 BiasedLockingCounters() :
a61af66fc99e Initial load
duke
parents:
diff changeset
123 _total_entry_count(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
124 _biased_lock_entry_count(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
125 _anonymously_biased_lock_entry_count(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
126 _rebiased_lock_entry_count(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
127 _revoked_lock_entry_count(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
128 _fast_path_entry_count(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
129 _slow_path_entry_count(0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 int slow_path_entry_count(); // Compute this field if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 int* total_entry_count_addr() { return &_total_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
134 int* biased_lock_entry_count_addr() { return &_biased_lock_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 int* anonymously_biased_lock_entry_count_addr() { return &_anonymously_biased_lock_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 int* rebiased_lock_entry_count_addr() { return &_rebiased_lock_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
137 int* revoked_lock_entry_count_addr() { return &_revoked_lock_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 int* fast_path_entry_count_addr() { return &_fast_path_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 int* slow_path_entry_count_addr() { return &_slow_path_entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 bool nonzero() { return _total_entry_count > 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 void print_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 void print() { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 };
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 class BiasedLocking : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
150 static BiasedLockingCounters _counters;
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
153 static int* total_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 static int* biased_lock_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static int* anonymously_biased_lock_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
156 static int* rebiased_lock_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
157 static int* revoked_lock_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
158 static int* fast_path_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
159 static int* slow_path_entry_count_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 enum Condition {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 NOT_BIASED = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
163 BIAS_REVOKED = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
164 BIAS_REVOKED_AND_REBIASED = 3
a61af66fc99e Initial load
duke
parents:
diff changeset
165 };
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // This initialization routine should only be called once and
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // schedules a PeriodicTask to turn on biased locking a few seconds
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // into the VM run to avoid startup time regressions
a61af66fc99e Initial load
duke
parents:
diff changeset
170 static void init();
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // This provides a global switch for leaving biased locking disabled
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // for the first part of a run and enabling it later
a61af66fc99e Initial load
duke
parents:
diff changeset
174 static bool enabled();
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // This should be called by JavaThreads to revoke the bias of an object
a61af66fc99e Initial load
duke
parents:
diff changeset
177 static Condition revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // These do not allow rebiasing; they are used by deoptimization to
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // ensure that monitors on the stack can be migrated
a61af66fc99e Initial load
duke
parents:
diff changeset
181 static void revoke(GrowableArray<Handle>* objs);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 static void revoke_at_safepoint(Handle obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 static void revoke_at_safepoint(GrowableArray<Handle>* objs);
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 static void print_counters() { _counters.print(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 static BiasedLockingCounters* counters() { return &_counters; }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // These routines are GC-related and should not be called by end
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // users. GCs which do not do preservation of mark words do not need
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // to call these routines.
a61af66fc99e Initial load
duke
parents:
diff changeset
191 static void preserve_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
192 static void restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
193 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
194
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
195 #endif // SHARE_VM_RUNTIME_BIASEDLOCKING_HPP