< prev index next >

src/hotspot/share/runtime/biasedLocking.cpp

Print this page


   1 /*
   2  * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 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.


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


   1 /*
   2  * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 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.


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


< prev index next >