< prev index next >

src/hotspot/share/runtime/biasedLocking.cpp

Print this page
rev 54621 : imported patch 8221734-v1

*** 619,648 **** event->set_disableBiasing(disabled_bias); set_safepoint_id(event); 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"); ! // 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) { // 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 // compare-and-exchange an unbiased header into the mark word of // the object, meaning that no other thread has raced to acquire // the bias of the object. 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; } } else if (mark->has_bias_pattern()) { Klass* k = obj->klass(); markOop prototype_header = k->prototype_header(); if (!prototype_header->has_bias_pattern()) { --- 619,646 ---- event->set_disableBiasing(disabled_bias); set_safepoint_id(event); event->commit(); } ! 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()) { // 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 // compare-and-exchange an unbiased header into the mark word of // the object, meaning that no other thread has raced to acquire // the bias of the object. 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 BiasedLocking::BIAS_REVOKED; } } else if (mark->has_bias_pattern()) { Klass* k = obj->klass(); markOop prototype_header = k->prototype_header(); if (!prototype_header->has_bias_pattern()) {
*** 653,697 **** // by another thread so we simply return and let the caller deal // with it. 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; } 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 // 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. 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 res_mark = obj->cas_set_mark(rebiased_prototype, mark); if (res_mark == biased_value) { ! return 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; } } } } HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias); if (heuristics == HR_NOT_BIASED) { return NOT_BIASED; } else if (heuristics == HR_SINGLE_REVOKE) { Klass *k = obj->klass(); markOop prototype_header = k->prototype_header(); ! if (mark->biased_locker() == 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 // computation. We can again avoid a safepoint in this case // since we are only going to walk our own stack. There are no --- 651,737 ---- // by another thread so we simply return and let the caller deal // with it. 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 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 // to rebias or revoke the bias of this object we can do it // 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. if (attempt_rebias) { markOop biased_value = mark; ! 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 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 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_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 // computation. We can again avoid a safepoint in this case // since we are only going to walk our own stack. There are no
< prev index next >