< prev index next >
src/share/vm/runtime/biasedLocking.cpp
Print this page
rev 8910 : full patch for jfr
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -29,10 +29,11 @@
#include "runtime/biasedLocking.hpp"
#include "runtime/task.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
+#include "trace/tracing.hpp"
static bool _biased_locking_enabled = false;
BiasedLockingCounters BiasedLocking::_counters;
static GrowableArray<Handle>* _preserved_oop_stack = NULL;
@@ -141,11 +142,11 @@
thread->set_cached_monitor_info(info);
return info;
}
-static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
+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,10 +252,15 @@
// 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 (EnableJFR && biased_locker != NULL) {
+ *biased_locker = biased_thread;
+ }
+
return BiasedLocking::BIAS_REVOKED;
}
enum HeuristicsResult {
@@ -371,11 +377,11 @@
}
}
// 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);
+ 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,18 +399,18 @@
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);
+ 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);
+ revoke_bias(o, false, true, requesting_thread, NULL);
}
if (TraceBiasedLocking) {
tty->print_cr("* Ending bulk revocation");
}
@@ -443,23 +449,26 @@
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) {}
+ , _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) {}
+ , _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,11 +493,15 @@
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);
+ JavaThread* biased_locker = NULL;
+ _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker);
+ if (biased_locker != NULL) {
+ _biased_locker_id = THREAD_TRACE_ID(biased_locker);
+ }
clean_up_cached_monitor_info();
return;
} else {
if (TraceBiasedLocking) {
tty->print_cr("Revoking bias with global safepoint:");
@@ -498,10 +511,14 @@
}
BiasedLocking::Condition status_code() const {
return _status_code;
}
+
+ traceid biased_locker() const {
+ return _biased_locker_id;
+ }
};
class VM_BulkRevokeBias : public VM_RevokeBias {
private:
@@ -607,27 +624,48 @@
// 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);
+ 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,11 +681,11 @@
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);
+ 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,11 +697,11 @@
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);
+ 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 >