src/share/vm/runtime/biasedLocking.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
8149383.02 Cdiff src/share/vm/runtime/biasedLocking.cpp
src/share/vm/runtime/biasedLocking.cpp
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2005, 2015, 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.
--- 1,7 ----
/*
! * Copyright (c) 2005, 2016, 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.
*** 21,30 ****
--- 21,32 ----
* questions.
*
*/
#include "precompiled.hpp"
+ #include "logging/log.hpp"
+ #include "memory/resourceArea.hpp"
#include "oops/klass.inline.hpp"
#include "oops/markOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/basicLock.hpp"
*** 58,70 ****
// currently loaded classes
SystemDictionary::classes_do(enable_biased_locking);
// Indicate that future instances should enable it as well
_biased_locking_enabled = true;
! if (TraceBiasedLocking) {
! tty->print_cr("Biased locking enabled");
! }
}
bool allow_nested_vm_operations() const { return false; }
};
--- 60,70 ----
// currently loaded classes
SystemDictionary::classes_do(enable_biased_locking);
// Indicate that future instances should enable it as well
_biased_locking_enabled = true;
! log_info(biasedlocking)("Biased locking enabled");
}
bool allow_nested_vm_operations() const { return false; }
};
*** 142,183 ****
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)",
obj->klass()->external_name());
}
return BiasedLocking::NOT_BIASED;
}
uint age = mark->age();
markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
! if (TraceBiasedLocking && (Verbose || !is_bulk)) {
ResourceMark rm;
! tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
! p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
}
JavaThread* biased_thread = mark->biased_locker();
if (biased_thread == NULL) {
// Object is anonymously biased. We can get here if, for
// example, we revoke the bias due to an identity hash code
// being computed for an object.
if (!allow_rebias) {
obj->set_mark(unbiased_prototype);
}
! if (TraceBiasedLocking && (Verbose || !is_bulk)) {
! tty->print_cr(" Revoked bias of anonymously-biased object");
}
return BiasedLocking::BIAS_REVOKED;
}
// Handle case where the thread toward which the object was biased has exited
--- 142,204 ----
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 (log_is_enabled(Info, biasedlocking)) {
ResourceMark rm;
! log_info(biasedlocking)(" (Skipping revocation of object of type %s "
! "because it's no longer biased)",
obj->klass()->external_name());
}
return BiasedLocking::NOT_BIASED;
}
uint age = mark->age();
markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
! // Log at "info" level if not bulk, else "trace" level
! if (!is_bulk) {
! ResourceMark rm;
! log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
! INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
! " , allow rebias %d , requesting thread " INTPTR_FORMAT,
! p2i((void *)obj),
! (intptr_t) mark,
! obj->klass()->external_name(),
! (intptr_t) obj->klass()->prototype_header(),
! (allow_rebias ? 1 : 0),
! (intptr_t) requesting_thread);
! } else {
ResourceMark rm;
! log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
! INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
! " , allow rebias %d , requesting thread " INTPTR_FORMAT,
! p2i((void *)obj),
! (intptr_t) mark,
! obj->klass()->external_name(),
! (intptr_t) obj->klass()->prototype_header(),
! (allow_rebias ? 1 : 0),
! (intptr_t) requesting_thread);
}
JavaThread* biased_thread = mark->biased_locker();
if (biased_thread == NULL) {
// Object is anonymously biased. We can get here if, for
// example, we revoke the bias due to an identity hash code
// being computed for an object.
if (!allow_rebias) {
obj->set_mark(unbiased_prototype);
}
! if (!is_bulk) {
! log_info(biasedlocking)(" Revoked bias of anonymously-biased object");
! } else {
! log_trace(biasedlocking)(" Revoked bias of anonymously-biased object");
}
return BiasedLocking::BIAS_REVOKED;
}
// Handle case where the thread toward which the object was biased has exited
*** 196,207 ****
if (allow_rebias) {
obj->set_mark(biased_prototype);
} else {
obj->set_mark(unbiased_prototype);
}
! if (TraceBiasedLocking && (Verbose || !is_bulk)) {
! tty->print_cr(" Revoked bias of object biased toward dead thread");
}
return BiasedLocking::BIAS_REVOKED;
}
// Thread owning bias is alive.
--- 217,231 ----
if (allow_rebias) {
obj->set_mark(biased_prototype);
} else {
obj->set_mark(unbiased_prototype);
}
! // Log at "info" level if not bulk, else "trace" level
! if (!is_bulk) {
! log_info(biasedlocking)(" Revoked bias of object biased toward dead thread");
! } else {
! log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread");
}
return BiasedLocking::BIAS_REVOKED;
}
// Thread owning bias is alive.
*** 212,253 ****
GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
BasicLock* highest_lock = NULL;
for (int i = 0; i < cached_monitor_info->length(); i++) {
MonitorInfo* mon_info = cached_monitor_info->at(i);
if (mon_info->owner() == obj) {
! if (TraceBiasedLocking && Verbose) {
! tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
- }
// Assume recursive case and fix up highest lock later
markOop mark = markOopDesc::encode((BasicLock*) NULL);
highest_lock = mon_info->lock();
highest_lock->set_displaced_header(mark);
} else {
! if (TraceBiasedLocking && Verbose) {
! tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
}
}
- }
if (highest_lock != NULL) {
// Fix up highest lock to contain displaced header and point
// object at it
highest_lock->set_displaced_header(unbiased_prototype);
// Reset object header to point to displaced mark.
// Must release storing the lock address for platforms without TSO
// ordering (e.g. ppc).
obj->release_set_mark(markOopDesc::encode(highest_lock));
assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
! if (TraceBiasedLocking && (Verbose || !is_bulk)) {
! tty->print_cr(" Revoked bias of currently-locked object");
}
} else {
! if (TraceBiasedLocking && (Verbose || !is_bulk)) {
! tty->print_cr(" Revoked bias of currently-unlocked object");
}
if (allow_rebias) {
obj->set_mark(biased_prototype);
} else {
// Store the unlocked value into the object's header.
--- 236,279 ----
GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
BasicLock* highest_lock = NULL;
for (int i = 0; i < cached_monitor_info->length(); i++) {
MonitorInfo* mon_info = cached_monitor_info->at(i);
if (mon_info->owner() == obj) {
! log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
// Assume recursive case and fix up highest lock later
markOop mark = markOopDesc::encode((BasicLock*) NULL);
highest_lock = mon_info->lock();
highest_lock->set_displaced_header(mark);
} else {
! log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
}
}
if (highest_lock != NULL) {
// Fix up highest lock to contain displaced header and point
// object at it
highest_lock->set_displaced_header(unbiased_prototype);
// Reset object header to point to displaced mark.
// Must release storing the lock address for platforms without TSO
// ordering (e.g. ppc).
obj->release_set_mark(markOopDesc::encode(highest_lock));
assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
! // Log at "info" level if not bulk, else "trace" level
! if (!is_bulk) {
! log_info(biasedlocking)(" Revoked bias of currently-locked object");
! } else {
! log_trace(biasedlocking)(" Revoked bias of currently-locked object");
}
} else {
! // Log at "info" level if not bulk, else "trace" level
! if (!is_bulk) {
! log_info(biasedlocking)(" Revoked bias of currently-unlocked object");
! } else {
! log_trace(biasedlocking)(" Revoked bias of currently-unlocked object");
}
if (allow_rebias) {
obj->set_mark(biased_prototype);
} else {
// Store the unlocked value into the object's header.
*** 324,339 ****
bool bulk_rebias,
bool attempt_rebias_of_object,
JavaThread* requesting_thread) {
assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
! if (TraceBiasedLocking) {
! tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(bulk_rebias ? "rebias" : "revoke"),
! p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name());
! }
jlong cur_time = os::javaTimeMillis();
o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
--- 350,365 ----
bool bulk_rebias,
bool attempt_rebias_of_object,
JavaThread* requesting_thread) {
assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
! log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object "
INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(bulk_rebias ? "rebias" : "revoke"),
! p2i((void *) o),
! (intptr_t) o->mark(),
! o->klass()->external_name());
jlong cur_time = os::javaTimeMillis();
o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
*** 375,387 ****
// 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());
}
// Disable biased locking for this data type. Not only will this
// cause future instances to not be biased, but existing biased
// instances will notice that this implicitly caused their biases
--- 401,413 ----
// 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 (log_is_enabled(Info, biasedlocking)) {
ResourceMark rm;
! log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
}
// Disable biased locking for this data type. Not only will this
// cause future instances to not be biased, but existing biased
// instances will notice that this implicitly caused their biases
*** 405,430 ****
// 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");
! }
BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
if (attempt_rebias_of_object &&
o->mark()->has_bias_pattern() &&
klass->prototype_header()->has_bias_pattern()) {
markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(),
klass->prototype_header()->bias_epoch());
o->set_mark(new_mark);
status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
! if (TraceBiasedLocking) {
! tty->print_cr(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
! }
}
assert(!o->mark()->has_bias_pattern() ||
(attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)),
"bug in bulk bias revocation");
--- 431,452 ----
// 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);
}
! log_info(biasedlocking)("* Ending bulk revocation");
BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
if (attempt_rebias_of_object &&
o->mark()->has_bias_pattern() &&
klass->prototype_header()->has_bias_pattern()) {
markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(),
klass->prototype_header()->bias_epoch());
o->set_mark(new_mark);
status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
! log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
}
assert(!o->mark()->has_bias_pattern() ||
(attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)),
"bug in bulk bias revocation");
*** 483,502 ****
return false;
}
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:");
! }
BiasedLocking::revoke_at_safepoint(_objs);
}
}
BiasedLocking::Condition status_code() const {
--- 505,520 ----
return false;
}
virtual void doit() {
if (_obj != NULL) {
! log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
_status_code = revoke_bias((*_obj)(), false, false, _requesting_thread);
clean_up_cached_monitor_info();
return;
} else {
! log_info(biasedlocking)("Revoking bias with global safepoint:");
BiasedLocking::revoke_at_safepoint(_objs);
}
}
BiasedLocking::Condition status_code() const {
*** 606,618 ****
// reach no safepoints in the revocation path.
// Also check the epoch because even if threads match, another thread
// can come in with a CAS to steal the bias of an object that has a
// 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 {
--- 624,634 ----
// reach no safepoints in the revocation path.
// Also check the epoch because even if threads match, another thread
// can come in with a CAS to steal the bias of an object that has a
// stale epoch.
ResourceMark rm;
! log_info(biasedlocking)("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 {
src/share/vm/runtime/biasedLocking.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File