< prev index next >

src/hotspot/share/runtime/biasedLocking.cpp

Print this page
rev 54697 : imported patch 8221734-v2-merge
rev 54698 : imported patch 8221734-v2


 604   assert(event != NULL, "invariant");
 605   assert(k != NULL, "invariant");
 606   assert(revoke != NULL, "invariant");
 607   assert(event->should_commit(), "invariant");
 608   event->set_lockClass(k);
 609   set_safepoint_id(event);
 610   event->set_previousOwner(revoke->biased_locker());
 611   event->commit();
 612 }
 613 
 614 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, bool disabled_bias) {
 615   assert(event != NULL, "invariant");
 616   assert(k != NULL, "invariant");
 617   assert(event->should_commit(), "invariant");
 618   event->set_revokedClass(k);
 619   event->set_disableBiasing(disabled_bias);
 620   set_safepoint_id(event);
 621   event->commit();
 622 }
 623 
 624 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
 625   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 626 
 627   // We can revoke the biases of anonymously-biased objects
 628   // efficiently enough that we should not cause these revocations to
 629   // update the heuristics because doing so may cause unwanted bulk
 630   // revocations (which are expensive) to occur.
 631   markOop mark = obj->mark();
 632   if (mark->is_biased_anonymously() && !attempt_rebias) {
 633     // We are probably trying to revoke the bias of this object due to
 634     // an identity hash code computation. Try to revoke the bias
 635     // without a safepoint. This is possible if we can successfully
 636     // compare-and-exchange an unbiased header into the mark word of
 637     // the object, meaning that no other thread has raced to acquire
 638     // the bias of the object.
 639     markOop biased_value       = mark;
 640     markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 641     markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 642     if (res_mark == biased_value) {
 643       return BIAS_REVOKED;
 644     }
 645   } else if (mark->has_bias_pattern()) {
 646     Klass* k = obj->klass();
 647     markOop prototype_header = k->prototype_header();
 648     if (!prototype_header->has_bias_pattern()) {
 649       // This object has a stale bias from before the bulk revocation
 650       // for this data type occurred. It's pointless to update the
 651       // heuristics at this point so simply update the header with a
 652       // CAS. If we fail this race, the object's bias has been revoked
 653       // by another thread so we simply return and let the caller deal
 654       // with it.
 655       markOop biased_value       = mark;
 656       markOop res_mark = obj->cas_set_mark(prototype_header, mark);
 657       assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
 658       return BIAS_REVOKED;
 659     } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
 660       // The epoch of this biasing has expired indicating that the
 661       // object is effectively unbiased. Depending on whether we need
 662       // to rebias or revoke the bias of this object we can do it
 663       // efficiently enough with a CAS that we shouldn't update the
 664       // heuristics. This is normally done in the assembly code but we
 665       // can reach this point due to various points in the runtime
 666       // needing to revoke biases.
 667       if (attempt_rebias) {
 668         assert(THREAD->is_Java_thread(), "");
 669         markOop biased_value       = mark;
 670         markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
 671         markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
 672         if (res_mark == biased_value) {
 673           return BIAS_REVOKED_AND_REBIASED;
 674         }
 675       } else {
 676         markOop biased_value       = mark;
 677         markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 678         markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 679         if (res_mark == biased_value) {
 680           return BIAS_REVOKED;
















 681         }












 682       }

 683     }













 684   }
 685 
 686   HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
 687   if (heuristics == HR_NOT_BIASED) {
 688     return NOT_BIASED;
 689   } else if (heuristics == HR_SINGLE_REVOKE) {

 690     Klass *k = obj->klass();
 691     markOop prototype_header = k->prototype_header();
 692     if (mark->biased_locker() == THREAD &&

 693         prototype_header->bias_epoch() == mark->bias_epoch()) {
 694       // A thread is trying to revoke the bias of an object biased
 695       // toward it, again likely due to an identity hash code
 696       // computation. We can again avoid a safepoint in this case
 697       // since we are only going to walk our own stack. There are no
 698       // races with revocations occurring in other threads because we
 699       // reach no safepoints in the revocation path.
 700       // Also check the epoch because even if threads match, another thread
 701       // can come in with a CAS to steal the bias of an object that has a
 702       // stale epoch.
 703       ResourceMark rm;
 704       log_info(biasedlocking)("Revoking bias by walking my own stack:");
 705       EventBiasedLockSelfRevocation event;
 706       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
 707       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
 708       assert(cond == BIAS_REVOKED, "why not?");
 709       if (event.should_commit()) {
 710         post_self_revocation_event(&event, k);
 711       }
 712       return cond;




 604   assert(event != NULL, "invariant");
 605   assert(k != NULL, "invariant");
 606   assert(revoke != NULL, "invariant");
 607   assert(event->should_commit(), "invariant");
 608   event->set_lockClass(k);
 609   set_safepoint_id(event);
 610   event->set_previousOwner(revoke->biased_locker());
 611   event->commit();
 612 }
 613 
 614 static void post_class_revocation_event(EventBiasedLockClassRevocation* event, Klass* k, bool disabled_bias) {
 615   assert(event != NULL, "invariant");
 616   assert(k != NULL, "invariant");
 617   assert(event->should_commit(), "invariant");
 618   event->set_revokedClass(k);
 619   event->set_disableBiasing(disabled_bias);
 620   set_safepoint_id(event);
 621   event->commit();
 622 }
 623 
 624 BiasedLocking::Condition fast_revoke(Handle obj, bool attempt_rebias, JavaThread* thread = NULL) {


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

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


< prev index next >