src/hotspot/share/runtime/biasedLocking.cpp
changeset 47764 029d5efaaa6c
parent 47632 0c2e1f8eccaa
child 48105 8d15b1369c7a
equal deleted inserted replaced
47763:08fa85a36a67 47764:029d5efaaa6c
   143 
   143 
   144   thread->set_cached_monitor_info(info);
   144   thread->set_cached_monitor_info(info);
   145   return info;
   145   return info;
   146 }
   146 }
   147 
   147 
   148 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
   148 // After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL,
       
   149 // AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization).
       
   150 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
   149   markOop mark = obj->mark();
   151   markOop mark = obj->mark();
   150   if (!mark->has_bias_pattern()) {
   152   if (!mark->has_bias_pattern()) {
   151     if (log_is_enabled(Info, biasedlocking)) {
   153     if (log_is_enabled(Info, biasedlocking)) {
   152       ResourceMark rm;
   154       ResourceMark rm;
   153       log_info(biasedlocking)("  (Skipping revocation of object " INTPTR_FORMAT
   155       log_info(biasedlocking)("  (Skipping revocation of object " INTPTR_FORMAT
   294       obj->set_mark(biased_prototype);
   296       obj->set_mark(biased_prototype);
   295     } else {
   297     } else {
   296       // Store the unlocked value into the object's header.
   298       // Store the unlocked value into the object's header.
   297       obj->set_mark(unbiased_prototype);
   299       obj->set_mark(unbiased_prototype);
   298     }
   300     }
       
   301   }
       
   302 
       
   303   // If requested, return information on which thread held the bias
       
   304   if (biased_locker != NULL) {
       
   305     *biased_locker = biased_thread;
   299   }
   306   }
   300 
   307 
   301   return BiasedLocking::BIAS_REVOKED;
   308   return BiasedLocking::BIAS_REVOKED;
   302 }
   309 }
   303 
   310 
   416       }
   423       }
   417     }
   424     }
   418 
   425 
   419     // At this point we're done. All we have to do is potentially
   426     // At this point we're done. All we have to do is potentially
   420     // adjust the header of the given object to revoke its bias.
   427     // adjust the header of the given object to revoke its bias.
   421     revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread);
   428     revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
   422   } else {
   429   } else {
   423     if (log_is_enabled(Info, biasedlocking)) {
   430     if (log_is_enabled(Info, biasedlocking)) {
   424       ResourceMark rm;
   431       ResourceMark rm;
   425       log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
   432       log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
   426     }
   433     }
   438       for (int i = 0; i < cached_monitor_info->length(); i++) {
   445       for (int i = 0; i < cached_monitor_info->length(); i++) {
   439         MonitorInfo* mon_info = cached_monitor_info->at(i);
   446         MonitorInfo* mon_info = cached_monitor_info->at(i);
   440         oop owner = mon_info->owner();
   447         oop owner = mon_info->owner();
   441         markOop mark = owner->mark();
   448         markOop mark = owner->mark();
   442         if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
   449         if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
   443           revoke_bias(owner, false, true, requesting_thread);
   450           revoke_bias(owner, false, true, requesting_thread, NULL);
   444         }
   451         }
   445       }
   452       }
   446     }
   453     }
   447 
   454 
   448     // Must force the bias of the passed object to be forcibly revoked
   455     // Must force the bias of the passed object to be forcibly revoked
   449     // as well to ensure guarantees to callers
   456     // as well to ensure guarantees to callers
   450     revoke_bias(o, false, true, requesting_thread);
   457     revoke_bias(o, false, true, requesting_thread, NULL);
   451   }
   458   }
   452 
   459 
   453   log_info(biasedlocking)("* Ending bulk revocation");
   460   log_info(biasedlocking)("* Ending bulk revocation");
   454 
   461 
   455   BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
   462   BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
   484 protected:
   491 protected:
   485   Handle* _obj;
   492   Handle* _obj;
   486   GrowableArray<Handle>* _objs;
   493   GrowableArray<Handle>* _objs;
   487   JavaThread* _requesting_thread;
   494   JavaThread* _requesting_thread;
   488   BiasedLocking::Condition _status_code;
   495   BiasedLocking::Condition _status_code;
       
   496   traceid _biased_locker_id;
   489 
   497 
   490 public:
   498 public:
   491   VM_RevokeBias(Handle* obj, JavaThread* requesting_thread)
   499   VM_RevokeBias(Handle* obj, JavaThread* requesting_thread)
   492     : _obj(obj)
   500     : _obj(obj)
   493     , _objs(NULL)
   501     , _objs(NULL)
   494     , _requesting_thread(requesting_thread)
   502     , _requesting_thread(requesting_thread)
   495     , _status_code(BiasedLocking::NOT_BIASED) {}
   503     , _status_code(BiasedLocking::NOT_BIASED)
       
   504     , _biased_locker_id(0) {}
   496 
   505 
   497   VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread)
   506   VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread)
   498     : _obj(NULL)
   507     : _obj(NULL)
   499     , _objs(objs)
   508     , _objs(objs)
   500     , _requesting_thread(requesting_thread)
   509     , _requesting_thread(requesting_thread)
   501     , _status_code(BiasedLocking::NOT_BIASED) {}
   510     , _status_code(BiasedLocking::NOT_BIASED)
       
   511     , _biased_locker_id(0) {}
   502 
   512 
   503   virtual VMOp_Type type() const { return VMOp_RevokeBias; }
   513   virtual VMOp_Type type() const { return VMOp_RevokeBias; }
   504 
   514 
   505   virtual bool doit_prologue() {
   515   virtual bool doit_prologue() {
   506     // Verify that there is actual work to do since the callers just
   516     // Verify that there is actual work to do since the callers just
   523   }
   533   }
   524 
   534 
   525   virtual void doit() {
   535   virtual void doit() {
   526     if (_obj != NULL) {
   536     if (_obj != NULL) {
   527       log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
   537       log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
   528       _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread);
   538       JavaThread* biased_locker = NULL;
       
   539       _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker);
       
   540       if (biased_locker != NULL) {
       
   541         _biased_locker_id = THREAD_TRACE_ID(biased_locker);
       
   542       }
   529       clean_up_cached_monitor_info();
   543       clean_up_cached_monitor_info();
   530       return;
   544       return;
   531     } else {
   545     } else {
   532       log_info(biasedlocking)("Revoking bias with global safepoint:");
   546       log_info(biasedlocking)("Revoking bias with global safepoint:");
   533       BiasedLocking::revoke_at_safepoint(_objs);
   547       BiasedLocking::revoke_at_safepoint(_objs);
   534     }
   548     }
   535   }
   549   }
   536 
   550 
   537   BiasedLocking::Condition status_code() const {
   551   BiasedLocking::Condition status_code() const {
   538     return _status_code;
   552     return _status_code;
       
   553   }
       
   554 
       
   555   traceid biased_locker() const {
       
   556     return _biased_locker_id;
   539   }
   557   }
   540 };
   558 };
   541 
   559 
   542 
   560 
   543 class VM_BulkRevokeBias : public VM_RevokeBias {
   561 class VM_BulkRevokeBias : public VM_RevokeBias {
   643       // can come in with a CAS to steal the bias of an object that has a
   661       // can come in with a CAS to steal the bias of an object that has a
   644       // stale epoch.
   662       // stale epoch.
   645       ResourceMark rm;
   663       ResourceMark rm;
   646       log_info(biasedlocking)("Revoking bias by walking my own stack:");
   664       log_info(biasedlocking)("Revoking bias by walking my own stack:");
   647       EventBiasedLockSelfRevocation event;
   665       EventBiasedLockSelfRevocation event;
   648       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD);
   666       BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
   649       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
   667       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
   650       assert(cond == BIAS_REVOKED, "why not?");
   668       assert(cond == BIAS_REVOKED, "why not?");
   651       if (event.should_commit()) {
   669       if (event.should_commit()) {
   652         event.set_lockClass(k);
   670         event.set_lockClass(k);
   653         event.commit();
   671         event.commit();
   659       VMThread::execute(&revoke);
   677       VMThread::execute(&revoke);
   660       if (event.should_commit() && (revoke.status_code() != NOT_BIASED)) {
   678       if (event.should_commit() && (revoke.status_code() != NOT_BIASED)) {
   661         event.set_lockClass(k);
   679         event.set_lockClass(k);
   662         // Subtract 1 to match the id of events committed inside the safepoint
   680         // Subtract 1 to match the id of events committed inside the safepoint
   663         event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1);
   681         event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1);
       
   682         event.set_previousOwner(revoke.biased_locker());
   664         event.commit();
   683         event.commit();
   665       }
   684       }
   666       return revoke.status_code();
   685       return revoke.status_code();
   667     }
   686     }
   668   }
   687   }
   698 void BiasedLocking::revoke_at_safepoint(Handle h_obj) {
   717 void BiasedLocking::revoke_at_safepoint(Handle h_obj) {
   699   assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
   718   assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
   700   oop obj = h_obj();
   719   oop obj = h_obj();
   701   HeuristicsResult heuristics = update_heuristics(obj, false);
   720   HeuristicsResult heuristics = update_heuristics(obj, false);
   702   if (heuristics == HR_SINGLE_REVOKE) {
   721   if (heuristics == HR_SINGLE_REVOKE) {
   703     revoke_bias(obj, false, false, NULL);
   722     revoke_bias(obj, false, false, NULL, NULL);
   704   } else if ((heuristics == HR_BULK_REBIAS) ||
   723   } else if ((heuristics == HR_BULK_REBIAS) ||
   705              (heuristics == HR_BULK_REVOKE)) {
   724              (heuristics == HR_BULK_REVOKE)) {
   706     bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
   725     bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
   707   }
   726   }
   708   clean_up_cached_monitor_info();
   727   clean_up_cached_monitor_info();
   714   int len = objs->length();
   733   int len = objs->length();
   715   for (int i = 0; i < len; i++) {
   734   for (int i = 0; i < len; i++) {
   716     oop obj = (objs->at(i))();
   735     oop obj = (objs->at(i))();
   717     HeuristicsResult heuristics = update_heuristics(obj, false);
   736     HeuristicsResult heuristics = update_heuristics(obj, false);
   718     if (heuristics == HR_SINGLE_REVOKE) {
   737     if (heuristics == HR_SINGLE_REVOKE) {
   719       revoke_bias(obj, false, false, NULL);
   738       revoke_bias(obj, false, false, NULL, NULL);
   720     } else if ((heuristics == HR_BULK_REBIAS) ||
   739     } else if ((heuristics == HR_BULK_REBIAS) ||
   721                (heuristics == HR_BULK_REVOKE)) {
   740                (heuristics == HR_BULK_REVOKE)) {
   722       bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
   741       bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
   723     }
   742     }
   724   }
   743   }