hotspot/src/share/vm/runtime/biasedLocking.cpp
changeset 36186 06763de0d7ad
parent 29081 c61eb4914428
child 37251 9fc139ad74b5
equal deleted inserted replaced
36185:3b446794e4e7 36186:06763de0d7ad
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
       
    26 #include "logging/log.hpp"
       
    27 #include "memory/resourceArea.hpp"
    26 #include "oops/klass.inline.hpp"
    28 #include "oops/klass.inline.hpp"
    27 #include "oops/markOop.hpp"
    29 #include "oops/markOop.hpp"
    28 #include "oops/oop.inline.hpp"
    30 #include "oops/oop.inline.hpp"
    29 #include "runtime/atomic.inline.hpp"
    31 #include "runtime/atomic.inline.hpp"
    30 #include "runtime/basicLock.hpp"
    32 #include "runtime/basicLock.hpp"
    58     // currently loaded classes
    60     // currently loaded classes
    59     SystemDictionary::classes_do(enable_biased_locking);
    61     SystemDictionary::classes_do(enable_biased_locking);
    60     // Indicate that future instances should enable it as well
    62     // Indicate that future instances should enable it as well
    61     _biased_locking_enabled = true;
    63     _biased_locking_enabled = true;
    62 
    64 
    63     if (TraceBiasedLocking) {
    65     log_info(biasedlocking)("Biased locking enabled");
    64       tty->print_cr("Biased locking enabled");
       
    65     }
       
    66   }
    66   }
    67 
    67 
    68   bool allow_nested_vm_operations() const        { return false; }
    68   bool allow_nested_vm_operations() const        { return false; }
    69 };
    69 };
    70 
    70 
   142 
   142 
   143   thread->set_cached_monitor_info(info);
   143   thread->set_cached_monitor_info(info);
   144   return info;
   144   return info;
   145 }
   145 }
   146 
   146 
   147 
       
   148 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
   147 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
   149   markOop mark = obj->mark();
   148   markOop mark = obj->mark();
   150   if (!mark->has_bias_pattern()) {
   149   if (!mark->has_bias_pattern()) {
   151     if (TraceBiasedLocking) {
   150     if (log_is_enabled(Info, biasedlocking)) {
   152       ResourceMark rm;
   151       ResourceMark rm;
   153       tty->print_cr("  (Skipping revocation of object of type %s because it's no longer biased)",
   152       log_info(biasedlocking)("  (Skipping revocation of object of type %s "
   154                     obj->klass()->external_name());
   153                               "because it's no longer biased)",
       
   154                               obj->klass()->external_name());
   155     }
   155     }
   156     return BiasedLocking::NOT_BIASED;
   156     return BiasedLocking::NOT_BIASED;
   157   }
   157   }
   158 
   158 
   159   uint age = mark->age();
   159   uint age = mark->age();
   160   markOop   biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
   160   markOop   biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
   161   markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
   161   markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
   162 
   162 
   163   if (TraceBiasedLocking && (Verbose || !is_bulk)) {
   163   // Log at "info" level if not bulk, else "trace" level
       
   164   if (!is_bulk) {
   164     ResourceMark rm;
   165     ResourceMark rm;
   165     tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
   166     log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
   166                   p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
   167                             INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
       
   168                             " , allow rebias %d , requesting thread " INTPTR_FORMAT,
       
   169                             p2i((void *)obj),
       
   170                             (intptr_t) mark,
       
   171                             obj->klass()->external_name(),
       
   172                             (intptr_t) obj->klass()->prototype_header(),
       
   173                             (allow_rebias ? 1 : 0),
       
   174                             (intptr_t) requesting_thread);
       
   175   } else {
       
   176     ResourceMark rm;
       
   177     log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
       
   178                              INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
       
   179                              " , allow rebias %d , requesting thread " INTPTR_FORMAT,
       
   180                              p2i((void *)obj),
       
   181                              (intptr_t) mark,
       
   182                              obj->klass()->external_name(),
       
   183                              (intptr_t) obj->klass()->prototype_header(),
       
   184                              (allow_rebias ? 1 : 0),
       
   185                              (intptr_t) requesting_thread);
   167   }
   186   }
   168 
   187 
   169   JavaThread* biased_thread = mark->biased_locker();
   188   JavaThread* biased_thread = mark->biased_locker();
   170   if (biased_thread == NULL) {
   189   if (biased_thread == NULL) {
   171     // Object is anonymously biased. We can get here if, for
   190     // Object is anonymously biased. We can get here if, for
   172     // example, we revoke the bias due to an identity hash code
   191     // example, we revoke the bias due to an identity hash code
   173     // being computed for an object.
   192     // being computed for an object.
   174     if (!allow_rebias) {
   193     if (!allow_rebias) {
   175       obj->set_mark(unbiased_prototype);
   194       obj->set_mark(unbiased_prototype);
   176     }
   195     }
   177     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
   196     // Log at "info" level if not bulk, else "trace" level
   178       tty->print_cr("  Revoked bias of anonymously-biased object");
   197     if (!is_bulk) {
       
   198       log_info(biasedlocking)("  Revoked bias of anonymously-biased object");
       
   199     } else {
       
   200       log_trace(biasedlocking)("  Revoked bias of anonymously-biased object");
   179     }
   201     }
   180     return BiasedLocking::BIAS_REVOKED;
   202     return BiasedLocking::BIAS_REVOKED;
   181   }
   203   }
   182 
   204 
   183   // Handle case where the thread toward which the object was biased has exited
   205   // Handle case where the thread toward which the object was biased has exited
   196     if (allow_rebias) {
   218     if (allow_rebias) {
   197       obj->set_mark(biased_prototype);
   219       obj->set_mark(biased_prototype);
   198     } else {
   220     } else {
   199       obj->set_mark(unbiased_prototype);
   221       obj->set_mark(unbiased_prototype);
   200     }
   222     }
   201     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
   223     // Log at "info" level if not bulk, else "trace" level
   202       tty->print_cr("  Revoked bias of object biased toward dead thread");
   224     if (!is_bulk) {
       
   225       log_info(biasedlocking)("  Revoked bias of object biased toward dead thread");
       
   226     } else {
       
   227       log_trace(biasedlocking)("  Revoked bias of object biased toward dead thread");
   203     }
   228     }
   204     return BiasedLocking::BIAS_REVOKED;
   229     return BiasedLocking::BIAS_REVOKED;
   205   }
   230   }
   206 
   231 
   207   // Thread owning bias is alive.
   232   // Thread owning bias is alive.
   212   GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
   237   GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
   213   BasicLock* highest_lock = NULL;
   238   BasicLock* highest_lock = NULL;
   214   for (int i = 0; i < cached_monitor_info->length(); i++) {
   239   for (int i = 0; i < cached_monitor_info->length(); i++) {
   215     MonitorInfo* mon_info = cached_monitor_info->at(i);
   240     MonitorInfo* mon_info = cached_monitor_info->at(i);
   216     if (mon_info->owner() == obj) {
   241     if (mon_info->owner() == obj) {
   217       if (TraceBiasedLocking && Verbose) {
   242       log_trace(biasedlocking)("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
   218         tty->print_cr("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
   243                                p2i((void *) mon_info->owner()),
   219                       p2i((void *) mon_info->owner()),
   244                                p2i((void *) obj));
   220                       p2i((void *) obj));
       
   221       }
       
   222       // Assume recursive case and fix up highest lock later
   245       // Assume recursive case and fix up highest lock later
   223       markOop mark = markOopDesc::encode((BasicLock*) NULL);
   246       markOop mark = markOopDesc::encode((BasicLock*) NULL);
   224       highest_lock = mon_info->lock();
   247       highest_lock = mon_info->lock();
   225       highest_lock->set_displaced_header(mark);
   248       highest_lock->set_displaced_header(mark);
   226     } else {
   249     } else {
   227       if (TraceBiasedLocking && Verbose) {
   250       log_trace(biasedlocking)("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
   228         tty->print_cr("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
   251                                p2i((void *) mon_info->owner()),
   229                       p2i((void *) mon_info->owner()),
   252                                p2i((void *) obj));
   230                       p2i((void *) obj));
       
   231       }
       
   232     }
   253     }
   233   }
   254   }
   234   if (highest_lock != NULL) {
   255   if (highest_lock != NULL) {
   235     // Fix up highest lock to contain displaced header and point
   256     // Fix up highest lock to contain displaced header and point
   236     // object at it
   257     // object at it
   238     // Reset object header to point to displaced mark.
   259     // Reset object header to point to displaced mark.
   239     // Must release storing the lock address for platforms without TSO
   260     // Must release storing the lock address for platforms without TSO
   240     // ordering (e.g. ppc).
   261     // ordering (e.g. ppc).
   241     obj->release_set_mark(markOopDesc::encode(highest_lock));
   262     obj->release_set_mark(markOopDesc::encode(highest_lock));
   242     assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
   263     assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
   243     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
   264     // Log at "info" level if not bulk, else "trace" level
   244       tty->print_cr("  Revoked bias of currently-locked object");
   265     if (!is_bulk) {
       
   266       log_info(biasedlocking)("  Revoked bias of currently-locked object");
       
   267     } else {
       
   268       log_trace(biasedlocking)("  Revoked bias of currently-locked object");
   245     }
   269     }
   246   } else {
   270   } else {
   247     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
   271     // Log at "info" level if not bulk, else "trace" level
   248       tty->print_cr("  Revoked bias of currently-unlocked object");
   272     if (!is_bulk) {
       
   273       log_info(biasedlocking)("  Revoked bias of currently-unlocked object");
       
   274     } else {
       
   275       log_trace(biasedlocking)("  Revoked bias of currently-unlocked object");
   249     }
   276     }
   250     if (allow_rebias) {
   277     if (allow_rebias) {
   251       obj->set_mark(biased_prototype);
   278       obj->set_mark(biased_prototype);
   252     } else {
   279     } else {
   253       // Store the unlocked value into the object's header.
   280       // Store the unlocked value into the object's header.
   324                                                                    bool bulk_rebias,
   351                                                                    bool bulk_rebias,
   325                                                                    bool attempt_rebias_of_object,
   352                                                                    bool attempt_rebias_of_object,
   326                                                                    JavaThread* requesting_thread) {
   353                                                                    JavaThread* requesting_thread) {
   327   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
   354   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
   328 
   355 
   329   if (TraceBiasedLocking) {
   356   log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object "
   330     tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
   357                           INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
   331                   INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
   358                           (bulk_rebias ? "rebias" : "revoke"),
   332                   (bulk_rebias ? "rebias" : "revoke"),
   359                           p2i((void *) o),
   333                   p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name());
   360                           (intptr_t) o->mark(),
   334   }
   361                           o->klass()->external_name());
   335 
   362 
   336   jlong cur_time = os::javaTimeMillis();
   363   jlong cur_time = os::javaTimeMillis();
   337   o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
   364   o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
   338 
   365 
   339 
   366 
   375 
   402 
   376     // At this point we're done. All we have to do is potentially
   403     // At this point we're done. All we have to do is potentially
   377     // adjust the header of the given object to revoke its bias.
   404     // adjust the header of the given object to revoke its bias.
   378     revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread);
   405     revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread);
   379   } else {
   406   } else {
   380     if (TraceBiasedLocking) {
   407     if (log_is_enabled(Info, biasedlocking)) {
   381       ResourceMark rm;
   408       ResourceMark rm;
   382       tty->print_cr("* Disabling biased locking for type %s", klass->external_name());
   409       log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
   383     }
   410     }
   384 
   411 
   385     // Disable biased locking for this data type. Not only will this
   412     // Disable biased locking for this data type. Not only will this
   386     // cause future instances to not be biased, but existing biased
   413     // cause future instances to not be biased, but existing biased
   387     // instances will notice that this implicitly caused their biases
   414     // instances will notice that this implicitly caused their biases
   405     // Must force the bias of the passed object to be forcibly revoked
   432     // Must force the bias of the passed object to be forcibly revoked
   406     // as well to ensure guarantees to callers
   433     // as well to ensure guarantees to callers
   407     revoke_bias(o, false, true, requesting_thread);
   434     revoke_bias(o, false, true, requesting_thread);
   408   }
   435   }
   409 
   436 
   410   if (TraceBiasedLocking) {
   437   log_info(biasedlocking)("* Ending bulk revocation");
   411     tty->print_cr("* Ending bulk revocation");
       
   412   }
       
   413 
   438 
   414   BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
   439   BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
   415 
   440 
   416   if (attempt_rebias_of_object &&
   441   if (attempt_rebias_of_object &&
   417       o->mark()->has_bias_pattern() &&
   442       o->mark()->has_bias_pattern() &&
   418       klass->prototype_header()->has_bias_pattern()) {
   443       klass->prototype_header()->has_bias_pattern()) {
   419     markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(),
   444     markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(),
   420                                            klass->prototype_header()->bias_epoch());
   445                                            klass->prototype_header()->bias_epoch());
   421     o->set_mark(new_mark);
   446     o->set_mark(new_mark);
   422     status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
   447     status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
   423     if (TraceBiasedLocking) {
   448     log_info(biasedlocking)("  Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
   424       tty->print_cr("  Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
       
   425     }
       
   426   }
   449   }
   427 
   450 
   428   assert(!o->mark()->has_bias_pattern() ||
   451   assert(!o->mark()->has_bias_pattern() ||
   429          (attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)),
   452          (attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)),
   430          "bug in bulk bias revocation");
   453          "bug in bulk bias revocation");
   483     return false;
   506     return false;
   484   }
   507   }
   485 
   508 
   486   virtual void doit() {
   509   virtual void doit() {
   487     if (_obj != NULL) {
   510     if (_obj != NULL) {
   488       if (TraceBiasedLocking) {
   511       log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
   489         tty->print_cr("Revoking bias with potentially per-thread safepoint:");
       
   490       }
       
   491       _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread);
   512       _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread);
   492       clean_up_cached_monitor_info();
   513       clean_up_cached_monitor_info();
   493       return;
   514       return;
   494     } else {
   515     } else {
   495       if (TraceBiasedLocking) {
   516       log_info(biasedlocking)("Revoking bias with global safepoint:");
   496         tty->print_cr("Revoking bias with global safepoint:");
       
   497       }
       
   498       BiasedLocking::revoke_at_safepoint(_objs);
   517       BiasedLocking::revoke_at_safepoint(_objs);
   499     }
   518     }
   500   }
   519   }
   501 
   520 
   502   BiasedLocking::Condition status_code() const {
   521   BiasedLocking::Condition status_code() const {
   606       // reach no safepoints in the revocation path.
   625       // reach no safepoints in the revocation path.
   607       // Also check the epoch because even if threads match, another thread
   626       // Also check the epoch because even if threads match, another thread
   608       // can come in with a CAS to steal the bias of an object that has a
   627       // can come in with a CAS to steal the bias of an object that has a
   609       // stale epoch.
   628       // stale epoch.
   610       ResourceMark rm;
   629       ResourceMark rm;
   611       if (TraceBiasedLocking) {
   630       log_info(biasedlocking)("Revoking bias by walking my own stack:");
   612         tty->print_cr("Revoking bias by walking my own stack:");
       
   613       }
       
   614       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD);
   631       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD);
   615       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
   632       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
   616       assert(cond == BIAS_REVOKED, "why not?");
   633       assert(cond == BIAS_REVOKED, "why not?");
   617       return cond;
   634       return cond;
   618     } else {
   635     } else {