< prev index next >

src/hotspot/share/runtime/biasedLocking.cpp

Print this page




 605   assert(op != NULL, "invariant");
 606   assert(event->should_commit(), "invariant");
 607   event->set_revokedClass(k);
 608   event->set_disableBiasing(!op->is_bulk_rebias());
 609   event->set_safepointId(op->safepoint_id());
 610   event->commit();
 611 }
 612 
 613 
 614 BiasedLocking::Condition BiasedLocking::single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser) {
 615 
 616   EventBiasedLockRevocation event;
 617   if (PrintBiasedLockingStatistics) {
 618     Atomic::inc(handshakes_count_addr());
 619   }
 620   log_info(biasedlocking, handshake)("JavaThread " INTPTR_FORMAT " handshaking JavaThread "
 621                                      INTPTR_FORMAT " to revoke object " INTPTR_FORMAT, p2i(requester),
 622                                      p2i(biaser), p2i(obj()));
 623 
 624   RevokeOneBias revoke(obj, requester, biaser);
 625   bool executed = Handshake::execute(&revoke, biaser);
 626   if (revoke.status_code() == NOT_REVOKED) {
 627     return NOT_REVOKED;
 628   }
 629   if (executed) {
 630     log_info(biasedlocking, handshake)("Handshake revocation for object " INTPTR_FORMAT " succeeded. Bias was %srevoked",
 631                                        p2i(obj()), (revoke.status_code() == BIAS_REVOKED ? "" : "already "));
 632     if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
 633       post_revocation_event(&event, obj->klass(), &revoke);
 634     }
 635     assert(!obj->mark().has_bias_pattern(), "invariant");
 636     return revoke.status_code();
 637   } else {
 638     // Thread was not alive.
 639     // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
 640     // created JavaThread (that happens to get the same memory address as biaser) synchronizing
 641     // on this object.
 642     {
 643       MutexLocker ml(Threads_lock);
 644       markWord mark = obj->mark();
 645       // Check if somebody else was able to revoke it before biased thread exited.


 649       ThreadsListHandle tlh;
 650       markWord prototype = obj->klass()->prototype_header();
 651       if (!prototype.has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark.biased_locker() &&
 652                                             prototype.bias_epoch() == mark.bias_epoch())) {
 653         obj->cas_set_mark(markWord::prototype().set_age(mark.age()), mark);
 654         if (event.should_commit()) {
 655           post_revocation_event(&event, obj->klass(), &revoke);
 656         }
 657         assert(!obj->mark().has_bias_pattern(), "bias should be revoked by now");
 658         return BIAS_REVOKED;
 659       }
 660     }
 661   }
 662 
 663   return NOT_REVOKED;
 664 }
 665 
 666 
 667 // Caller should have instantiated a ResourceMark object before calling this method
 668 void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {

 669   assert(!SafepointSynchronize::is_at_safepoint(), "this should always be executed outside safepoints");
 670   assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
 671 
 672   markWord mark = obj->mark();
 673   assert(mark.biased_locker() == biased_locker &&
 674          obj->klass()->prototype_header().bias_epoch() == mark.bias_epoch(), "invariant");
 675 
 676   log_trace(biasedlocking)("%s(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
 677                            INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
 678                            ", biaser " INTPTR_FORMAT " %s",
 679                            Thread::current()->is_VM_thread() ? "VMThread" : "JavaThread",
 680                            p2i(Thread::current()),
 681                            p2i(obj),
 682                            mark.value(),
 683                            obj->klass()->external_name(),
 684                            obj->klass()->prototype_header().value(),
 685                            p2i(biased_locker),
 686                            Thread::current()->is_VM_thread() ? "" : "(walking own stack)");
 687 
 688   markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
 689 
 690   GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
 691   BasicLock* highest_lock = NULL;
 692   for (int i = 0; i < cached_monitor_info->length(); i++) {
 693     MonitorInfo* mon_info = cached_monitor_info->at(i);
 694     if (mon_info->owner() == obj) {
 695       log_trace(biasedlocking)("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
 696                                p2i(mon_info->owner()),
 697                                p2i(obj));
 698       // Assume recursive case and fix up highest lock below
 699       markWord mark = markWord::encode((BasicLock*) NULL);
 700       highest_lock = mon_info->lock();
 701       highest_lock->set_displaced_header(mark);
 702     } else {
 703       log_trace(biasedlocking)("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
 704                                p2i(mon_info->owner()),
 705                                p2i(obj));
 706     }




 605   assert(op != NULL, "invariant");
 606   assert(event->should_commit(), "invariant");
 607   event->set_revokedClass(k);
 608   event->set_disableBiasing(!op->is_bulk_rebias());
 609   event->set_safepointId(op->safepoint_id());
 610   event->commit();
 611 }
 612 
 613 
 614 BiasedLocking::Condition BiasedLocking::single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser) {
 615 
 616   EventBiasedLockRevocation event;
 617   if (PrintBiasedLockingStatistics) {
 618     Atomic::inc(handshakes_count_addr());
 619   }
 620   log_info(biasedlocking, handshake)("JavaThread " INTPTR_FORMAT " handshaking JavaThread "
 621                                      INTPTR_FORMAT " to revoke object " INTPTR_FORMAT, p2i(requester),
 622                                      p2i(biaser), p2i(obj()));
 623 
 624   RevokeOneBias revoke(obj, requester, biaser);
 625   bool executed = Handshake::execute_direct(&revoke, biaser);
 626   if (revoke.status_code() == NOT_REVOKED) {
 627     return NOT_REVOKED;
 628   }
 629   if (executed) {
 630     log_info(biasedlocking, handshake)("Handshake revocation for object " INTPTR_FORMAT " succeeded. Bias was %srevoked",
 631                                        p2i(obj()), (revoke.status_code() == BIAS_REVOKED ? "" : "already "));
 632     if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
 633       post_revocation_event(&event, obj->klass(), &revoke);
 634     }
 635     assert(!obj->mark().has_bias_pattern(), "invariant");
 636     return revoke.status_code();
 637   } else {
 638     // Thread was not alive.
 639     // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
 640     // created JavaThread (that happens to get the same memory address as biaser) synchronizing
 641     // on this object.
 642     {
 643       MutexLocker ml(Threads_lock);
 644       markWord mark = obj->mark();
 645       // Check if somebody else was able to revoke it before biased thread exited.


 649       ThreadsListHandle tlh;
 650       markWord prototype = obj->klass()->prototype_header();
 651       if (!prototype.has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark.biased_locker() &&
 652                                             prototype.bias_epoch() == mark.bias_epoch())) {
 653         obj->cas_set_mark(markWord::prototype().set_age(mark.age()), mark);
 654         if (event.should_commit()) {
 655           post_revocation_event(&event, obj->klass(), &revoke);
 656         }
 657         assert(!obj->mark().has_bias_pattern(), "bias should be revoked by now");
 658         return BIAS_REVOKED;
 659       }
 660     }
 661   }
 662 
 663   return NOT_REVOKED;
 664 }
 665 
 666 
 667 // Caller should have instantiated a ResourceMark object before calling this method
 668 void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
 669   Thread* cur = Thread::current();
 670   assert(!SafepointSynchronize::is_at_safepoint(), "this should always be executed outside safepoints");
 671   assert(cur == biased_locker || cur == biased_locker->active_handshaker(), "wrong thread");
 672 
 673   markWord mark = obj->mark();
 674   assert(mark.biased_locker() == biased_locker &&
 675          obj->klass()->prototype_header().bias_epoch() == mark.bias_epoch(), "invariant");
 676 
 677   log_trace(biasedlocking)("JavaThread(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
 678                            INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
 679                            ", biaser " INTPTR_FORMAT " %s",
 680                            p2i(cur),

 681                            p2i(obj),
 682                            mark.value(),
 683                            obj->klass()->external_name(),
 684                            obj->klass()->prototype_header().value(),
 685                            p2i(biased_locker),
 686                            cur != biased_locker ? "" : "(walking own stack)");
 687 
 688   markWord unbiased_prototype = markWord::prototype().set_age(obj->mark().age());
 689 
 690   GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
 691   BasicLock* highest_lock = NULL;
 692   for (int i = 0; i < cached_monitor_info->length(); i++) {
 693     MonitorInfo* mon_info = cached_monitor_info->at(i);
 694     if (mon_info->owner() == obj) {
 695       log_trace(biasedlocking)("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
 696                                p2i(mon_info->owner()),
 697                                p2i(obj));
 698       // Assume recursive case and fix up highest lock below
 699       markWord mark = markWord::encode((BasicLock*) NULL);
 700       highest_lock = mon_info->lock();
 701       highest_lock->set_displaced_header(mark);
 702     } else {
 703       log_trace(biasedlocking)("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
 704                                p2i(mon_info->owner()),
 705                                p2i(obj));
 706     }


< prev index next >