mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8229844: Remove attempt_rebias parameter from revoke_and_rebias()
Removed attempt_rebias parameter and merged fast_enter() and slow_enter() into enter() Reviewed-by: dholmes, rehn, coleenp, dcubed
This commit is contained in:
parent
702199983a
commit
85dbabe345
14 changed files with 125 additions and 249 deletions
|
@ -157,7 +157,7 @@ static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thre
|
|||
|
||||
// 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).
|
||||
BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
|
||||
void BiasedLocking::single_revoke_at_safepoint(oop obj, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
|
||||
assert(Thread::current()->is_VM_thread(), "must be VMThread");
|
||||
|
||||
|
@ -173,11 +173,10 @@ BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool
|
|||
obj->klass()->external_name(),
|
||||
(intptr_t) requesting_thread);
|
||||
}
|
||||
return NOT_BIASED;
|
||||
return;
|
||||
}
|
||||
|
||||
uint age = mark.age();
|
||||
markWord biased_prototype = markWord::biased_locking_prototype().set_age(age);
|
||||
markWord unbiased_prototype = markWord::prototype().set_age(age);
|
||||
|
||||
// Log at "info" level if not bulk, else "trace" level
|
||||
|
@ -185,23 +184,21 @@ BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool
|
|||
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,
|
||||
", requesting thread " INTPTR_FORMAT,
|
||||
p2i((void *)obj),
|
||||
mark.value(),
|
||||
obj->klass()->external_name(),
|
||||
obj->klass()->prototype_header().value(),
|
||||
(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,
|
||||
" , requesting thread " INTPTR_FORMAT,
|
||||
p2i((void *)obj),
|
||||
mark.value(),
|
||||
obj->klass()->external_name(),
|
||||
obj->klass()->prototype_header().value(),
|
||||
(allow_rebias ? 1 : 0),
|
||||
(intptr_t) requesting_thread);
|
||||
}
|
||||
|
||||
|
@ -210,16 +207,15 @@ BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool
|
|||
// 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);
|
||||
}
|
||||
obj->set_mark(unbiased_prototype);
|
||||
|
||||
// Log at "info" level if not bulk, else "trace" level
|
||||
if (!is_bulk) {
|
||||
log_info(biasedlocking)(" Revoked bias of anonymously-biased object");
|
||||
} else {
|
||||
log_trace(biasedlocking)(" Revoked bias of anonymously-biased object");
|
||||
}
|
||||
return BIAS_REVOKED;
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle case where the thread toward which the object was biased has exited
|
||||
|
@ -231,11 +227,7 @@ BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool
|
|||
thread_is_alive = tlh.includes(biased_thread);
|
||||
}
|
||||
if (!thread_is_alive) {
|
||||
if (allow_rebias) {
|
||||
obj->set_mark(biased_prototype);
|
||||
} else {
|
||||
obj->set_mark(unbiased_prototype);
|
||||
}
|
||||
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 ("
|
||||
|
@ -244,7 +236,7 @@ BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool
|
|||
log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread ("
|
||||
PTR_FORMAT ")", p2i(biased_thread));
|
||||
}
|
||||
return BIAS_REVOKED;
|
||||
return;
|
||||
}
|
||||
|
||||
// Log at "info" level if not bulk, else "trace" level
|
||||
|
@ -301,20 +293,14 @@ BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool
|
|||
} 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.
|
||||
obj->set_mark(unbiased_prototype);
|
||||
}
|
||||
// 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 BIAS_REVOKED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -379,10 +365,7 @@ static HeuristicsResult update_heuristics(oop o) {
|
|||
}
|
||||
|
||||
|
||||
BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o,
|
||||
bool bulk_rebias,
|
||||
bool attempt_rebias_of_object,
|
||||
JavaThread* requesting_thread) {
|
||||
void BiasedLocking::bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread* requesting_thread) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
|
||||
assert(Thread::current()->is_VM_thread(), "must be VMThread");
|
||||
|
||||
|
@ -437,7 +420,7 @@ BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o
|
|||
|
||||
// At this point we're done. All we have to do is potentially
|
||||
// adjust the header of the given object to revoke its bias.
|
||||
single_revoke_at_safepoint(o, attempt_rebias_of_object && klass->prototype_header().has_bias_pattern(), true, requesting_thread, NULL);
|
||||
single_revoke_at_safepoint(o, true, requesting_thread, NULL);
|
||||
} else {
|
||||
if (log_is_enabled(Info, biasedlocking)) {
|
||||
ResourceMark rm;
|
||||
|
@ -459,36 +442,20 @@ BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o
|
|||
oop owner = mon_info->owner();
|
||||
markWord mark = owner->mark();
|
||||
if ((owner->klass() == k_o) && mark.has_bias_pattern()) {
|
||||
single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL);
|
||||
single_revoke_at_safepoint(owner, true, requesting_thread, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Must force the bias of the passed object to be forcibly revoked
|
||||
// as well to ensure guarantees to callers
|
||||
single_revoke_at_safepoint(o, false, true, requesting_thread, NULL);
|
||||
single_revoke_at_safepoint(o, true, requesting_thread, NULL);
|
||||
}
|
||||
} // ThreadsListHandle is destroyed here.
|
||||
|
||||
log_info(biasedlocking)("* Ending bulk revocation");
|
||||
|
||||
BiasedLocking::Condition status_code = BIAS_REVOKED;
|
||||
|
||||
if (attempt_rebias_of_object &&
|
||||
o->mark().has_bias_pattern() &&
|
||||
klass->prototype_header().has_bias_pattern()) {
|
||||
markWord new_mark = markWord::encode(requesting_thread, o->mark().age(),
|
||||
klass->prototype_header().bias_epoch());
|
||||
o->set_mark(new_mark);
|
||||
status_code = 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");
|
||||
|
||||
return status_code;
|
||||
assert(!o->mark().has_bias_pattern(), "bug in bulk bias revocation");
|
||||
}
|
||||
|
||||
|
||||
|
@ -509,25 +476,20 @@ private:
|
|||
Handle* _obj;
|
||||
JavaThread* _requesting_thread;
|
||||
bool _bulk_rebias;
|
||||
bool _attempt_rebias_of_object;
|
||||
BiasedLocking::Condition _status_code;
|
||||
uint64_t _safepoint_id;
|
||||
|
||||
public:
|
||||
VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread,
|
||||
bool bulk_rebias,
|
||||
bool attempt_rebias_of_object)
|
||||
bool bulk_rebias)
|
||||
: _obj(obj)
|
||||
, _requesting_thread(requesting_thread)
|
||||
, _bulk_rebias(bulk_rebias)
|
||||
, _attempt_rebias_of_object(attempt_rebias_of_object)
|
||||
, _status_code(BiasedLocking::NOT_BIASED)
|
||||
, _safepoint_id(0) {}
|
||||
|
||||
virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; }
|
||||
|
||||
virtual void doit() {
|
||||
_status_code = BiasedLocking::bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
|
||||
BiasedLocking::bulk_revoke_at_safepoint((*_obj)(), _bulk_rebias, _requesting_thread);
|
||||
_safepoint_id = SafepointSynchronize::safepoint_id();
|
||||
clean_up_cached_monitor_info();
|
||||
}
|
||||
|
@ -536,10 +498,6 @@ public:
|
|||
return _bulk_rebias;
|
||||
}
|
||||
|
||||
BiasedLocking::Condition status_code() const {
|
||||
return _status_code;
|
||||
}
|
||||
|
||||
uint64_t safepoint_id() const {
|
||||
return _safepoint_id;
|
||||
}
|
||||
|
@ -769,7 +727,7 @@ void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
|
|||
}
|
||||
|
||||
|
||||
BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
|
||||
void BiasedLocking::revoke(Handle obj, TRAPS) {
|
||||
assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
|
||||
|
||||
while (true) {
|
||||
|
@ -778,7 +736,12 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
|
|||
// update the heuristics because doing so may cause unwanted bulk
|
||||
// revocations (which are expensive) to occur.
|
||||
markWord mark = obj->mark();
|
||||
if (mark.is_biased_anonymously() && !attempt_rebias) {
|
||||
|
||||
if (!mark.has_bias_pattern()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mark.is_biased_anonymously()) {
|
||||
// We are probably trying to revoke the bias of this object due to
|
||||
// an identity hash code computation. Try to revoke the bias
|
||||
// without a safepoint. This is possible if we can successfully
|
||||
|
@ -789,10 +752,10 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
|
|||
markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
|
||||
markWord res_mark = obj->cas_set_mark(unbiased_prototype, mark);
|
||||
if (res_mark == biased_value) {
|
||||
return BIAS_REVOKED;
|
||||
return;
|
||||
}
|
||||
mark = res_mark; // Refresh mark with the latest value.
|
||||
} else if (mark.has_bias_pattern()) {
|
||||
} else {
|
||||
Klass* k = obj->klass();
|
||||
markWord prototype_header = k->prototype_header();
|
||||
if (!prototype_header.has_bias_pattern()) {
|
||||
|
@ -804,31 +767,20 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
|
|||
// with it.
|
||||
obj->cas_set_mark(prototype_header.set_age(mark.age()), mark);
|
||||
assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked");
|
||||
return BIAS_REVOKED;
|
||||
return;
|
||||
} else if (prototype_header.bias_epoch() != mark.bias_epoch()) {
|
||||
// The epoch of this biasing has expired indicating that the
|
||||
// object is effectively unbiased. Depending on whether we need
|
||||
// to rebias or revoke the bias of this object we can do it
|
||||
// efficiently enough with a CAS that we shouldn't update the
|
||||
// object is effectively unbiased. We can revoke the bias of this
|
||||
// object efficiently enough with a CAS that we shouldn't update the
|
||||
// heuristics. This is normally done in the assembly code but we
|
||||
// can reach this point due to various points in the runtime
|
||||
// needing to revoke biases.
|
||||
markWord res_mark;
|
||||
if (attempt_rebias) {
|
||||
assert(THREAD->is_Java_thread(), "");
|
||||
markWord biased_value = mark;
|
||||
markWord rebiased_prototype = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
|
||||
res_mark = obj->cas_set_mark(rebiased_prototype, mark);
|
||||
if (res_mark == biased_value) {
|
||||
return BIAS_REVOKED_AND_REBIASED;
|
||||
}
|
||||
} else {
|
||||
markWord biased_value = mark;
|
||||
markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
|
||||
res_mark = obj->cas_set_mark(unbiased_prototype, mark);
|
||||
if (res_mark == biased_value) {
|
||||
return BIAS_REVOKED;
|
||||
}
|
||||
markWord biased_value = mark;
|
||||
markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
|
||||
res_mark = obj->cas_set_mark(unbiased_prototype, mark);
|
||||
if (res_mark == biased_value) {
|
||||
return;
|
||||
}
|
||||
mark = res_mark; // Refresh mark with the latest value.
|
||||
}
|
||||
|
@ -836,7 +788,7 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
|
|||
|
||||
HeuristicsResult heuristics = update_heuristics(obj());
|
||||
if (heuristics == HR_NOT_BIASED) {
|
||||
return NOT_BIASED;
|
||||
return;
|
||||
} else if (heuristics == HR_SINGLE_REVOKE) {
|
||||
JavaThread *blt = mark.biased_locker();
|
||||
assert(blt != NULL, "invariant");
|
||||
|
@ -855,11 +807,11 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
|
|||
if (event.should_commit()) {
|
||||
post_self_revocation_event(&event, obj->klass());
|
||||
}
|
||||
return BIAS_REVOKED;
|
||||
return;
|
||||
} else {
|
||||
BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt);
|
||||
if (cond != NOT_REVOKED) {
|
||||
return cond;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -867,13 +819,12 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
|
|||
(heuristics == HR_BULK_REBIAS), "?");
|
||||
EventBiasedLockClassRevocation event;
|
||||
VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD,
|
||||
(heuristics == HR_BULK_REBIAS),
|
||||
attempt_rebias);
|
||||
(heuristics == HR_BULK_REBIAS));
|
||||
VMThread::execute(&bulk_revoke);
|
||||
if (event.should_commit()) {
|
||||
post_class_revocation_event(&event, obj->klass(), &bulk_revoke);
|
||||
}
|
||||
return bulk_revoke.status_code();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -901,13 +852,13 @@ void BiasedLocking::revoke_at_safepoint(Handle h_obj) {
|
|||
HeuristicsResult heuristics = update_heuristics(obj);
|
||||
if (heuristics == HR_SINGLE_REVOKE) {
|
||||
JavaThread* biased_locker = NULL;
|
||||
single_revoke_at_safepoint(obj, false, false, NULL, &biased_locker);
|
||||
single_revoke_at_safepoint(obj, false, NULL, &biased_locker);
|
||||
if (biased_locker) {
|
||||
clean_up_cached_monitor_info(biased_locker);
|
||||
}
|
||||
} else if ((heuristics == HR_BULK_REBIAS) ||
|
||||
(heuristics == HR_BULK_REVOKE)) {
|
||||
bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
|
||||
bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL);
|
||||
clean_up_cached_monitor_info();
|
||||
}
|
||||
}
|
||||
|
@ -920,10 +871,10 @@ void BiasedLocking::revoke_at_safepoint(GrowableArray<Handle>* objs) {
|
|||
oop obj = (objs->at(i))();
|
||||
HeuristicsResult heuristics = update_heuristics(obj);
|
||||
if (heuristics == HR_SINGLE_REVOKE) {
|
||||
single_revoke_at_safepoint(obj, false, false, NULL, NULL);
|
||||
single_revoke_at_safepoint(obj, 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);
|
||||
bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL);
|
||||
}
|
||||
}
|
||||
clean_up_cached_monitor_info();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue