annotate src/share/vm/runtime/biasedLocking.hpp @ 1721:413ad0331a0c

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