--- old/src/hotspot/share/runtime/biasedLocking.cpp 2019-08-22 18:54:04.950216306 +0000 +++ new/src/hotspot/share/runtime/biasedLocking.cpp 2019-08-22 18:54:04.056195791 +0000 @@ -157,7 +157,7 @@ // 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ } 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 @@ } -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 @@ // 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 @@ 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 @@ 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 @@ return _bulk_rebias; } - BiasedLocking::Condition status_code() const { - return _status_code; - } - uint64_t safepoint_id() const { return _safepoint_id; } @@ -769,7 +727,7 @@ } -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 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ (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 @@ 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 @@ 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();