--- old/src/hotspot/share/runtime/biasedLocking.cpp 2019-04-25 11:54:22.798097603 +0200 +++ new/src/hotspot/share/runtime/biasedLocking.cpp 2019-04-25 11:54:22.049072377 +0200 @@ -621,15 +621,13 @@ event->commit(); } -BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) { - assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint"); - +BiasedLocking::Condition fast_revoke(Handle obj, bool attempt_rebias, JavaThread* thread = NULL) { // We can revoke the biases of anonymously-biased objects // efficiently enough that we should not cause these revocations to // update the heuristics because doing so may cause unwanted bulk // revocations (which are expensive) to occur. markOop mark = obj->mark(); - if (mark->is_biased_anonymously() && !attempt_rebias) { + 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 @@ -640,7 +638,7 @@ markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark); if (res_mark == biased_value) { - return BIAS_REVOKED; + return BiasedLocking::BIAS_REVOKED; } } else if (mark->has_bias_pattern()) { Klass* k = obj->klass(); @@ -655,7 +653,7 @@ markOop biased_value = mark; markOop res_mark = obj->cas_set_mark(prototype_header, mark); assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked"); - return BIAS_REVOKED; + return BiasedLocking::BIAS_REVOKED; } 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 @@ -665,31 +663,73 @@ // can reach this point due to various points in the runtime // needing to revoke biases. if (attempt_rebias) { - assert(THREAD->is_Java_thread(), ""); markOop biased_value = mark; - markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch()); + markOop rebiased_prototype = markOopDesc::encode(thread, mark->age(), prototype_header->bias_epoch()); markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark); if (res_mark == biased_value) { - return BIAS_REVOKED_AND_REBIASED; + return BiasedLocking::BIAS_REVOKED_AND_REBIASED; } } else { markOop biased_value = mark; markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark); if (res_mark == biased_value) { - return BIAS_REVOKED; + return BiasedLocking::BIAS_REVOKED; } } } } + return BiasedLocking::NOT_REVOKED; +} + +BiasedLocking::Condition BiasedLocking::revoke_and_rebias_in_handshake(Handle obj, TRAPS) { + BiasedLocking::Condition bc = fast_revoke(obj, false); + if (bc != NOT_REVOKED) { + return bc; + } + + markOop mark = obj->mark(); + if (!mark->has_bias_pattern()) { + return NOT_BIASED; + } + + Klass *k = obj->klass(); + markOop prototype_header = k->prototype_header(); + if (mark->biased_locker() == THREAD && prototype_header->bias_epoch() == mark->bias_epoch()) { + ResourceMark rm; + log_info(biasedlocking)("Revoking bias by walking my own stack:"); + 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()) { + post_self_revocation_event(&event, k); + } + return cond; + } + + ShouldNotReachHere(); + + return NOT_REVOKED; +} + +BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) { + assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint"); + assert(!attempt_rebias || THREAD->is_Java_thread(), ""); + + BiasedLocking::Condition bc = fast_revoke(obj, attempt_rebias, (JavaThread*) THREAD); + if (bc != NOT_REVOKED) { + return bc; + } HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias); if (heuristics == HR_NOT_BIASED) { return NOT_BIASED; } else if (heuristics == HR_SINGLE_REVOKE) { + markOop mark = obj->mark(); Klass *k = obj->klass(); markOop prototype_header = k->prototype_header(); - if (mark->biased_locker() == THREAD && + if (mark->biased_locker_is((JavaThread*) THREAD) && prototype_header->bias_epoch() == mark->bias_epoch()) { // A thread is trying to revoke the bias of an object biased // toward it, again likely due to an identity hash code