< prev index next >

src/hotspot/share/runtime/biasedLocking.cpp

Print this page
rev 54838 : [mq]: 8221734-v2
rev 54839 : [mq]: 8221734-v3


 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, 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   markOop mark = obj->mark();
 637   if (mark->is_biased_anonymously() && !attempt_rebias) {
 638     // We are probably trying to revoke the bias of this object due to
 639     // an identity hash code computation. Try to revoke the bias
 640     // without a safepoint. This is possible if we can successfully
 641     // compare-and-exchange an unbiased header into the mark word of
 642     // the object, meaning that no other thread has raced to acquire
 643     // the bias of the object.
 644     markOop biased_value       = mark;
 645     markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 646     markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 647     if (res_mark == biased_value) {
 648       return BiasedLocking::BIAS_REVOKED;
 649     }
 650   } else if (mark->has_bias_pattern()) {
 651     Klass* k = obj->klass();
 652     markOop prototype_header = k->prototype_header();
 653     if (!prototype_header->has_bias_pattern()) {
 654       // This object has a stale bias from before the bulk revocation
 655       // for this data type occurred. It's pointless to update the
 656       // heuristics at this point so simply update the header with a


 672       if (attempt_rebias) {
 673         markOop biased_value       = mark;
 674         markOop rebiased_prototype = markOopDesc::encode(thread, mark->age(), prototype_header->bias_epoch());
 675         markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
 676         if (res_mark == biased_value) {
 677           return BiasedLocking::BIAS_REVOKED_AND_REBIASED;
 678         }
 679       } else {
 680         markOop biased_value       = mark;
 681         markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 682         markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 683         if (res_mark == biased_value) {
 684           return BiasedLocking::BIAS_REVOKED;
 685         }
 686       }
 687     }
 688   }
 689   return BiasedLocking::NOT_REVOKED;
 690 }
 691 
 692 BiasedLocking::Condition BiasedLocking::revoke_and_rebias_in_handshake(Handle obj, TRAPS) {
 693   BiasedLocking::Condition bc = fast_revoke(obj, false);

 694   if (bc != NOT_REVOKED) {
 695     return bc;
 696   }
 697 
 698   markOop mark = obj->mark();
 699   if (!mark->has_bias_pattern()) {
 700     return NOT_BIASED;
 701   }
 702 
 703   Klass *k = obj->klass();
 704   markOop prototype_header = k->prototype_header();
 705   if (mark->biased_locker() == THREAD && prototype_header->bias_epoch() == mark->bias_epoch()) {

 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   ShouldNotReachHere();
 719 
 720   return NOT_REVOKED;
 721 }
 722 
 723 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
 724   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 725   assert(!attempt_rebias || THREAD->is_Java_thread(), "");
 726 
 727   BiasedLocking::Condition bc = fast_revoke(obj, attempt_rebias, (JavaThread*) THREAD);

 728   if (bc != NOT_REVOKED) {
 729     return bc;
 730   }
 731 
 732   HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
 733   if (heuristics == HR_NOT_BIASED) {
 734     return NOT_BIASED;
 735   } else if (heuristics == HR_SINGLE_REVOKE) {
 736     markOop mark = obj->mark();
 737     Klass *k = obj->klass();
 738     markOop prototype_header = k->prototype_header();
 739     if (mark->has_bias_pattern() &&
 740         mark->biased_locker() == ((JavaThread*) THREAD) &&
 741         prototype_header->bias_epoch() == mark->bias_epoch()) {
 742       // A thread is trying to revoke the bias of an object biased
 743       // toward it, again likely due to an identity hash code
 744       // computation. We can again avoid a safepoint in this case
 745       // since we are only going to walk our own stack. There are no
 746       // races with revocations occurring in other threads because we
 747       // reach no safepoints in the revocation path.
 748       // Also check the epoch because even if threads match, another thread
 749       // can come in with a CAS to steal the bias of an object that has a
 750       // stale epoch.
 751       ResourceMark rm;
 752       log_info(biasedlocking)("Revoking bias by walking my own stack:");
 753       EventBiasedLockSelfRevocation event;
 754       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
 755       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
 756       assert(cond == BIAS_REVOKED, "why not?");
 757       if (event.should_commit()) {
 758         post_self_revocation_event(&event, k);
 759       }
 760       return cond;




 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


 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;
 746       log_info(biasedlocking)("Revoking bias by walking my own stack:");
 747       EventBiasedLockSelfRevocation event;
 748       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
 749       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
 750       assert(cond == BIAS_REVOKED, "why not?");
 751       if (event.should_commit()) {
 752         post_self_revocation_event(&event, k);
 753       }
 754       return cond;


< prev index next >