610 event->set_previousOwner(revoke->biased_locker());
611 event->commit();
612 }
613
614 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, bool disabled_bias) {
615 assert(event != NULL, "invariant");
616 assert(k != NULL, "invariant");
617 assert(event->should_commit(), "invariant");
618 event->set_revokedClass(k);
619 event->set_disableBiasing(disabled_bias);
620 set_safepoint_id(event);
621 event->commit();
622 }
623
624 BiasedLocking::Condition fast_revoke(Handle obj, bool attempt_rebias, JavaThread* thread = NULL) {
625 // We can revoke the biases of anonymously-biased objects
626 // efficiently enough that we should not cause these revocations to
627 // update the heuristics because doing so may cause unwanted bulk
628 // revocations (which are expensive) to occur.
629 markOop mark = obj->mark();
630 if (mark->is_biased_anonymously()) {
631 // We are probably trying to revoke the bias of this object due to
632 // an identity hash code computation. Try to revoke the bias
633 // without a safepoint. This is possible if we can successfully
634 // compare-and-exchange an unbiased header into the mark word of
635 // the object, meaning that no other thread has raced to acquire
636 // the bias of the object.
637 markOop biased_value = mark;
638 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
639 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
640 if (res_mark == biased_value) {
641 return BiasedLocking::BIAS_REVOKED;
642 }
643 } else if (mark->has_bias_pattern()) {
644 Klass* k = obj->klass();
645 markOop prototype_header = k->prototype_header();
646 if (!prototype_header->has_bias_pattern()) {
647 // This object has a stale bias from before the bulk revocation
648 // for this data type occurred. It's pointless to update the
649 // heuristics at this point so simply update the header with a
650 // CAS. If we fail this race, the object's bias has been revoked
712
713 return NOT_REVOKED;
714 }
715
716 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
717 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
718 assert(!attempt_rebias || THREAD->is_Java_thread(), "");
719
720 BiasedLocking::Condition bc = fast_revoke(obj, attempt_rebias, (JavaThread*) THREAD);
721 if (bc != NOT_REVOKED) {
722 return bc;
723 }
724
725 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
726 if (heuristics == HR_NOT_BIASED) {
727 return NOT_BIASED;
728 } else if (heuristics == HR_SINGLE_REVOKE) {
729 markOop mark = obj->mark();
730 Klass *k = obj->klass();
731 markOop prototype_header = k->prototype_header();
732 if (mark->biased_locker_is((JavaThread*) THREAD) &&
733 prototype_header->bias_epoch() == mark->bias_epoch()) {
734 // A thread is trying to revoke the bias of an object biased
735 // toward it, again likely due to an identity hash code
736 // computation. We can again avoid a safepoint in this case
737 // since we are only going to walk our own stack. There are no
738 // races with revocations occurring in other threads because we
739 // reach no safepoints in the revocation path.
740 // Also check the epoch because even if threads match, another thread
741 // can come in with a CAS to steal the bias of an object that has a
742 // stale epoch.
743 ResourceMark rm;
744 log_info(biasedlocking)("Revoking bias by walking my own stack:");
745 EventBiasedLockSelfRevocation event;
746 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
747 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
748 assert(cond == BIAS_REVOKED, "why not?");
749 if (event.should_commit()) {
750 post_self_revocation_event(&event, k);
751 }
752 return cond;
|
610 event->set_previousOwner(revoke->biased_locker());
611 event->commit();
612 }
613
614 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, bool disabled_bias) {
615 assert(event != NULL, "invariant");
616 assert(k != NULL, "invariant");
617 assert(event->should_commit(), "invariant");
618 event->set_revokedClass(k);
619 event->set_disableBiasing(disabled_bias);
620 set_safepoint_id(event);
621 event->commit();
622 }
623
624 BiasedLocking::Condition fast_revoke(Handle obj, bool attempt_rebias, JavaThread* thread = NULL) {
625 // We can revoke the biases of anonymously-biased objects
626 // efficiently enough that we should not cause these revocations to
627 // update the heuristics because doing so may cause unwanted bulk
628 // revocations (which are expensive) to occur.
629 markOop mark = obj->mark();
630 if (mark->is_biased_anonymously() && !attempt_rebias) {
631 // We are probably trying to revoke the bias of this object due to
632 // an identity hash code computation. Try to revoke the bias
633 // without a safepoint. This is possible if we can successfully
634 // compare-and-exchange an unbiased header into the mark word of
635 // the object, meaning that no other thread has raced to acquire
636 // the bias of the object.
637 markOop biased_value = mark;
638 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
639 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
640 if (res_mark == biased_value) {
641 return BiasedLocking::BIAS_REVOKED;
642 }
643 } else if (mark->has_bias_pattern()) {
644 Klass* k = obj->klass();
645 markOop prototype_header = k->prototype_header();
646 if (!prototype_header->has_bias_pattern()) {
647 // This object has a stale bias from before the bulk revocation
648 // for this data type occurred. It's pointless to update the
649 // heuristics at this point so simply update the header with a
650 // CAS. If we fail this race, the object's bias has been revoked
712
713 return NOT_REVOKED;
714 }
715
716 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
717 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
718 assert(!attempt_rebias || THREAD->is_Java_thread(), "");
719
720 BiasedLocking::Condition bc = fast_revoke(obj, attempt_rebias, (JavaThread*) THREAD);
721 if (bc != NOT_REVOKED) {
722 return bc;
723 }
724
725 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
726 if (heuristics == HR_NOT_BIASED) {
727 return NOT_BIASED;
728 } else if (heuristics == HR_SINGLE_REVOKE) {
729 markOop mark = obj->mark();
730 Klass *k = obj->klass();
731 markOop prototype_header = k->prototype_header();
732 if (mark->has_bias_pattern() &&
733 mark->biased_locker() == ((JavaThread*) THREAD) &&
734 prototype_header->bias_epoch() == mark->bias_epoch()) {
735 // A thread is trying to revoke the bias of an object biased
736 // toward it, again likely due to an identity hash code
737 // computation. We can again avoid a safepoint in this case
738 // since we are only going to walk our own stack. There are no
739 // races with revocations occurring in other threads because we
740 // reach no safepoints in the revocation path.
741 // Also check the epoch because even if threads match, another thread
742 // can come in with a CAS to steal the bias of an object that has a
743 // stale epoch.
744 ResourceMark rm;
745 log_info(biasedlocking)("Revoking bias by walking my own stack:");
746 EventBiasedLockSelfRevocation event;
747 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
748 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
749 assert(cond == BIAS_REVOKED, "why not?");
750 if (event.should_commit()) {
751 post_self_revocation_event(&event, k);
752 }
753 return cond;
|