144
145
146 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
147 markOop mark = obj->mark();
148 if (!mark->has_bias_pattern()) {
149 if (TraceBiasedLocking) {
150 ResourceMark rm;
151 tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)",
152 obj->klass()->external_name());
153 }
154 return BiasedLocking::NOT_BIASED;
155 }
156
157 uint age = mark->age();
158 markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
159 markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
160
161 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
162 ResourceMark rm;
163 tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
164 (void *)obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
165 }
166
167 JavaThread* biased_thread = mark->biased_locker();
168 if (biased_thread == NULL) {
169 // Object is anonymously biased. We can get here if, for
170 // example, we revoke the bias due to an identity hash code
171 // being computed for an object.
172 if (!allow_rebias) {
173 obj->set_mark(unbiased_prototype);
174 }
175 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
176 tty->print_cr(" Revoked bias of anonymously-biased object");
177 }
178 return BiasedLocking::BIAS_REVOKED;
179 }
180
181 // Handle case where the thread toward which the object was biased has exited
182 bool thread_is_alive = false;
183 if (requesting_thread == biased_thread) {
184 thread_is_alive = true;
197 obj->set_mark(unbiased_prototype);
198 }
199 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
200 tty->print_cr(" Revoked bias of object biased toward dead thread");
201 }
202 return BiasedLocking::BIAS_REVOKED;
203 }
204
205 // Thread owning bias is alive.
206 // Check to see whether it currently owns the lock and, if so,
207 // write down the needed displaced headers to the thread's stack.
208 // Otherwise, restore the object's header either to the unlocked
209 // or unbiased state.
210 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
211 BasicLock* highest_lock = NULL;
212 for (int i = 0; i < cached_monitor_info->length(); i++) {
213 MonitorInfo* mon_info = cached_monitor_info->at(i);
214 if (mon_info->owner() == obj) {
215 if (TraceBiasedLocking && Verbose) {
216 tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
217 (void *) mon_info->owner(),
218 (void *) obj);
219 }
220 // Assume recursive case and fix up highest lock later
221 markOop mark = markOopDesc::encode((BasicLock*) NULL);
222 highest_lock = mon_info->lock();
223 highest_lock->set_displaced_header(mark);
224 } else {
225 if (TraceBiasedLocking && Verbose) {
226 tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
227 (void *) mon_info->owner(),
228 (void *) obj);
229 }
230 }
231 }
232 if (highest_lock != NULL) {
233 // Fix up highest lock to contain displaced header and point
234 // object at it
235 highest_lock->set_displaced_header(unbiased_prototype);
236 // Reset object header to point to displaced mark.
237 // Must release storing the lock address for platforms without TSO
238 // ordering (e.g. ppc).
239 obj->release_set_mark(markOopDesc::encode(highest_lock));
240 assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
241 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
242 tty->print_cr(" Revoked bias of currently-locked object");
243 }
244 } else {
245 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
246 tty->print_cr(" Revoked bias of currently-unlocked object");
247 }
248 if (allow_rebias) {
311 }
312
313 if (revocation_count == BiasedLockingBulkRebiasThreshold) {
314 return HR_BULK_REBIAS;
315 }
316
317 return HR_SINGLE_REVOKE;
318 }
319
320
321 static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
322 bool bulk_rebias,
323 bool attempt_rebias_of_object,
324 JavaThread* requesting_thread) {
325 assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
326
327 if (TraceBiasedLocking) {
328 tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
329 INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
330 (bulk_rebias ? "rebias" : "revoke"),
331 (void *) o, (intptr_t) o->mark(), o->klass()->external_name());
332 }
333
334 jlong cur_time = os::javaTimeMillis();
335 o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
336
337
338 Klass* k_o = o->klass();
339 Klass* klass = k_o;
340
341 if (bulk_rebias) {
342 // Use the epoch in the klass of the object to implicitly revoke
343 // all biases of objects of this data type and force them to be
344 // reacquired. However, we also need to walk the stacks of all
345 // threads and update the headers of lightweight locked objects
346 // with biases to have the current epoch.
347
348 // If the prototype header doesn't have the bias pattern, don't
349 // try to update the epoch -- assume another VM operation came in
350 // and reset the header to the unbiased state, which will
351 // implicitly cause all existing biases to be revoked
|
144
145
146 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
147 markOop mark = obj->mark();
148 if (!mark->has_bias_pattern()) {
149 if (TraceBiasedLocking) {
150 ResourceMark rm;
151 tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)",
152 obj->klass()->external_name());
153 }
154 return BiasedLocking::NOT_BIASED;
155 }
156
157 uint age = mark->age();
158 markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
159 markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
160
161 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
162 ResourceMark rm;
163 tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
164 p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
165 }
166
167 JavaThread* biased_thread = mark->biased_locker();
168 if (biased_thread == NULL) {
169 // Object is anonymously biased. We can get here if, for
170 // example, we revoke the bias due to an identity hash code
171 // being computed for an object.
172 if (!allow_rebias) {
173 obj->set_mark(unbiased_prototype);
174 }
175 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
176 tty->print_cr(" Revoked bias of anonymously-biased object");
177 }
178 return BiasedLocking::BIAS_REVOKED;
179 }
180
181 // Handle case where the thread toward which the object was biased has exited
182 bool thread_is_alive = false;
183 if (requesting_thread == biased_thread) {
184 thread_is_alive = true;
197 obj->set_mark(unbiased_prototype);
198 }
199 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
200 tty->print_cr(" Revoked bias of object biased toward dead thread");
201 }
202 return BiasedLocking::BIAS_REVOKED;
203 }
204
205 // Thread owning bias is alive.
206 // Check to see whether it currently owns the lock and, if so,
207 // write down the needed displaced headers to the thread's stack.
208 // Otherwise, restore the object's header either to the unlocked
209 // or unbiased state.
210 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
211 BasicLock* highest_lock = NULL;
212 for (int i = 0; i < cached_monitor_info->length(); i++) {
213 MonitorInfo* mon_info = cached_monitor_info->at(i);
214 if (mon_info->owner() == obj) {
215 if (TraceBiasedLocking && Verbose) {
216 tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
217 p2i((void *) mon_info->owner()),
218 p2i((void *) obj));
219 }
220 // Assume recursive case and fix up highest lock later
221 markOop mark = markOopDesc::encode((BasicLock*) NULL);
222 highest_lock = mon_info->lock();
223 highest_lock->set_displaced_header(mark);
224 } else {
225 if (TraceBiasedLocking && Verbose) {
226 tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
227 p2i((void *) mon_info->owner()),
228 p2i((void *) obj));
229 }
230 }
231 }
232 if (highest_lock != NULL) {
233 // Fix up highest lock to contain displaced header and point
234 // object at it
235 highest_lock->set_displaced_header(unbiased_prototype);
236 // Reset object header to point to displaced mark.
237 // Must release storing the lock address for platforms without TSO
238 // ordering (e.g. ppc).
239 obj->release_set_mark(markOopDesc::encode(highest_lock));
240 assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
241 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
242 tty->print_cr(" Revoked bias of currently-locked object");
243 }
244 } else {
245 if (TraceBiasedLocking && (Verbose || !is_bulk)) {
246 tty->print_cr(" Revoked bias of currently-unlocked object");
247 }
248 if (allow_rebias) {
311 }
312
313 if (revocation_count == BiasedLockingBulkRebiasThreshold) {
314 return HR_BULK_REBIAS;
315 }
316
317 return HR_SINGLE_REVOKE;
318 }
319
320
321 static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
322 bool bulk_rebias,
323 bool attempt_rebias_of_object,
324 JavaThread* requesting_thread) {
325 assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
326
327 if (TraceBiasedLocking) {
328 tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
329 INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
330 (bulk_rebias ? "rebias" : "revoke"),
331 p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name());
332 }
333
334 jlong cur_time = os::javaTimeMillis();
335 o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
336
337
338 Klass* k_o = o->klass();
339 Klass* klass = k_o;
340
341 if (bulk_rebias) {
342 // Use the epoch in the klass of the object to implicitly revoke
343 // all biases of objects of this data type and force them to be
344 // reacquired. However, we also need to walk the stacks of all
345 // threads and update the headers of lightweight locked objects
346 // with biases to have the current epoch.
347
348 // If the prototype header doesn't have the bias pattern, don't
349 // try to update the epoch -- assume another VM operation came in
350 // and reset the header to the unbiased state, which will
351 // implicitly cause all existing biases to be revoked
|