1.1 --- a/src/share/vm/runtime/biasedLocking.cpp Wed Oct 14 16:43:13 2020 +0800 1.2 +++ b/src/share/vm/runtime/biasedLocking.cpp Wed Oct 14 17:44:48 2020 +0800 1.3 @@ -31,6 +31,8 @@ 1.4 #include "runtime/vframe.hpp" 1.5 #include "runtime/vmThread.hpp" 1.6 #include "runtime/vm_operations.hpp" 1.7 +#include "jfr/support/jfrThreadId.hpp" 1.8 +#include "jfr/jfrEvents.hpp" 1.9 1.10 static bool _biased_locking_enabled = false; 1.11 BiasedLockingCounters BiasedLocking::_counters; 1.12 @@ -142,8 +144,9 @@ 1.13 return info; 1.14 } 1.15 1.16 - 1.17 -static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) { 1.18 +// After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL, 1.19 +// AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization). 1.20 +static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) { 1.21 markOop mark = obj->mark(); 1.22 if (!mark->has_bias_pattern()) { 1.23 if (TraceBiasedLocking) { 1.24 @@ -253,6 +256,13 @@ 1.25 } 1.26 } 1.27 1.28 +#if INCLUDE_JFR 1.29 + // If requested, return information on which thread held the bias 1.30 + if (biased_locker != NULL) { 1.31 + *biased_locker = biased_thread; 1.32 + } 1.33 +#endif // INCLUDE_JFR 1.34 + 1.35 return BiasedLocking::BIAS_REVOKED; 1.36 } 1.37 1.38 @@ -373,7 +383,7 @@ 1.39 1.40 // At this point we're done. All we have to do is potentially 1.41 // adjust the header of the given object to revoke its bias. 1.42 - revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread); 1.43 + revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL); 1.44 } else { 1.45 if (TraceBiasedLocking) { 1.46 ResourceMark rm; 1.47 @@ -395,14 +405,14 @@ 1.48 oop owner = mon_info->owner(); 1.49 markOop mark = owner->mark(); 1.50 if ((owner->klass() == k_o) && mark->has_bias_pattern()) { 1.51 - revoke_bias(owner, false, true, requesting_thread); 1.52 + revoke_bias(owner, false, true, requesting_thread, NULL); 1.53 } 1.54 } 1.55 } 1.56 1.57 // Must force the bias of the passed object to be forcibly revoked 1.58 // as well to ensure guarantees to callers 1.59 - revoke_bias(o, false, true, requesting_thread); 1.60 + revoke_bias(o, false, true, requesting_thread, NULL); 1.61 } 1.62 1.63 if (TraceBiasedLocking) { 1.64 @@ -445,19 +455,22 @@ 1.65 GrowableArray<Handle>* _objs; 1.66 JavaThread* _requesting_thread; 1.67 BiasedLocking::Condition _status_code; 1.68 + traceid _biased_locker_id; 1.69 1.70 public: 1.71 VM_RevokeBias(Handle* obj, JavaThread* requesting_thread) 1.72 : _obj(obj) 1.73 , _objs(NULL) 1.74 , _requesting_thread(requesting_thread) 1.75 - , _status_code(BiasedLocking::NOT_BIASED) {} 1.76 + , _status_code(BiasedLocking::NOT_BIASED) 1.77 + , _biased_locker_id(0) {} 1.78 1.79 VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread) 1.80 : _obj(NULL) 1.81 , _objs(objs) 1.82 , _requesting_thread(requesting_thread) 1.83 - , _status_code(BiasedLocking::NOT_BIASED) {} 1.84 + , _status_code(BiasedLocking::NOT_BIASED) 1.85 + , _biased_locker_id(0) {} 1.86 1.87 virtual VMOp_Type type() const { return VMOp_RevokeBias; } 1.88 1.89 @@ -486,7 +499,15 @@ 1.90 if (TraceBiasedLocking) { 1.91 tty->print_cr("Revoking bias with potentially per-thread safepoint:"); 1.92 } 1.93 - _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread); 1.94 + 1.95 + JavaThread* biased_locker = NULL; 1.96 + _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker); 1.97 +#if INCLUDE_JFR 1.98 + if (biased_locker != NULL) { 1.99 + _biased_locker_id = JFR_THREAD_ID(biased_locker); 1.100 + } 1.101 +#endif // INCLUDE_JFR 1.102 + 1.103 clean_up_cached_monitor_info(); 1.104 return; 1.105 } else { 1.106 @@ -500,6 +521,10 @@ 1.107 BiasedLocking::Condition status_code() const { 1.108 return _status_code; 1.109 } 1.110 + 1.111 + traceid biased_locker() const { 1.112 + return _biased_locker_id; 1.113 + } 1.114 }; 1.115 1.116 1.117 @@ -609,23 +634,44 @@ 1.118 if (TraceBiasedLocking) { 1.119 tty->print_cr("Revoking bias by walking my own stack:"); 1.120 } 1.121 - BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD); 1.122 + EventBiasedLockSelfRevocation event; 1.123 + BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL); 1.124 ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); 1.125 assert(cond == BIAS_REVOKED, "why not?"); 1.126 + if (event.should_commit()) { 1.127 + event.set_lockClass(k); 1.128 + event.commit(); 1.129 + } 1.130 return cond; 1.131 } else { 1.132 + EventBiasedLockRevocation event; 1.133 VM_RevokeBias revoke(&obj, (JavaThread*) THREAD); 1.134 VMThread::execute(&revoke); 1.135 + if (event.should_commit() && (revoke.status_code() != NOT_BIASED)) { 1.136 + event.set_lockClass(k); 1.137 + // Subtract 1 to match the id of events committed inside the safepoint 1.138 + event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1); 1.139 + event.set_previousOwner(revoke.biased_locker()); 1.140 + event.commit(); 1.141 + } 1.142 return revoke.status_code(); 1.143 } 1.144 } 1.145 1.146 assert((heuristics == HR_BULK_REVOKE) || 1.147 (heuristics == HR_BULK_REBIAS), "?"); 1.148 + EventBiasedLockClassRevocation event; 1.149 VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD, 1.150 (heuristics == HR_BULK_REBIAS), 1.151 attempt_rebias); 1.152 VMThread::execute(&bulk_revoke); 1.153 + if (event.should_commit()) { 1.154 + event.set_revokedClass(obj->klass()); 1.155 + event.set_disableBiasing((heuristics != HR_BULK_REBIAS)); 1.156 + // Subtract 1 to match the id of events committed inside the safepoint 1.157 + event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1); 1.158 + event.commit(); 1.159 + } 1.160 return bulk_revoke.status_code(); 1.161 } 1.162 1.163 @@ -645,7 +691,7 @@ 1.164 oop obj = h_obj(); 1.165 HeuristicsResult heuristics = update_heuristics(obj, false); 1.166 if (heuristics == HR_SINGLE_REVOKE) { 1.167 - revoke_bias(obj, false, false, NULL); 1.168 + revoke_bias(obj, false, false, NULL, NULL); 1.169 } else if ((heuristics == HR_BULK_REBIAS) || 1.170 (heuristics == HR_BULK_REVOKE)) { 1.171 bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); 1.172 @@ -661,7 +707,7 @@ 1.173 oop obj = (objs->at(i))(); 1.174 HeuristicsResult heuristics = update_heuristics(obj, false); 1.175 if (heuristics == HR_SINGLE_REVOKE) { 1.176 - revoke_bias(obj, false, false, NULL); 1.177 + revoke_bias(obj, false, false, NULL, NULL); 1.178 } else if ((heuristics == HR_BULK_REBIAS) || 1.179 (heuristics == HR_BULK_REVOKE)) { 1.180 bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);