28 #include "jfr/support/jfrThreadId.hpp"
29 #include "logging/log.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "oops/klass.inline.hpp"
32 #include "oops/markOop.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/atomic.hpp"
35 #include "runtime/basicLock.hpp"
36 #include "runtime/biasedLocking.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/task.hpp"
39 #include "runtime/threadSMR.hpp"
40 #include "runtime/vframe.hpp"
41 #include "runtime/vmThread.hpp"
42 #include "runtime/vmOperations.hpp"
43
44
45 static bool _biased_locking_enabled = false;
46 BiasedLockingCounters BiasedLocking::_counters;
47
48 static GrowableArray<Handle>* _preserved_oop_stack = NULL;
49 static GrowableArray<markWord>* _preserved_mark_stack = NULL;
50
51 static void enable_biased_locking(InstanceKlass* k) {
52 k->set_prototype_header(markWord::biased_locking_prototype());
53 }
54
55 static void enable_biased_locking() {
56 _biased_locking_enabled = true;
57 log_info(biasedlocking)("Biased locking enabled");
58 }
59
60 class VM_EnableBiasedLocking: public VM_Operation {
61 public:
62 VM_EnableBiasedLocking() {}
63 VMOp_Type type() const { return VMOp_EnableBiasedLocking; }
64 Mode evaluation_mode() const { return _async_safepoint; }
65 bool is_cheap_allocated() const { return true; }
66
67 void doit() {
68 // Iterate the class loader data dictionaries enabling biased locking for all
461 if ((owner->klass() == k_o) && mark.has_bias_pattern()) {
462 single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL);
463 }
464 }
465 }
466
467 // Must force the bias of the passed object to be forcibly revoked
468 // as well to ensure guarantees to callers
469 single_revoke_at_safepoint(o, false, true, requesting_thread, NULL);
470 }
471 } // ThreadsListHandle is destroyed here.
472
473 log_info(biasedlocking)("* Ending bulk revocation");
474
475 BiasedLocking::Condition status_code = BIAS_REVOKED;
476
477 if (attempt_rebias_of_object &&
478 o->mark().has_bias_pattern() &&
479 klass->prototype_header().has_bias_pattern()) {
480 markWord new_mark = markWord::encode(requesting_thread, o->mark().age(),
481 klass->prototype_header().bias_epoch());
482 o->set_mark(new_mark);
483 status_code = BIAS_REVOKED_AND_REBIASED;
484 log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
485 }
486
487 assert(!o->mark().has_bias_pattern() ||
488 (attempt_rebias_of_object && (o->mark().biased_locker() == requesting_thread)),
489 "bug in bulk bias revocation");
490
491 return status_code;
492 }
493
494
495 static void clean_up_cached_monitor_info(JavaThread* thread = NULL) {
496 if (thread != NULL) {
497 thread->set_cached_monitor_info(NULL);
498 } else {
499 // Walk the thread list clearing out the cached monitors
500 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
501 thr->set_cached_monitor_info(NULL);
675 if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
676 post_revocation_event(&event, obj->klass(), &revoke);
677 }
678 assert(!obj->mark().has_bias_pattern(), "invariant");
679 return revoke.status_code();
680 } else {
681 // Thread was not alive.
682 // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
683 // created JavaThread (that happens to get the same memory address as biaser) synchronizing
684 // on this object.
685 {
686 MutexLocker ml(Threads_lock);
687 markWord mark = obj->mark();
688 // Check if somebody else was able to revoke it before biased thread exited.
689 if (!mark.has_bias_pattern()) {
690 return NOT_BIASED;
691 }
692 ThreadsListHandle tlh;
693 markWord prototype = obj->klass()->prototype_header();
694 if (!prototype.has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark.biased_locker() &&
695 prototype.bias_epoch() == mark.bias_epoch())) {
696 obj->cas_set_mark(markWord::prototype().set_age(mark.age()), mark);
697 if (event.should_commit()) {
698 post_revocation_event(&event, obj->klass(), &revoke);
699 }
700 assert(!obj->mark().has_bias_pattern(), "bias should be revoked by now");
701 return BIAS_REVOKED;
702 }
703 }
704 }
705
706 return NOT_REVOKED;
707 }
708
709
710 // Caller should have instantiated a ResourceMark object before calling this method
711 void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
712 assert(!SafepointSynchronize::is_at_safepoint() || !ThreadLocalHandshakes,
713 "if ThreadLocalHandshakes is enabled this should always be executed outside safepoints");
714 assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
715
796 Klass* k = obj->klass();
797 markWord prototype_header = k->prototype_header();
798 if (!prototype_header.has_bias_pattern()) {
799 // This object has a stale bias from before the bulk revocation
800 // for this data type occurred. It's pointless to update the
801 // heuristics at this point so simply update the header with a
802 // CAS. If we fail this race, the object's bias has been revoked
803 // by another thread so we simply return and let the caller deal
804 // with it.
805 obj->cas_set_mark(prototype_header.set_age(mark.age()), mark);
806 assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked");
807 return BIAS_REVOKED;
808 } else if (prototype_header.bias_epoch() != mark.bias_epoch()) {
809 // The epoch of this biasing has expired indicating that the
810 // object is effectively unbiased. Depending on whether we need
811 // to rebias or revoke the bias of this object we can do it
812 // efficiently enough with a CAS that we shouldn't update the
813 // heuristics. This is normally done in the assembly code but we
814 // can reach this point due to various points in the runtime
815 // needing to revoke biases.
816 markWord res_mark(0);
817 if (attempt_rebias) {
818 assert(THREAD->is_Java_thread(), "");
819 markWord biased_value = mark;
820 markWord rebiased_prototype = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
821 res_mark = obj->cas_set_mark(rebiased_prototype, mark);
822 if (res_mark == biased_value) {
823 return BIAS_REVOKED_AND_REBIASED;
824 }
825 } else {
826 markWord biased_value = mark;
827 markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
828 res_mark = obj->cas_set_mark(unbiased_prototype, mark);
829 if (res_mark == biased_value) {
830 return BIAS_REVOKED;
831 }
832 }
833 mark = res_mark; // Refresh mark with the latest value.
834 }
835 }
836
|
28 #include "jfr/support/jfrThreadId.hpp"
29 #include "logging/log.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "oops/klass.inline.hpp"
32 #include "oops/markOop.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/atomic.hpp"
35 #include "runtime/basicLock.hpp"
36 #include "runtime/biasedLocking.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/task.hpp"
39 #include "runtime/threadSMR.hpp"
40 #include "runtime/vframe.hpp"
41 #include "runtime/vmThread.hpp"
42 #include "runtime/vmOperations.hpp"
43
44
45 static bool _biased_locking_enabled = false;
46 BiasedLockingCounters BiasedLocking::_counters;
47
48 static GrowableArray<Handle>* _preserved_oop_stack = NULL;
49 static GrowableArray<markWord>* _preserved_mark_stack = NULL;
50
51 static void enable_biased_locking(InstanceKlass* k) {
52 k->set_prototype_header(markWord::biased_locking_prototype());
53 }
54
55 static void enable_biased_locking() {
56 _biased_locking_enabled = true;
57 log_info(biasedlocking)("Biased locking enabled");
58 }
59
60 class VM_EnableBiasedLocking: public VM_Operation {
61 public:
62 VM_EnableBiasedLocking() {}
63 VMOp_Type type() const { return VMOp_EnableBiasedLocking; }
64 Mode evaluation_mode() const { return _async_safepoint; }
65 bool is_cheap_allocated() const { return true; }
66
67 void doit() {
68 // Iterate the class loader data dictionaries enabling biased locking for all
461 if ((owner->klass() == k_o) && mark.has_bias_pattern()) {
462 single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL);
463 }
464 }
465 }
466
467 // Must force the bias of the passed object to be forcibly revoked
468 // as well to ensure guarantees to callers
469 single_revoke_at_safepoint(o, false, true, requesting_thread, NULL);
470 }
471 } // ThreadsListHandle is destroyed here.
472
473 log_info(biasedlocking)("* Ending bulk revocation");
474
475 BiasedLocking::Condition status_code = BIAS_REVOKED;
476
477 if (attempt_rebias_of_object &&
478 o->mark().has_bias_pattern() &&
479 klass->prototype_header().has_bias_pattern()) {
480 markWord new_mark = markWord::encode(requesting_thread, o->mark().age(),
481 klass->prototype_header().bias_epoch());
482 o->set_mark(new_mark);
483 status_code = BIAS_REVOKED_AND_REBIASED;
484 log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
485 }
486
487 assert(!o->mark().has_bias_pattern() ||
488 (attempt_rebias_of_object && (o->mark().biased_locker() == requesting_thread)),
489 "bug in bulk bias revocation");
490
491 return status_code;
492 }
493
494
495 static void clean_up_cached_monitor_info(JavaThread* thread = NULL) {
496 if (thread != NULL) {
497 thread->set_cached_monitor_info(NULL);
498 } else {
499 // Walk the thread list clearing out the cached monitors
500 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
501 thr->set_cached_monitor_info(NULL);
675 if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
676 post_revocation_event(&event, obj->klass(), &revoke);
677 }
678 assert(!obj->mark().has_bias_pattern(), "invariant");
679 return revoke.status_code();
680 } else {
681 // Thread was not alive.
682 // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
683 // created JavaThread (that happens to get the same memory address as biaser) synchronizing
684 // on this object.
685 {
686 MutexLocker ml(Threads_lock);
687 markWord mark = obj->mark();
688 // Check if somebody else was able to revoke it before biased thread exited.
689 if (!mark.has_bias_pattern()) {
690 return NOT_BIASED;
691 }
692 ThreadsListHandle tlh;
693 markWord prototype = obj->klass()->prototype_header();
694 if (!prototype.has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark.biased_locker() &&
695 prototype.bias_epoch() == mark.bias_epoch())) {
696 obj->cas_set_mark(markWord::prototype().set_age(mark.age()), mark);
697 if (event.should_commit()) {
698 post_revocation_event(&event, obj->klass(), &revoke);
699 }
700 assert(!obj->mark().has_bias_pattern(), "bias should be revoked by now");
701 return BIAS_REVOKED;
702 }
703 }
704 }
705
706 return NOT_REVOKED;
707 }
708
709
710 // Caller should have instantiated a ResourceMark object before calling this method
711 void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
712 assert(!SafepointSynchronize::is_at_safepoint() || !ThreadLocalHandshakes,
713 "if ThreadLocalHandshakes is enabled this should always be executed outside safepoints");
714 assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
715
796 Klass* k = obj->klass();
797 markWord prototype_header = k->prototype_header();
798 if (!prototype_header.has_bias_pattern()) {
799 // This object has a stale bias from before the bulk revocation
800 // for this data type occurred. It's pointless to update the
801 // heuristics at this point so simply update the header with a
802 // CAS. If we fail this race, the object's bias has been revoked
803 // by another thread so we simply return and let the caller deal
804 // with it.
805 obj->cas_set_mark(prototype_header.set_age(mark.age()), mark);
806 assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked");
807 return BIAS_REVOKED;
808 } else if (prototype_header.bias_epoch() != mark.bias_epoch()) {
809 // The epoch of this biasing has expired indicating that the
810 // object is effectively unbiased. Depending on whether we need
811 // to rebias or revoke the bias of this object we can do it
812 // efficiently enough with a CAS that we shouldn't update the
813 // heuristics. This is normally done in the assembly code but we
814 // can reach this point due to various points in the runtime
815 // needing to revoke biases.
816 markWord res_mark;
817 if (attempt_rebias) {
818 assert(THREAD->is_Java_thread(), "");
819 markWord biased_value = mark;
820 markWord rebiased_prototype = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
821 res_mark = obj->cas_set_mark(rebiased_prototype, mark);
822 if (res_mark == biased_value) {
823 return BIAS_REVOKED_AND_REBIASED;
824 }
825 } else {
826 markWord biased_value = mark;
827 markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
828 res_mark = obj->cas_set_mark(unbiased_prototype, mark);
829 if (res_mark == biased_value) {
830 return BIAS_REVOKED;
831 }
832 }
833 mark = res_mark; // Refresh mark with the latest value.
834 }
835 }
836
|