src/share/vm/runtime/biasedLocking.cpp

changeset 9931
fd44df5e3bc3
parent 6876
710a3c8b516e
parent 9895
c439931136f1
     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);

mercurial