604 assert(event != NULL, "invariant");
605 assert(k != NULL, "invariant");
606 assert(revoke != NULL, "invariant");
607 assert(event->should_commit(), "invariant");
608 event->set_lockClass(k);
609 set_safepoint_id(event);
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 BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
625 assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
626
627 // We can revoke the biases of anonymously-biased objects
628 // efficiently enough that we should not cause these revocations to
629 // update the heuristics because doing so may cause unwanted bulk
630 // revocations (which are expensive) to occur.
631 markOop mark = obj->mark();
632 if (mark->is_biased_anonymously() && !attempt_rebias) {
633 // We are probably trying to revoke the bias of this object due to
634 // an identity hash code computation. Try to revoke the bias
635 // without a safepoint. This is possible if we can successfully
636 // compare-and-exchange an unbiased header into the mark word of
637 // the object, meaning that no other thread has raced to acquire
638 // the bias of the object.
639 markOop biased_value = mark;
640 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
641 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
642 if (res_mark == biased_value) {
643 return BIAS_REVOKED;
644 }
645 } else if (mark->has_bias_pattern()) {
646 Klass* k = obj->klass();
647 markOop prototype_header = k->prototype_header();
648 if (!prototype_header->has_bias_pattern()) {
649 // This object has a stale bias from before the bulk revocation
650 // for this data type occurred. It's pointless to update the
651 // heuristics at this point so simply update the header with a
652 // CAS. If we fail this race, the object's bias has been revoked
653 // by another thread so we simply return and let the caller deal
654 // with it.
655 markOop biased_value = mark;
656 markOop res_mark = obj->cas_set_mark(prototype_header, mark);
657 assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
658 return BIAS_REVOKED;
659 } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
660 // The epoch of this biasing has expired indicating that the
661 // object is effectively unbiased. Depending on whether we need
662 // to rebias or revoke the bias of this object we can do it
663 // efficiently enough with a CAS that we shouldn't update the
664 // heuristics. This is normally done in the assembly code but we
665 // can reach this point due to various points in the runtime
666 // needing to revoke biases.
667 if (attempt_rebias) {
668 assert(THREAD->is_Java_thread(), "");
669 markOop biased_value = mark;
670 markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
671 markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
672 if (res_mark == biased_value) {
673 return BIAS_REVOKED_AND_REBIASED;
674 }
675 } else {
676 markOop biased_value = mark;
677 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
678 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
679 if (res_mark == biased_value) {
680 return BIAS_REVOKED;
681 }
682 }
683 }
684 }
685
686 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
687 if (heuristics == HR_NOT_BIASED) {
688 return NOT_BIASED;
689 } else if (heuristics == HR_SINGLE_REVOKE) {
690 Klass *k = obj->klass();
691 markOop prototype_header = k->prototype_header();
692 if (mark->biased_locker() == THREAD &&
693 prototype_header->bias_epoch() == mark->bias_epoch()) {
694 // A thread is trying to revoke the bias of an object biased
695 // toward it, again likely due to an identity hash code
696 // computation. We can again avoid a safepoint in this case
697 // since we are only going to walk our own stack. There are no
698 // races with revocations occurring in other threads because we
699 // reach no safepoints in the revocation path.
700 // Also check the epoch because even if threads match, another thread
701 // can come in with a CAS to steal the bias of an object that has a
702 // stale epoch.
703 ResourceMark rm;
704 log_info(biasedlocking)("Revoking bias by walking my own stack:");
705 EventBiasedLockSelfRevocation event;
706 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
707 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
708 assert(cond == BIAS_REVOKED, "why not?");
709 if (event.should_commit()) {
710 post_self_revocation_event(&event, k);
711 }
712 return cond;
|
604 assert(event != NULL, "invariant");
605 assert(k != NULL, "invariant");
606 assert(revoke != NULL, "invariant");
607 assert(event->should_commit(), "invariant");
608 event->set_lockClass(k);
609 set_safepoint_id(event);
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
651 // by another thread so we simply return and let the caller deal
652 // with it.
653 markOop biased_value = mark;
654 markOop res_mark = obj->cas_set_mark(prototype_header, mark);
655 assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
656 return BiasedLocking::BIAS_REVOKED;
657 } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
658 // The epoch of this biasing has expired indicating that the
659 // object is effectively unbiased. Depending on whether we need
660 // to rebias or revoke the bias of this object we can do it
661 // efficiently enough with a CAS that we shouldn't update the
662 // heuristics. This is normally done in the assembly code but we
663 // can reach this point due to various points in the runtime
664 // needing to revoke biases.
665 if (attempt_rebias) {
666 markOop biased_value = mark;
667 markOop rebiased_prototype = markOopDesc::encode(thread, mark->age(), prototype_header->bias_epoch());
668 markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
669 if (res_mark == biased_value) {
670 return BiasedLocking::BIAS_REVOKED_AND_REBIASED;
671 }
672 } else {
673 markOop biased_value = mark;
674 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
675 markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
676 if (res_mark == biased_value) {
677 return BiasedLocking::BIAS_REVOKED;
678 }
679 }
680 }
681 }
682 return BiasedLocking::NOT_REVOKED;
683 }
684
685 BiasedLocking::Condition BiasedLocking::revoke_and_rebias_in_handshake(Handle obj, TRAPS) {
686 BiasedLocking::Condition bc = fast_revoke(obj, false);
687 if (bc != NOT_REVOKED) {
688 return bc;
689 }
690
691 markOop mark = obj->mark();
692 if (!mark->has_bias_pattern()) {
693 return NOT_BIASED;
694 }
695
696 Klass *k = obj->klass();
697 markOop prototype_header = k->prototype_header();
698 if (mark->biased_locker() == THREAD && prototype_header->bias_epoch() == mark->bias_epoch()) {
699 ResourceMark rm;
700 log_info(biasedlocking)("Revoking bias by walking my own stack:");
701 EventBiasedLockSelfRevocation event;
702 BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
703 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
704 assert(cond == BIAS_REVOKED, "why not?");
705 if (event.should_commit()) {
706 post_self_revocation_event(&event, k);
707 }
708 return cond;
709 }
710
711 ShouldNotReachHere();
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;
|