605 assert(op != NULL, "invariant");
606 assert(event->should_commit(), "invariant");
607 event->set_revokedClass(k);
608 event->set_disableBiasing(!op->is_bulk_rebias());
609 event->set_safepointId(op->safepoint_id());
610 event->commit();
611 }
612
613
614 BiasedLocking::Condition BiasedLocking::single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser) {
615
616 EventBiasedLockRevocation event;
617 if (PrintBiasedLockingStatistics) {
618 Atomic::inc(handshakes_count_addr());
619 }
620 log_info(biasedlocking, handshake)("JavaThread " INTPTR_FORMAT " handshaking JavaThread "
621 INTPTR_FORMAT " to revoke object " INTPTR_FORMAT, p2i(requester),
622 p2i(biaser), p2i(obj()));
623
624 RevokeOneBias revoke(obj, requester, biaser);
625 bool executed = Handshake::execute(&revoke, biaser);
626 if (revoke.status_code() == NOT_REVOKED) {
627 return NOT_REVOKED;
628 }
629 if (executed) {
630 log_info(biasedlocking, handshake)("Handshake revocation for object " INTPTR_FORMAT " succeeded. Bias was %srevoked",
631 p2i(obj()), (revoke.status_code() == BIAS_REVOKED ? "" : "already "));
632 if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
633 post_revocation_event(&event, obj->klass(), &revoke);
634 }
635 assert(!obj->mark().has_bias_pattern(), "invariant");
636 return revoke.status_code();
637 } else {
638 // Thread was not alive.
639 // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
640 // created JavaThread (that happens to get the same memory address as biaser) synchronizing
641 // on this object.
642 {
643 MutexLocker ml(Threads_lock);
644 markWord mark = obj->mark();
645 // Check if somebody else was able to revoke it before biased thread exited.
649 ThreadsListHandle tlh;
650 markWord prototype = obj->klass()->prototype_header();
651 if (!prototype.has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark.biased_locker() &&
652 prototype.bias_epoch() == mark.bias_epoch())) {
653 obj->cas_set_mark(markWord::prototype().set_age(mark.age()), mark);
654 if (event.should_commit()) {
655 post_revocation_event(&event, obj->klass(), &revoke);
656 }
657 assert(!obj->mark().has_bias_pattern(), "bias should be revoked by now");
658 return BIAS_REVOKED;
659 }
660 }
661 }
662
663 return NOT_REVOKED;
664 }
665
666
667 // Caller should have instantiated a ResourceMark object before calling this method
668 void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
669 assert(!SafepointSynchronize::is_at_safepoint(), "this should always be executed outside safepoints");
670 assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
671
672 markWord mark = obj->mark();
673 assert(mark.biased_locker() == biased_locker &&
674 obj->klass()->prototype_header().bias_epoch() == mark.bias_epoch(), "invariant");
675
676 log_trace(biasedlocking)("%s(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
677 INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
678 ", biaser " INTPTR_FORMAT " %s",
679 Thread::current()->is_VM_thread() ? "VMThread" : "JavaThread",
680 p2i(Thread::current()),
681 p2i(obj),
682 mark.value(),
683 obj->klass()->external_name(),
684 obj->klass()->prototype_header().value(),
685 p2i(biased_locker),
686 Thread::current()->is_VM_thread() ? "" : "(walking own stack)");
687
688 markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
689
690 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
691 BasicLock* highest_lock = NULL;
692 for (int i = 0; i < cached_monitor_info->length(); i++) {
693 MonitorInfo* mon_info = cached_monitor_info->at(i);
694 if (mon_info->owner() == obj) {
695 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
696 p2i(mon_info->owner()),
697 p2i(obj));
698 // Assume recursive case and fix up highest lock below
699 markWord mark = markWord::encode((BasicLock*) NULL);
700 highest_lock = mon_info->lock();
701 highest_lock->set_displaced_header(mark);
702 } else {
703 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
704 p2i(mon_info->owner()),
705 p2i(obj));
706 }
|
605 assert(op != NULL, "invariant");
606 assert(event->should_commit(), "invariant");
607 event->set_revokedClass(k);
608 event->set_disableBiasing(!op->is_bulk_rebias());
609 event->set_safepointId(op->safepoint_id());
610 event->commit();
611 }
612
613
614 BiasedLocking::Condition BiasedLocking::single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser) {
615
616 EventBiasedLockRevocation event;
617 if (PrintBiasedLockingStatistics) {
618 Atomic::inc(handshakes_count_addr());
619 }
620 log_info(biasedlocking, handshake)("JavaThread " INTPTR_FORMAT " handshaking JavaThread "
621 INTPTR_FORMAT " to revoke object " INTPTR_FORMAT, p2i(requester),
622 p2i(biaser), p2i(obj()));
623
624 RevokeOneBias revoke(obj, requester, biaser);
625 bool executed = Handshake::execute_direct(&revoke, biaser);
626 if (revoke.status_code() == NOT_REVOKED) {
627 return NOT_REVOKED;
628 }
629 if (executed) {
630 log_info(biasedlocking, handshake)("Handshake revocation for object " INTPTR_FORMAT " succeeded. Bias was %srevoked",
631 p2i(obj()), (revoke.status_code() == BIAS_REVOKED ? "" : "already "));
632 if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
633 post_revocation_event(&event, obj->klass(), &revoke);
634 }
635 assert(!obj->mark().has_bias_pattern(), "invariant");
636 return revoke.status_code();
637 } else {
638 // Thread was not alive.
639 // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
640 // created JavaThread (that happens to get the same memory address as biaser) synchronizing
641 // on this object.
642 {
643 MutexLocker ml(Threads_lock);
644 markWord mark = obj->mark();
645 // Check if somebody else was able to revoke it before biased thread exited.
649 ThreadsListHandle tlh;
650 markWord prototype = obj->klass()->prototype_header();
651 if (!prototype.has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark.biased_locker() &&
652 prototype.bias_epoch() == mark.bias_epoch())) {
653 obj->cas_set_mark(markWord::prototype().set_age(mark.age()), mark);
654 if (event.should_commit()) {
655 post_revocation_event(&event, obj->klass(), &revoke);
656 }
657 assert(!obj->mark().has_bias_pattern(), "bias should be revoked by now");
658 return BIAS_REVOKED;
659 }
660 }
661 }
662
663 return NOT_REVOKED;
664 }
665
666
667 // Caller should have instantiated a ResourceMark object before calling this method
668 void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
669 Thread* cur = Thread::current();
670 assert(!SafepointSynchronize::is_at_safepoint(), "this should always be executed outside safepoints");
671 assert(cur == biased_locker || cur == biased_locker->active_handshaker(), "wrong thread");
672
673 markWord mark = obj->mark();
674 assert(mark.biased_locker() == biased_locker &&
675 obj->klass()->prototype_header().bias_epoch() == mark.bias_epoch(), "invariant");
676
677 log_trace(biasedlocking)("JavaThread(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
678 INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
679 ", biaser " INTPTR_FORMAT " %s",
680 p2i(cur),
681 p2i(obj),
682 mark.value(),
683 obj->klass()->external_name(),
684 obj->klass()->prototype_header().value(),
685 p2i(biased_locker),
686 cur != biased_locker ? "" : "(walking own stack)");
687
688 markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
689
690 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
691 BasicLock* highest_lock = NULL;
692 for (int i = 0; i < cached_monitor_info->length(); i++) {
693 MonitorInfo* mon_info = cached_monitor_info->at(i);
694 if (mon_info->owner() == obj) {
695 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
696 p2i(mon_info->owner()),
697 p2i(obj));
698 // Assume recursive case and fix up highest lock below
699 markWord mark = markWord::encode((BasicLock*) NULL);
700 highest_lock = mon_info->lock();
701 highest_lock->set_displaced_header(mark);
702 } else {
703 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
704 p2i(mon_info->owner()),
705 p2i(obj));
706 }
|