< prev index next >

src/hotspot/share/runtime/biasedLocking.cpp

Print this page
rev 54936 : imported patch 8221734-v3
rev 54937 : imported patch 8221734-v4


 611   assert(k != NULL, "invariant");
 612   assert(op != NULL, "invariant");
 613   assert(event->should_commit(), "invariant");
 614   event->set_lockClass(k);
 615   event->set_safepointId(op->safepoint_id());
 616   event->set_previousOwner(op->biased_locker());
 617   event->commit();
 618 }
 619 
 620 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, VM_BulkRevokeBias* op) {
 621   assert(event != NULL, "invariant");
 622   assert(k != NULL, "invariant");
 623   assert(op != NULL, "invariant");
 624   assert(event->should_commit(), "invariant");
 625   event->set_revokedClass(k);
 626   event->set_disableBiasing(!op->is_bulk_rebias());
 627   event->set_safepointId(op->safepoint_id());
 628   event->commit();
 629 }
 630 
 631 BiasedLocking::Condition fast_revoke(Handle obj, markOop mark, bool attempt_rebias, JavaThread* thread = NULL) {

























 632   // We can revoke the biases of anonymously-biased objects
 633   // efficiently enough that we should not cause these revocations to
 634   // update the heuristics because doing so may cause unwanted bulk
 635   // revocations (which are expensive) to occur.

 636   if (mark->is_biased_anonymously() && !attempt_rebias) {
 637     // We are probably trying to revoke the bias of this object due to
 638     // an identity hash code computation. Try to revoke the bias
 639     // without a safepoint. This is possible if we can successfully
 640     // compare-and-exchange an unbiased header into the mark word of
 641     // the object, meaning that no other thread has raced to acquire
 642     // the bias of the object.
 643     markOop biased_value       = mark;
 644     markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 645     markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 646     if (res_mark == biased_value) {
 647       return BiasedLocking::BIAS_REVOKED;
 648     }
 649   } else if (mark->has_bias_pattern()) {
 650     Klass* k = obj->klass();
 651     markOop prototype_header = k->prototype_header();
 652     if (!prototype_header->has_bias_pattern()) {
 653       // This object has a stale bias from before the bulk revocation
 654       // for this data type occurred. It's pointless to update the
 655       // heuristics at this point so simply update the header with a
 656       // CAS. If we fail this race, the object's bias has been revoked
 657       // by another thread so we simply return and let the caller deal
 658       // with it.
 659       markOop biased_value       = mark;
 660       markOop res_mark = obj->cas_set_mark(prototype_header, mark);
 661       assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
 662       return BiasedLocking::BIAS_REVOKED;
 663     } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
 664       // The epoch of this biasing has expired indicating that the
 665       // object is effectively unbiased. Depending on whether we need
 666       // to rebias or revoke the bias of this object we can do it
 667       // efficiently enough with a CAS that we shouldn't update the
 668       // heuristics. This is normally done in the assembly code but we
 669       // can reach this point due to various points in the runtime
 670       // needing to revoke biases.
 671       if (attempt_rebias) {

 672         markOop biased_value       = mark;
 673         markOop rebiased_prototype = markOopDesc::encode(thread, mark->age(), prototype_header->bias_epoch());
 674         markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
 675         if (res_mark == biased_value) {
 676           return BiasedLocking::BIAS_REVOKED_AND_REBIASED;
 677         }
 678       } else {
 679         markOop biased_value       = mark;
 680         markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 681         markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 682         if (res_mark == biased_value) {
 683           return BiasedLocking::BIAS_REVOKED;
 684         }
 685       }
 686     }
 687   }
 688   return BiasedLocking::NOT_REVOKED;
 689 }
 690 
 691 BiasedLocking::Condition BiasedLocking::revoke_own_locks_in_handshake(Handle obj, TRAPS) {
 692   markOop mark = obj->mark();
 693   BiasedLocking::Condition bc = fast_revoke(obj, mark, false);
 694   if (bc != NOT_REVOKED) {
 695     return bc;
 696   }
 697 
 698   if (!mark->has_bias_pattern()) {
 699     return NOT_BIASED;
 700   }
 701 
 702   Klass *k = obj->klass();
 703   markOop prototype_header = k->prototype_header();
 704   guarantee(mark->biased_locker() == THREAD &&
 705             prototype_header->bias_epoch() == mark->bias_epoch(), "Revoke failed, unhandled biased lock state");
 706   ResourceMark rm;
 707   log_info(biasedlocking)("Revoking bias by walking my own stack:");
 708   EventBiasedLockSelfRevocation event;
 709   BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
 710   ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
 711   assert(cond == BIAS_REVOKED, "why not?");
 712   if (event.should_commit()) {
 713     post_self_revocation_event(&event, k);
 714   }
 715   return cond;
 716 }
 717 
 718 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
 719   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 720   assert(!attempt_rebias || THREAD->is_Java_thread(), "");
 721 
 722   markOop mark = obj->mark();
 723   BiasedLocking::Condition bc = fast_revoke(obj, mark, attempt_rebias, (JavaThread*) THREAD);
 724   if (bc != NOT_REVOKED) {
 725     return bc;
 726   }
 727 
 728   HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
 729   if (heuristics == HR_NOT_BIASED) {
 730     return NOT_BIASED;
 731   } else if (heuristics == HR_SINGLE_REVOKE) {
 732     Klass *k = obj->klass();
 733     markOop prototype_header = k->prototype_header();
 734     if (mark->biased_locker() == THREAD &&
 735         prototype_header->bias_epoch() == mark->bias_epoch()) {
 736       // A thread is trying to revoke the bias of an object biased
 737       // toward it, again likely due to an identity hash code
 738       // computation. We can again avoid a safepoint in this case
 739       // since we are only going to walk our own stack. There are no
 740       // races with revocations occurring in other threads because we
 741       // reach no safepoints in the revocation path.
 742       // Also check the epoch because even if threads match, another thread
 743       // can come in with a CAS to steal the bias of an object that has a
 744       // stale epoch.
 745       ResourceMark rm;




 611   assert(k != NULL, "invariant");
 612   assert(op != NULL, "invariant");
 613   assert(event->should_commit(), "invariant");
 614   event->set_lockClass(k);
 615   event->set_safepointId(op->safepoint_id());
 616   event->set_previousOwner(op->biased_locker());
 617   event->commit();
 618 }
 619 
 620 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, VM_BulkRevokeBias* op) {
 621   assert(event != NULL, "invariant");
 622   assert(k != NULL, "invariant");
 623   assert(op != NULL, "invariant");
 624   assert(event->should_commit(), "invariant");
 625   event->set_revokedClass(k);
 626   event->set_disableBiasing(!op->is_bulk_rebias());
 627   event->set_safepointId(op->safepoint_id());
 628   event->commit();
 629 }
 630 
 631 BiasedLocking::Condition BiasedLocking::revoke_own_locks_in_handshake(Handle obj, TRAPS) {
 632   markOop mark = obj->mark();
 633 
 634   if (!mark->has_bias_pattern()) {
 635     return NOT_BIASED;
 636   }
 637 
 638   Klass *k = obj->klass();
 639   markOop prototype_header = k->prototype_header();
 640   assert(mark->biased_locker() == THREAD &&
 641             prototype_header->bias_epoch() == mark->bias_epoch(), "Revoke failed, unhandled biased lock state");
 642   ResourceMark rm;
 643   log_info(biasedlocking)("Revoking bias by walking my own stack:");
 644   EventBiasedLockSelfRevocation event;
 645   BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
 646   ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
 647   assert(cond == BIAS_REVOKED, "why not?");
 648   if (event.should_commit()) {
 649     post_self_revocation_event(&event, k);
 650   }
 651   return cond;
 652 }
 653 
 654 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
 655   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 656 
 657   // We can revoke the biases of anonymously-biased objects
 658   // efficiently enough that we should not cause these revocations to
 659   // update the heuristics because doing so may cause unwanted bulk
 660   // revocations (which are expensive) to occur.
 661   markOop mark = obj->mark();
 662   if (mark->is_biased_anonymously() && !attempt_rebias) {
 663     // We are probably trying to revoke the bias of this object due to
 664     // an identity hash code computation. Try to revoke the bias
 665     // without a safepoint. This is possible if we can successfully
 666     // compare-and-exchange an unbiased header into the mark word of
 667     // the object, meaning that no other thread has raced to acquire
 668     // the bias of the object.
 669     markOop biased_value       = mark;
 670     markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 671     markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 672     if (res_mark == biased_value) {
 673       return BIAS_REVOKED;
 674     }
 675   } else if (mark->has_bias_pattern()) {
 676     Klass* k = obj->klass();
 677     markOop prototype_header = k->prototype_header();
 678     if (!prototype_header->has_bias_pattern()) {
 679       // This object has a stale bias from before the bulk revocation
 680       // for this data type occurred. It's pointless to update the
 681       // heuristics at this point so simply update the header with a
 682       // CAS. If we fail this race, the object's bias has been revoked
 683       // by another thread so we simply return and let the caller deal
 684       // with it.
 685       markOop biased_value       = mark;
 686       markOop res_mark = obj->cas_set_mark(prototype_header, mark);
 687       assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
 688       return BIAS_REVOKED;
 689     } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
 690       // The epoch of this biasing has expired indicating that the
 691       // object is effectively unbiased. Depending on whether we need
 692       // to rebias or revoke the bias of this object we can do it
 693       // efficiently enough with a CAS that we shouldn't update the
 694       // heuristics. This is normally done in the assembly code but we
 695       // can reach this point due to various points in the runtime
 696       // needing to revoke biases.
 697       if (attempt_rebias) {
 698         assert(THREAD->is_Java_thread(), "");
 699         markOop biased_value       = mark;
 700         markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
 701         markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
 702         if (res_mark == biased_value) {
 703           return BIAS_REVOKED_AND_REBIASED;
 704         }
 705       } else {
 706         markOop biased_value       = mark;
 707         markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 708         markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 709         if (res_mark == biased_value) {
 710           return BIAS_REVOKED;


 711         }
 712       }


























 713     }











 714   }
 715 
 716   HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
 717   if (heuristics == HR_NOT_BIASED) {
 718     return NOT_BIASED;
 719   } else if (heuristics == HR_SINGLE_REVOKE) {
 720     Klass *k = obj->klass();
 721     markOop prototype_header = k->prototype_header();
 722     if (mark->biased_locker() == THREAD &&
 723         prototype_header->bias_epoch() == mark->bias_epoch()) {
 724       // A thread is trying to revoke the bias of an object biased
 725       // toward it, again likely due to an identity hash code
 726       // computation. We can again avoid a safepoint in this case
 727       // since we are only going to walk our own stack. There are no
 728       // races with revocations occurring in other threads because we
 729       // reach no safepoints in the revocation path.
 730       // Also check the epoch because even if threads match, another thread
 731       // can come in with a CAS to steal the bias of an object that has a
 732       // stale epoch.
 733       ResourceMark rm;


< prev index next >