155 } |
155 } |
156 |
156 |
157 |
157 |
158 // After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL, |
158 // After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL, |
159 // AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization). |
159 // AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization). |
160 BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) { |
160 void BiasedLocking::single_revoke_at_safepoint(oop obj, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) { |
161 assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); |
161 assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); |
162 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
162 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
163 |
163 |
164 markWord mark = obj->mark(); |
164 markWord mark = obj->mark(); |
165 if (!mark.has_bias_pattern()) { |
165 if (!mark.has_bias_pattern()) { |
171 " because it's no longer biased)", |
171 " because it's no longer biased)", |
172 p2i((void *)obj), mark.value(), |
172 p2i((void *)obj), mark.value(), |
173 obj->klass()->external_name(), |
173 obj->klass()->external_name(), |
174 (intptr_t) requesting_thread); |
174 (intptr_t) requesting_thread); |
175 } |
175 } |
176 return NOT_BIASED; |
176 return; |
177 } |
177 } |
178 |
178 |
179 uint age = mark.age(); |
179 uint age = mark.age(); |
180 markWord biased_prototype = markWord::biased_locking_prototype().set_age(age); |
|
181 markWord unbiased_prototype = markWord::prototype().set_age(age); |
180 markWord unbiased_prototype = markWord::prototype().set_age(age); |
182 |
181 |
183 // Log at "info" level if not bulk, else "trace" level |
182 // Log at "info" level if not bulk, else "trace" level |
184 if (!is_bulk) { |
183 if (!is_bulk) { |
185 ResourceMark rm; |
184 ResourceMark rm; |
186 log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT ", mark " |
185 log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT ", mark " |
187 INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT |
186 INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT |
188 ", allow rebias %d, requesting thread " INTPTR_FORMAT, |
187 ", requesting thread " INTPTR_FORMAT, |
189 p2i((void *)obj), |
188 p2i((void *)obj), |
190 mark.value(), |
189 mark.value(), |
191 obj->klass()->external_name(), |
190 obj->klass()->external_name(), |
192 obj->klass()->prototype_header().value(), |
191 obj->klass()->prototype_header().value(), |
193 (allow_rebias ? 1 : 0), |
|
194 (intptr_t) requesting_thread); |
192 (intptr_t) requesting_thread); |
195 } else { |
193 } else { |
196 ResourceMark rm; |
194 ResourceMark rm; |
197 log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark " |
195 log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark " |
198 INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT |
196 INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT |
199 " , allow rebias %d , requesting thread " INTPTR_FORMAT, |
197 " , requesting thread " INTPTR_FORMAT, |
200 p2i((void *)obj), |
198 p2i((void *)obj), |
201 mark.value(), |
199 mark.value(), |
202 obj->klass()->external_name(), |
200 obj->klass()->external_name(), |
203 obj->klass()->prototype_header().value(), |
201 obj->klass()->prototype_header().value(), |
204 (allow_rebias ? 1 : 0), |
|
205 (intptr_t) requesting_thread); |
202 (intptr_t) requesting_thread); |
206 } |
203 } |
207 |
204 |
208 JavaThread* biased_thread = mark.biased_locker(); |
205 JavaThread* biased_thread = mark.biased_locker(); |
209 if (biased_thread == NULL) { |
206 if (biased_thread == NULL) { |
210 // Object is anonymously biased. We can get here if, for |
207 // Object is anonymously biased. We can get here if, for |
211 // example, we revoke the bias due to an identity hash code |
208 // example, we revoke the bias due to an identity hash code |
212 // being computed for an object. |
209 // being computed for an object. |
213 if (!allow_rebias) { |
210 obj->set_mark(unbiased_prototype); |
214 obj->set_mark(unbiased_prototype); |
211 |
215 } |
|
216 // Log at "info" level if not bulk, else "trace" level |
212 // Log at "info" level if not bulk, else "trace" level |
217 if (!is_bulk) { |
213 if (!is_bulk) { |
218 log_info(biasedlocking)(" Revoked bias of anonymously-biased object"); |
214 log_info(biasedlocking)(" Revoked bias of anonymously-biased object"); |
219 } else { |
215 } else { |
220 log_trace(biasedlocking)(" Revoked bias of anonymously-biased object"); |
216 log_trace(biasedlocking)(" Revoked bias of anonymously-biased object"); |
221 } |
217 } |
222 return BIAS_REVOKED; |
218 return; |
223 } |
219 } |
224 |
220 |
225 // Handle case where the thread toward which the object was biased has exited |
221 // Handle case where the thread toward which the object was biased has exited |
226 bool thread_is_alive = false; |
222 bool thread_is_alive = false; |
227 if (requesting_thread == biased_thread) { |
223 if (requesting_thread == biased_thread) { |
229 } else { |
225 } else { |
230 ThreadsListHandle tlh; |
226 ThreadsListHandle tlh; |
231 thread_is_alive = tlh.includes(biased_thread); |
227 thread_is_alive = tlh.includes(biased_thread); |
232 } |
228 } |
233 if (!thread_is_alive) { |
229 if (!thread_is_alive) { |
234 if (allow_rebias) { |
230 obj->set_mark(unbiased_prototype); |
235 obj->set_mark(biased_prototype); |
|
236 } else { |
|
237 obj->set_mark(unbiased_prototype); |
|
238 } |
|
239 // Log at "info" level if not bulk, else "trace" level |
231 // Log at "info" level if not bulk, else "trace" level |
240 if (!is_bulk) { |
232 if (!is_bulk) { |
241 log_info(biasedlocking)(" Revoked bias of object biased toward dead thread (" |
233 log_info(biasedlocking)(" Revoked bias of object biased toward dead thread (" |
242 PTR_FORMAT ")", p2i(biased_thread)); |
234 PTR_FORMAT ")", p2i(biased_thread)); |
243 } else { |
235 } else { |
244 log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread (" |
236 log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread (" |
245 PTR_FORMAT ")", p2i(biased_thread)); |
237 PTR_FORMAT ")", p2i(biased_thread)); |
246 } |
238 } |
247 return BIAS_REVOKED; |
239 return; |
248 } |
240 } |
249 |
241 |
250 // Log at "info" level if not bulk, else "trace" level |
242 // Log at "info" level if not bulk, else "trace" level |
251 if (!is_bulk) { |
243 if (!is_bulk) { |
252 log_info(biasedlocking)(" Revoked bias of object biased toward live thread (" |
244 log_info(biasedlocking)(" Revoked bias of object biased toward live thread (" |
299 if (!is_bulk) { |
291 if (!is_bulk) { |
300 log_info(biasedlocking)(" Revoked bias of currently-unlocked object"); |
292 log_info(biasedlocking)(" Revoked bias of currently-unlocked object"); |
301 } else { |
293 } else { |
302 log_trace(biasedlocking)(" Revoked bias of currently-unlocked object"); |
294 log_trace(biasedlocking)(" Revoked bias of currently-unlocked object"); |
303 } |
295 } |
304 if (allow_rebias) { |
296 // Store the unlocked value into the object's header. |
305 obj->set_mark(biased_prototype); |
297 obj->set_mark(unbiased_prototype); |
306 } else { |
|
307 // Store the unlocked value into the object's header. |
|
308 obj->set_mark(unbiased_prototype); |
|
309 } |
|
310 } |
298 } |
311 |
299 |
312 // If requested, return information on which thread held the bias |
300 // If requested, return information on which thread held the bias |
313 if (biased_locker != NULL) { |
301 if (biased_locker != NULL) { |
314 *biased_locker = biased_thread; |
302 *biased_locker = biased_thread; |
315 } |
303 } |
316 |
|
317 return BIAS_REVOKED; |
|
318 } |
304 } |
319 |
305 |
320 |
306 |
321 enum HeuristicsResult { |
307 enum HeuristicsResult { |
322 HR_NOT_BIASED = 1, |
308 HR_NOT_BIASED = 1, |
377 |
363 |
378 return HR_SINGLE_REVOKE; |
364 return HR_SINGLE_REVOKE; |
379 } |
365 } |
380 |
366 |
381 |
367 |
382 BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o, |
368 void BiasedLocking::bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread* requesting_thread) { |
383 bool bulk_rebias, |
|
384 bool attempt_rebias_of_object, |
|
385 JavaThread* requesting_thread) { |
|
386 assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); |
369 assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); |
387 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
370 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
388 |
371 |
389 log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object " |
372 log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object " |
390 INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
373 INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
457 for (int i = 0; i < cached_monitor_info->length(); i++) { |
440 for (int i = 0; i < cached_monitor_info->length(); i++) { |
458 MonitorInfo* mon_info = cached_monitor_info->at(i); |
441 MonitorInfo* mon_info = cached_monitor_info->at(i); |
459 oop owner = mon_info->owner(); |
442 oop owner = mon_info->owner(); |
460 markWord mark = owner->mark(); |
443 markWord mark = owner->mark(); |
461 if ((owner->klass() == k_o) && mark.has_bias_pattern()) { |
444 if ((owner->klass() == k_o) && mark.has_bias_pattern()) { |
462 single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL); |
445 single_revoke_at_safepoint(owner, true, requesting_thread, NULL); |
463 } |
446 } |
464 } |
447 } |
465 } |
448 } |
466 |
449 |
467 // Must force the bias of the passed object to be forcibly revoked |
450 // Must force the bias of the passed object to be forcibly revoked |
468 // as well to ensure guarantees to callers |
451 // as well to ensure guarantees to callers |
469 single_revoke_at_safepoint(o, false, true, requesting_thread, NULL); |
452 single_revoke_at_safepoint(o, true, requesting_thread, NULL); |
470 } |
453 } |
471 } // ThreadsListHandle is destroyed here. |
454 } // ThreadsListHandle is destroyed here. |
472 |
455 |
473 log_info(biasedlocking)("* Ending bulk revocation"); |
456 log_info(biasedlocking)("* Ending bulk revocation"); |
474 |
457 |
475 BiasedLocking::Condition status_code = BIAS_REVOKED; |
458 assert(!o->mark().has_bias_pattern(), "bug in bulk bias revocation"); |
476 |
|
477 if (attempt_rebias_of_object && |
|
478 o->mark().has_bias_pattern() && |
|
479 klass->prototype_header().has_bias_pattern()) { |
|
480 markWord new_mark = markWord::encode(requesting_thread, o->mark().age(), |
|
481 klass->prototype_header().bias_epoch()); |
|
482 o->set_mark(new_mark); |
|
483 status_code = BIAS_REVOKED_AND_REBIASED; |
|
484 log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread); |
|
485 } |
|
486 |
|
487 assert(!o->mark().has_bias_pattern() || |
|
488 (attempt_rebias_of_object && (o->mark().biased_locker() == requesting_thread)), |
|
489 "bug in bulk bias revocation"); |
|
490 |
|
491 return status_code; |
|
492 } |
459 } |
493 |
460 |
494 |
461 |
495 static void clean_up_cached_monitor_info(JavaThread* thread = NULL) { |
462 static void clean_up_cached_monitor_info(JavaThread* thread = NULL) { |
496 if (thread != NULL) { |
463 if (thread != NULL) { |
507 class VM_BulkRevokeBias : public VM_Operation { |
474 class VM_BulkRevokeBias : public VM_Operation { |
508 private: |
475 private: |
509 Handle* _obj; |
476 Handle* _obj; |
510 JavaThread* _requesting_thread; |
477 JavaThread* _requesting_thread; |
511 bool _bulk_rebias; |
478 bool _bulk_rebias; |
512 bool _attempt_rebias_of_object; |
|
513 BiasedLocking::Condition _status_code; |
|
514 uint64_t _safepoint_id; |
479 uint64_t _safepoint_id; |
515 |
480 |
516 public: |
481 public: |
517 VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread, |
482 VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread, |
518 bool bulk_rebias, |
483 bool bulk_rebias) |
519 bool attempt_rebias_of_object) |
|
520 : _obj(obj) |
484 : _obj(obj) |
521 , _requesting_thread(requesting_thread) |
485 , _requesting_thread(requesting_thread) |
522 , _bulk_rebias(bulk_rebias) |
486 , _bulk_rebias(bulk_rebias) |
523 , _attempt_rebias_of_object(attempt_rebias_of_object) |
|
524 , _status_code(BiasedLocking::NOT_BIASED) |
|
525 , _safepoint_id(0) {} |
487 , _safepoint_id(0) {} |
526 |
488 |
527 virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; } |
489 virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; } |
528 |
490 |
529 virtual void doit() { |
491 virtual void doit() { |
530 _status_code = BiasedLocking::bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread); |
492 BiasedLocking::bulk_revoke_at_safepoint((*_obj)(), _bulk_rebias, _requesting_thread); |
531 _safepoint_id = SafepointSynchronize::safepoint_id(); |
493 _safepoint_id = SafepointSynchronize::safepoint_id(); |
532 clean_up_cached_monitor_info(); |
494 clean_up_cached_monitor_info(); |
533 } |
495 } |
534 |
496 |
535 bool is_bulk_rebias() const { |
497 bool is_bulk_rebias() const { |
536 return _bulk_rebias; |
498 return _bulk_rebias; |
537 } |
|
538 |
|
539 BiasedLocking::Condition status_code() const { |
|
540 return _status_code; |
|
541 } |
499 } |
542 |
500 |
543 uint64_t safepoint_id() const { |
501 uint64_t safepoint_id() const { |
544 return _safepoint_id; |
502 return _safepoint_id; |
545 } |
503 } |
767 |
725 |
768 assert(!obj->mark().has_bias_pattern(), "must not be biased"); |
726 assert(!obj->mark().has_bias_pattern(), "must not be biased"); |
769 } |
727 } |
770 |
728 |
771 |
729 |
772 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) { |
730 void BiasedLocking::revoke(Handle obj, TRAPS) { |
773 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint"); |
731 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint"); |
774 |
732 |
775 while (true) { |
733 while (true) { |
776 // We can revoke the biases of anonymously-biased objects |
734 // We can revoke the biases of anonymously-biased objects |
777 // efficiently enough that we should not cause these revocations to |
735 // efficiently enough that we should not cause these revocations to |
778 // update the heuristics because doing so may cause unwanted bulk |
736 // update the heuristics because doing so may cause unwanted bulk |
779 // revocations (which are expensive) to occur. |
737 // revocations (which are expensive) to occur. |
780 markWord mark = obj->mark(); |
738 markWord mark = obj->mark(); |
781 if (mark.is_biased_anonymously() && !attempt_rebias) { |
739 |
|
740 if (!mark.has_bias_pattern()) { |
|
741 return; |
|
742 } |
|
743 |
|
744 if (mark.is_biased_anonymously()) { |
782 // We are probably trying to revoke the bias of this object due to |
745 // We are probably trying to revoke the bias of this object due to |
783 // an identity hash code computation. Try to revoke the bias |
746 // an identity hash code computation. Try to revoke the bias |
784 // without a safepoint. This is possible if we can successfully |
747 // without a safepoint. This is possible if we can successfully |
785 // compare-and-exchange an unbiased header into the mark word of |
748 // compare-and-exchange an unbiased header into the mark word of |
786 // the object, meaning that no other thread has raced to acquire |
749 // the object, meaning that no other thread has raced to acquire |
787 // the bias of the object. |
750 // the bias of the object. |
788 markWord biased_value = mark; |
751 markWord biased_value = mark; |
789 markWord unbiased_prototype = markWord::prototype().set_age(mark.age()); |
752 markWord unbiased_prototype = markWord::prototype().set_age(mark.age()); |
790 markWord res_mark = obj->cas_set_mark(unbiased_prototype, mark); |
753 markWord res_mark = obj->cas_set_mark(unbiased_prototype, mark); |
791 if (res_mark == biased_value) { |
754 if (res_mark == biased_value) { |
792 return BIAS_REVOKED; |
755 return; |
793 } |
756 } |
794 mark = res_mark; // Refresh mark with the latest value. |
757 mark = res_mark; // Refresh mark with the latest value. |
795 } else if (mark.has_bias_pattern()) { |
758 } else { |
796 Klass* k = obj->klass(); |
759 Klass* k = obj->klass(); |
797 markWord prototype_header = k->prototype_header(); |
760 markWord prototype_header = k->prototype_header(); |
798 if (!prototype_header.has_bias_pattern()) { |
761 if (!prototype_header.has_bias_pattern()) { |
799 // This object has a stale bias from before the bulk revocation |
762 // This object has a stale bias from before the bulk revocation |
800 // for this data type occurred. It's pointless to update the |
763 // for this data type occurred. It's pointless to update the |
802 // CAS. If we fail this race, the object's bias has been revoked |
765 // CAS. If we fail this race, the object's bias has been revoked |
803 // by another thread so we simply return and let the caller deal |
766 // by another thread so we simply return and let the caller deal |
804 // with it. |
767 // with it. |
805 obj->cas_set_mark(prototype_header.set_age(mark.age()), mark); |
768 obj->cas_set_mark(prototype_header.set_age(mark.age()), mark); |
806 assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked"); |
769 assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked"); |
807 return BIAS_REVOKED; |
770 return; |
808 } else if (prototype_header.bias_epoch() != mark.bias_epoch()) { |
771 } else if (prototype_header.bias_epoch() != mark.bias_epoch()) { |
809 // The epoch of this biasing has expired indicating that the |
772 // The epoch of this biasing has expired indicating that the |
810 // object is effectively unbiased. Depending on whether we need |
773 // object is effectively unbiased. We can revoke the bias of this |
811 // to rebias or revoke the bias of this object we can do it |
774 // object efficiently enough with a CAS that we shouldn't update the |
812 // efficiently enough with a CAS that we shouldn't update the |
|
813 // heuristics. This is normally done in the assembly code but we |
775 // heuristics. This is normally done in the assembly code but we |
814 // can reach this point due to various points in the runtime |
776 // can reach this point due to various points in the runtime |
815 // needing to revoke biases. |
777 // needing to revoke biases. |
816 markWord res_mark; |
778 markWord res_mark; |
817 if (attempt_rebias) { |
779 markWord biased_value = mark; |
818 assert(THREAD->is_Java_thread(), ""); |
780 markWord unbiased_prototype = markWord::prototype().set_age(mark.age()); |
819 markWord biased_value = mark; |
781 res_mark = obj->cas_set_mark(unbiased_prototype, mark); |
820 markWord rebiased_prototype = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch()); |
782 if (res_mark == biased_value) { |
821 res_mark = obj->cas_set_mark(rebiased_prototype, mark); |
783 return; |
822 if (res_mark == biased_value) { |
|
823 return BIAS_REVOKED_AND_REBIASED; |
|
824 } |
|
825 } else { |
|
826 markWord biased_value = mark; |
|
827 markWord unbiased_prototype = markWord::prototype().set_age(mark.age()); |
|
828 res_mark = obj->cas_set_mark(unbiased_prototype, mark); |
|
829 if (res_mark == biased_value) { |
|
830 return BIAS_REVOKED; |
|
831 } |
|
832 } |
784 } |
833 mark = res_mark; // Refresh mark with the latest value. |
785 mark = res_mark; // Refresh mark with the latest value. |
834 } |
786 } |
835 } |
787 } |
836 |
788 |
837 HeuristicsResult heuristics = update_heuristics(obj()); |
789 HeuristicsResult heuristics = update_heuristics(obj()); |
838 if (heuristics == HR_NOT_BIASED) { |
790 if (heuristics == HR_NOT_BIASED) { |
839 return NOT_BIASED; |
791 return; |
840 } else if (heuristics == HR_SINGLE_REVOKE) { |
792 } else if (heuristics == HR_SINGLE_REVOKE) { |
841 JavaThread *blt = mark.biased_locker(); |
793 JavaThread *blt = mark.biased_locker(); |
842 assert(blt != NULL, "invariant"); |
794 assert(blt != NULL, "invariant"); |
843 if (blt == THREAD) { |
795 if (blt == THREAD) { |
844 // A thread is trying to revoke the bias of an object biased |
796 // A thread is trying to revoke the bias of an object biased |
853 blt->set_cached_monitor_info(NULL); |
805 blt->set_cached_monitor_info(NULL); |
854 assert(!obj->mark().has_bias_pattern(), "invariant"); |
806 assert(!obj->mark().has_bias_pattern(), "invariant"); |
855 if (event.should_commit()) { |
807 if (event.should_commit()) { |
856 post_self_revocation_event(&event, obj->klass()); |
808 post_self_revocation_event(&event, obj->klass()); |
857 } |
809 } |
858 return BIAS_REVOKED; |
810 return; |
859 } else { |
811 } else { |
860 BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt); |
812 BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt); |
861 if (cond != NOT_REVOKED) { |
813 if (cond != NOT_REVOKED) { |
862 return cond; |
814 return; |
863 } |
815 } |
864 } |
816 } |
865 } else { |
817 } else { |
866 assert((heuristics == HR_BULK_REVOKE) || |
818 assert((heuristics == HR_BULK_REVOKE) || |
867 (heuristics == HR_BULK_REBIAS), "?"); |
819 (heuristics == HR_BULK_REBIAS), "?"); |
868 EventBiasedLockClassRevocation event; |
820 EventBiasedLockClassRevocation event; |
869 VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD, |
821 VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD, |
870 (heuristics == HR_BULK_REBIAS), |
822 (heuristics == HR_BULK_REBIAS)); |
871 attempt_rebias); |
|
872 VMThread::execute(&bulk_revoke); |
823 VMThread::execute(&bulk_revoke); |
873 if (event.should_commit()) { |
824 if (event.should_commit()) { |
874 post_class_revocation_event(&event, obj->klass(), &bulk_revoke); |
825 post_class_revocation_event(&event, obj->klass(), &bulk_revoke); |
875 } |
826 } |
876 return bulk_revoke.status_code(); |
827 return; |
877 } |
828 } |
878 } |
829 } |
879 } |
830 } |
880 |
831 |
881 // All objects in objs should be locked by biaser |
832 // All objects in objs should be locked by biaser |
899 assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint"); |
850 assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint"); |
900 oop obj = h_obj(); |
851 oop obj = h_obj(); |
901 HeuristicsResult heuristics = update_heuristics(obj); |
852 HeuristicsResult heuristics = update_heuristics(obj); |
902 if (heuristics == HR_SINGLE_REVOKE) { |
853 if (heuristics == HR_SINGLE_REVOKE) { |
903 JavaThread* biased_locker = NULL; |
854 JavaThread* biased_locker = NULL; |
904 single_revoke_at_safepoint(obj, false, false, NULL, &biased_locker); |
855 single_revoke_at_safepoint(obj, false, NULL, &biased_locker); |
905 if (biased_locker) { |
856 if (biased_locker) { |
906 clean_up_cached_monitor_info(biased_locker); |
857 clean_up_cached_monitor_info(biased_locker); |
907 } |
858 } |
908 } else if ((heuristics == HR_BULK_REBIAS) || |
859 } else if ((heuristics == HR_BULK_REBIAS) || |
909 (heuristics == HR_BULK_REVOKE)) { |
860 (heuristics == HR_BULK_REVOKE)) { |
910 bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); |
861 bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL); |
911 clean_up_cached_monitor_info(); |
862 clean_up_cached_monitor_info(); |
912 } |
863 } |
913 } |
864 } |
914 |
865 |
915 |
866 |
918 int len = objs->length(); |
869 int len = objs->length(); |
919 for (int i = 0; i < len; i++) { |
870 for (int i = 0; i < len; i++) { |
920 oop obj = (objs->at(i))(); |
871 oop obj = (objs->at(i))(); |
921 HeuristicsResult heuristics = update_heuristics(obj); |
872 HeuristicsResult heuristics = update_heuristics(obj); |
922 if (heuristics == HR_SINGLE_REVOKE) { |
873 if (heuristics == HR_SINGLE_REVOKE) { |
923 single_revoke_at_safepoint(obj, false, false, NULL, NULL); |
874 single_revoke_at_safepoint(obj, false, NULL, NULL); |
924 } else if ((heuristics == HR_BULK_REBIAS) || |
875 } else if ((heuristics == HR_BULK_REBIAS) || |
925 (heuristics == HR_BULK_REVOKE)) { |
876 (heuristics == HR_BULK_REVOKE)) { |
926 bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); |
877 bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL); |
927 } |
878 } |
928 } |
879 } |
929 clean_up_cached_monitor_info(); |
880 clean_up_cached_monitor_info(); |
930 } |
881 } |
931 |
882 |