< prev index next >

src/share/vm/runtime/biasedLocking.cpp

Print this page
rev 9030 : 8223690: Add JFR BiasedLock Event Support

*** 29,38 **** --- 29,40 ---- #include "runtime/biasedLocking.hpp" #include "runtime/task.hpp" #include "runtime/vframe.hpp" #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp" + #include "jfr/support/jfrThreadId.hpp" + #include "jfr/jfrEvents.hpp" static bool _biased_locking_enabled = false; BiasedLockingCounters BiasedLocking::_counters; static GrowableArray<Handle>* _preserved_oop_stack = NULL;
*** 140,151 **** thread->set_cached_monitor_info(info); return info; } ! ! static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) { markOop mark = obj->mark(); if (!mark->has_bias_pattern()) { if (TraceBiasedLocking) { ResourceMark rm; tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)", --- 142,154 ---- thread->set_cached_monitor_info(info); return info; } ! // After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL, ! // AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization). ! static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) { markOop mark = obj->mark(); if (!mark->has_bias_pattern()) { if (TraceBiasedLocking) { ResourceMark rm; tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)",
*** 251,260 **** --- 254,268 ---- // Store the unlocked value into the object's header. obj->set_mark(unbiased_prototype); } } + // If requested, return information on which thread held the bias + if (biased_locker != NULL) { + *biased_locker = biased_thread; + } + return BiasedLocking::BIAS_REVOKED; } enum HeuristicsResult {
*** 371,381 **** } } // At this point we're done. All we have to do is potentially // adjust the header of the given object to revoke its bias. ! revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread); } else { if (TraceBiasedLocking) { ResourceMark rm; tty->print_cr("* Disabling biased locking for type %s", klass->external_name()); } --- 379,389 ---- } } // At this point we're done. All we have to do is potentially // adjust the header of the given object to revoke its bias. ! revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL); } else { if (TraceBiasedLocking) { ResourceMark rm; tty->print_cr("* Disabling biased locking for type %s", klass->external_name()); }
*** 393,410 **** for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); oop owner = mon_info->owner(); markOop mark = owner->mark(); if ((owner->klass() == k_o) && mark->has_bias_pattern()) { ! revoke_bias(owner, false, true, requesting_thread); } } } // Must force the bias of the passed object to be forcibly revoked // as well to ensure guarantees to callers ! revoke_bias(o, false, true, requesting_thread); } if (TraceBiasedLocking) { tty->print_cr("* Ending bulk revocation"); } --- 401,418 ---- for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); oop owner = mon_info->owner(); markOop mark = owner->mark(); if ((owner->klass() == k_o) && mark->has_bias_pattern()) { ! revoke_bias(owner, false, true, requesting_thread, NULL); } } } // Must force the bias of the passed object to be forcibly revoked // as well to ensure guarantees to callers ! revoke_bias(o, false, true, requesting_thread, NULL); } if (TraceBiasedLocking) { tty->print_cr("* Ending bulk revocation"); }
*** 443,465 **** protected: Handle* _obj; GrowableArray<Handle>* _objs; JavaThread* _requesting_thread; BiasedLocking::Condition _status_code; public: VM_RevokeBias(Handle* obj, JavaThread* requesting_thread) : _obj(obj) , _objs(NULL) , _requesting_thread(requesting_thread) ! , _status_code(BiasedLocking::NOT_BIASED) {} VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread) : _obj(NULL) , _objs(objs) , _requesting_thread(requesting_thread) ! , _status_code(BiasedLocking::NOT_BIASED) {} virtual VMOp_Type type() const { return VMOp_RevokeBias; } virtual bool doit_prologue() { // Verify that there is actual work to do since the callers just --- 451,476 ---- protected: Handle* _obj; GrowableArray<Handle>* _objs; JavaThread* _requesting_thread; BiasedLocking::Condition _status_code; + traceid _biased_locker_id; public: VM_RevokeBias(Handle* obj, JavaThread* requesting_thread) : _obj(obj) , _objs(NULL) , _requesting_thread(requesting_thread) ! , _status_code(BiasedLocking::NOT_BIASED) ! , _biased_locker_id(0) {} VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread) : _obj(NULL) , _objs(objs) , _requesting_thread(requesting_thread) ! , _status_code(BiasedLocking::NOT_BIASED) ! , _biased_locker_id(0) {} virtual VMOp_Type type() const { return VMOp_RevokeBias; } virtual bool doit_prologue() { // Verify that there is actual work to do since the callers just
*** 484,494 **** virtual void doit() { if (_obj != NULL) { if (TraceBiasedLocking) { tty->print_cr("Revoking bias with potentially per-thread safepoint:"); } ! _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread); clean_up_cached_monitor_info(); return; } else { if (TraceBiasedLocking) { tty->print_cr("Revoking bias with global safepoint:"); --- 495,509 ---- virtual void doit() { if (_obj != NULL) { if (TraceBiasedLocking) { tty->print_cr("Revoking bias with potentially per-thread safepoint:"); } ! JavaThread* biased_locker = NULL; ! _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker); ! if (biased_locker != NULL) { ! _biased_locker_id = JFR_THREAD_ID(biased_locker); ! } clean_up_cached_monitor_info(); return; } else { if (TraceBiasedLocking) { tty->print_cr("Revoking bias with global safepoint:");
*** 498,507 **** --- 513,526 ---- } BiasedLocking::Condition status_code() const { return _status_code; } + + traceid biased_locker() const { + return _biased_locker_id; + } }; class VM_BulkRevokeBias : public VM_RevokeBias { private:
*** 607,633 **** // stale epoch. ResourceMark rm; if (TraceBiasedLocking) { tty->print_cr("Revoking bias by walking my own stack:"); } ! BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD); ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); assert(cond == BIAS_REVOKED, "why not?"); return cond; } else { VM_RevokeBias revoke(&obj, (JavaThread*) THREAD); VMThread::execute(&revoke); return revoke.status_code(); } } assert((heuristics == HR_BULK_REVOKE) || (heuristics == HR_BULK_REBIAS), "?"); VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD, (heuristics == HR_BULK_REBIAS), attempt_rebias); VMThread::execute(&bulk_revoke); return bulk_revoke.status_code(); } void BiasedLocking::revoke(GrowableArray<Handle>* objs) { --- 626,673 ---- // stale epoch. ResourceMark rm; if (TraceBiasedLocking) { tty->print_cr("Revoking bias by walking my own stack:"); } ! EventBiasedLockSelfRevocation event; ! BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL); ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); assert(cond == BIAS_REVOKED, "why not?"); + if (event.should_commit()) { + event.set_lockClass(k); + event.commit(); + } return cond; } else { + EventBiasedLockRevocation event; VM_RevokeBias revoke(&obj, (JavaThread*) THREAD); VMThread::execute(&revoke); + if (event.should_commit() && (revoke.status_code() != NOT_BIASED)) { + event.set_lockClass(k); + // Subtract 1 to match the id of events committed inside the safepoint + event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1); + event.set_previousOwner(revoke.biased_locker()); + event.commit(); + } return revoke.status_code(); } } assert((heuristics == HR_BULK_REVOKE) || (heuristics == HR_BULK_REBIAS), "?"); + EventBiasedLockClassRevocation event; VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD, (heuristics == HR_BULK_REBIAS), attempt_rebias); VMThread::execute(&bulk_revoke); + if (event.should_commit()) { + event.set_revokedClass(obj->klass()); + event.set_disableBiasing((heuristics != HR_BULK_REBIAS)); + // Subtract 1 to match the id of events committed inside the safepoint + event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1); + event.commit(); + } return bulk_revoke.status_code(); } void BiasedLocking::revoke(GrowableArray<Handle>* objs) {
*** 643,653 **** void BiasedLocking::revoke_at_safepoint(Handle h_obj) { assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint"); oop obj = h_obj(); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { ! revoke_bias(obj, false, false, NULL); } else if ((heuristics == HR_BULK_REBIAS) || (heuristics == HR_BULK_REVOKE)) { bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); } clean_up_cached_monitor_info(); --- 683,693 ---- void BiasedLocking::revoke_at_safepoint(Handle h_obj) { assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint"); oop obj = h_obj(); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { ! revoke_bias(obj, false, false, NULL, NULL); } else if ((heuristics == HR_BULK_REBIAS) || (heuristics == HR_BULK_REVOKE)) { bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); } clean_up_cached_monitor_info();
*** 659,669 **** int len = objs->length(); for (int i = 0; i < len; i++) { oop obj = (objs->at(i))(); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { ! revoke_bias(obj, false, false, NULL); } else if ((heuristics == HR_BULK_REBIAS) || (heuristics == HR_BULK_REVOKE)) { bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); } } --- 699,709 ---- int len = objs->length(); for (int i = 0; i < len; i++) { oop obj = (objs->at(i))(); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { ! revoke_bias(obj, false, false, NULL, NULL); } else if ((heuristics == HR_BULK_REBIAS) || (heuristics == HR_BULK_REVOKE)) { bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); } }
< prev index next >