611 assert(k != NULL, "invariant");
612 assert(op != NULL, "invariant");
613 assert(event->should_commit(), "invariant");
614 event->set_lockClass(k);
615 event->set_safepointId(op->safepoint_id());
616 event->set_previousOwner(op->biased_locker());
617 event->commit();
618 }
619
620 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, VM_BulkRevokeBias* op) {
621 assert(event != NULL, "invariant");
622 assert(k != NULL, "invariant");
623 assert(op != NULL, "invariant");
624 assert(event->should_commit(), "invariant");
625 event->set_revokedClass(k);
626 event->set_disableBiasing(!op->is_bulk_rebias());
627 event->set_safepointId(op->safepoint_id());
628 event->commit();
629 }
630
631 BiasedLocking::Condition fast_revoke(Handle obj, bool attempt_rebias, JavaThread* thread = NULL) {
632 // We can revoke the biases of anonymously-biased objects
633 // efficiently enough that we should not cause these revocations to
634 // update the heuristics because doing so may cause unwanted bulk
635 // revocations (which are expensive) to occur.
636 markOop mark = obj->mark();
637 if (mark->is_biased_anonymously() && !attempt_rebias) {
638 // We are probably trying to revoke the bias of this object due to
639 // an identity hash code computation. Try to revoke the bias
640 // without a safepoint. This is possible if we can successfully
641 // compare-and-exchange an unbiased header into the mark word of
642 // the object, meaning that no other thread has raced to acquire
643 // the bias of the object.
644 markOop biased_value = mark;
645 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
646 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
647 if (res_mark == biased_value) {
648 return BiasedLocking::BIAS_REVOKED;
649 }
650 } else if (mark->has_bias_pattern()) {
651 Klass* k = obj->klass();
652 markOop prototype_header = k->prototype_header();
653 if (!prototype_header->has_bias_pattern()) {
654 // This object has a stale bias from before the bulk revocation
655 // for this data type occurred. It's pointless to update the
656 // heuristics at this point so simply update the header with a
672 if (attempt_rebias) {
673 markOop biased_value = mark;
674 markOop rebiased_prototype = markOopDesc::encode(thread, mark->age(), prototype_header->bias_epoch());
675 markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
676 if (res_mark == biased_value) {
677 return BiasedLocking::BIAS_REVOKED_AND_REBIASED;
678 }
679 } else {
680 markOop biased_value = mark;
681 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
682 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
683 if (res_mark == biased_value) {
684 return BiasedLocking::BIAS_REVOKED;
685 }
686 }
687 }
688 }
689 return BiasedLocking::NOT_REVOKED;
690 }
691
692 BiasedLocking::Condition BiasedLocking::revoke_and_rebias_in_handshake(Handle obj, TRAPS) {
693 BiasedLocking::Condition bc = fast_revoke(obj, false);
694 if (bc != NOT_REVOKED) {
695 return bc;
696 }
697
698 markOop mark = obj->mark();
699 if (!mark->has_bias_pattern()) {
700 return NOT_BIASED;
701 }
702
703 Klass *k = obj->klass();
704 markOop prototype_header = k->prototype_header();
705 if (mark->biased_locker() == THREAD && prototype_header->bias_epoch() == mark->bias_epoch()) {
706 ResourceMark rm;
707 log_info(biasedlocking)("Revoking bias by walking my own stack:");
708 EventBiasedLockSelfRevocation event;
709 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
710 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
711 assert(cond == BIAS_REVOKED, "why not?");
712 if (event.should_commit()) {
713 post_self_revocation_event(&event, k);
714 }
715 return cond;
716 }
717
718 ShouldNotReachHere();
719
720 return NOT_REVOKED;
721 }
722
723 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
724 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
725 assert(!attempt_rebias || THREAD->is_Java_thread(), "");
726
727 BiasedLocking::Condition bc = fast_revoke(obj, attempt_rebias, (JavaThread*) THREAD);
728 if (bc != NOT_REVOKED) {
729 return bc;
730 }
731
732 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
733 if (heuristics == HR_NOT_BIASED) {
734 return NOT_BIASED;
735 } else if (heuristics == HR_SINGLE_REVOKE) {
736 markOop mark = obj->mark();
737 Klass *k = obj->klass();
738 markOop prototype_header = k->prototype_header();
739 if (mark->has_bias_pattern() &&
740 mark->biased_locker() == ((JavaThread*) THREAD) &&
741 prototype_header->bias_epoch() == mark->bias_epoch()) {
742 // A thread is trying to revoke the bias of an object biased
743 // toward it, again likely due to an identity hash code
744 // computation. We can again avoid a safepoint in this case
745 // since we are only going to walk our own stack. There are no
746 // races with revocations occurring in other threads because we
747 // reach no safepoints in the revocation path.
748 // Also check the epoch because even if threads match, another thread
749 // can come in with a CAS to steal the bias of an object that has a
750 // stale epoch.
751 ResourceMark rm;
752 log_info(biasedlocking)("Revoking bias by walking my own stack:");
753 EventBiasedLockSelfRevocation event;
754 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
755 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
756 assert(cond == BIAS_REVOKED, "why not?");
757 if (event.should_commit()) {
758 post_self_revocation_event(&event, k);
759 }
760 return cond;
|
611 assert(k != NULL, "invariant");
612 assert(op != NULL, "invariant");
613 assert(event->should_commit(), "invariant");
614 event->set_lockClass(k);
615 event->set_safepointId(op->safepoint_id());
616 event->set_previousOwner(op->biased_locker());
617 event->commit();
618 }
619
620 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, VM_BulkRevokeBias* op) {
621 assert(event != NULL, "invariant");
622 assert(k != NULL, "invariant");
623 assert(op != NULL, "invariant");
624 assert(event->should_commit(), "invariant");
625 event->set_revokedClass(k);
626 event->set_disableBiasing(!op->is_bulk_rebias());
627 event->set_safepointId(op->safepoint_id());
628 event->commit();
629 }
630
631 BiasedLocking::Condition fast_revoke(Handle obj, markOop mark, bool attempt_rebias, JavaThread* thread = NULL) {
632 // We can revoke the biases of anonymously-biased objects
633 // efficiently enough that we should not cause these revocations to
634 // update the heuristics because doing so may cause unwanted bulk
635 // revocations (which are expensive) to occur.
636 if (mark->is_biased_anonymously() && !attempt_rebias) {
637 // We are probably trying to revoke the bias of this object due to
638 // an identity hash code computation. Try to revoke the bias
639 // without a safepoint. This is possible if we can successfully
640 // compare-and-exchange an unbiased header into the mark word of
641 // the object, meaning that no other thread has raced to acquire
642 // the bias of the object.
643 markOop biased_value = mark;
644 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
645 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
646 if (res_mark == biased_value) {
647 return BiasedLocking::BIAS_REVOKED;
648 }
649 } else if (mark->has_bias_pattern()) {
650 Klass* k = obj->klass();
651 markOop prototype_header = k->prototype_header();
652 if (!prototype_header->has_bias_pattern()) {
653 // This object has a stale bias from before the bulk revocation
654 // for this data type occurred. It's pointless to update the
655 // heuristics at this point so simply update the header with a
671 if (attempt_rebias) {
672 markOop biased_value = mark;
673 markOop rebiased_prototype = markOopDesc::encode(thread, mark->age(), prototype_header->bias_epoch());
674 markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
675 if (res_mark == biased_value) {
676 return BiasedLocking::BIAS_REVOKED_AND_REBIASED;
677 }
678 } else {
679 markOop biased_value = mark;
680 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
681 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
682 if (res_mark == biased_value) {
683 return BiasedLocking::BIAS_REVOKED;
684 }
685 }
686 }
687 }
688 return BiasedLocking::NOT_REVOKED;
689 }
690
691 BiasedLocking::Condition BiasedLocking::revoke_own_locks_in_handshake(Handle obj, TRAPS) {
692 markOop mark = obj->mark();
693 BiasedLocking::Condition bc = fast_revoke(obj, mark, false);
694 if (bc != NOT_REVOKED) {
695 return bc;
696 }
697
698 if (!mark->has_bias_pattern()) {
699 return NOT_BIASED;
700 }
701
702 Klass *k = obj->klass();
703 markOop prototype_header = k->prototype_header();
704 guarantee(mark->biased_locker() == THREAD &&
705 prototype_header->bias_epoch() == mark->bias_epoch(), "Revoke failed, unhandled biased lock state");
706 ResourceMark rm;
707 log_info(biasedlocking)("Revoking bias by walking my own stack:");
708 EventBiasedLockSelfRevocation event;
709 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
710 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
711 assert(cond == BIAS_REVOKED, "why not?");
712 if (event.should_commit()) {
713 post_self_revocation_event(&event, k);
714 }
715 return cond;
716 }
717
718 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
719 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
720 assert(!attempt_rebias || THREAD->is_Java_thread(), "");
721
722 markOop mark = obj->mark();
723 BiasedLocking::Condition bc = fast_revoke(obj, mark, attempt_rebias, (JavaThread*) THREAD);
724 if (bc != NOT_REVOKED) {
725 return bc;
726 }
727
728 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
729 if (heuristics == HR_NOT_BIASED) {
730 return NOT_BIASED;
731 } else if (heuristics == HR_SINGLE_REVOKE) {
732 Klass *k = obj->klass();
733 markOop prototype_header = k->prototype_header();
734 if (mark->biased_locker() == THREAD &&
735 prototype_header->bias_epoch() == mark->bias_epoch()) {
736 // A thread is trying to revoke the bias of an object biased
737 // toward it, again likely due to an identity hash code
738 // computation. We can again avoid a safepoint in this case
739 // since we are only going to walk our own stack. There are no
740 // races with revocations occurring in other threads because we
741 // reach no safepoints in the revocation path.
742 // Also check the epoch because even if threads match, another thread
743 // can come in with a CAS to steal the bias of an object that has a
744 // stale epoch.
745 ResourceMark rm;
746 log_info(biasedlocking)("Revoking bias by walking my own stack:");
747 EventBiasedLockSelfRevocation event;
748 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
749 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
750 assert(cond == BIAS_REVOKED, "why not?");
751 if (event.should_commit()) {
752 post_self_revocation_event(&event, k);
753 }
754 return cond;
|