1 /*
2 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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.
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() || !SafepointMechanism::uses_thread_local_poll(),
670 "if SafepointMechanism::uses_thread_local_poll() is enabled this should always be executed outside safepoints");
671 assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "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)("%s(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
678 INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
679 ", biaser " INTPTR_FORMAT " %s",
680 Thread::current()->is_VM_thread() ? "VMThread" : "JavaThread",
681 p2i(Thread::current()),
682 p2i(obj),
683 mark.value(),
684 obj->klass()->external_name(),
685 obj->klass()->prototype_header().value(),
686 p2i(biased_locker),
687 Thread::current()->is_VM_thread() ? "" : "(walking own stack)");
688
689 markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
690
691 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
692 BasicLock* highest_lock = NULL;
693 for (int i = 0; i < cached_monitor_info->length(); i++) {
694 MonitorInfo* mon_info = cached_monitor_info->at(i);
695 if (mon_info->owner() == obj) {
696 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
697 p2i(mon_info->owner()),
698 p2i(obj));
699 // Assume recursive case and fix up highest lock below
700 markWord mark = markWord::encode((BasicLock*) NULL);
701 highest_lock = mon_info->lock();
702 highest_lock->set_displaced_header(mark);
703 } else {
704 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
705 p2i(mon_info->owner()),
706 p2i(obj));
707 }
|
1 /*
2 * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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.
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() || !SafepointMechanism::uses_thread_local_poll(),
670 "if SafepointMechanism::uses_thread_local_poll() is enabled this should always be executed outside safepoints");
671 Thread* cur = Thread::current();
672 assert(cur == biased_locker || cur == biased_locker->get_active_handshaker() || cur->is_VM_thread(), "wrong thread");
673
674 markWord mark = obj->mark();
675 assert(mark.biased_locker() == biased_locker &&
676 obj->klass()->prototype_header().bias_epoch() == mark.bias_epoch(), "invariant");
677
678 log_trace(biasedlocking)("%s(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
679 INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
680 ", biaser " INTPTR_FORMAT " %s",
681 cur->is_VM_thread() ? "VMThread" : "JavaThread",
682 p2i(cur),
683 p2i(obj),
684 mark.value(),
685 obj->klass()->external_name(),
686 obj->klass()->prototype_header().value(),
687 p2i(biased_locker),
688 cur->is_VM_thread() ? "" : "(walking own stack)");
689
690 markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
691
692 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
693 BasicLock* highest_lock = NULL;
694 for (int i = 0; i < cached_monitor_info->length(); i++) {
695 MonitorInfo* mon_info = cached_monitor_info->at(i);
696 if (mon_info->owner() == obj) {
697 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
698 p2i(mon_info->owner()),
699 p2i(obj));
700 // Assume recursive case and fix up highest lock below
701 markWord mark = markWord::encode((BasicLock*) NULL);
702 highest_lock = mon_info->lock();
703 highest_lock->set_displaced_header(mark);
704 } else {
705 log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
706 p2i(mon_info->owner()),
707 p2i(obj));
708 }
|