src/share/vm/runtime/biasedLocking.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/runtime

src/share/vm/runtime/biasedLocking.cpp

Print this page




 144 
 145 
 146 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
 147   markOop mark = obj->mark();
 148   if (!mark->has_bias_pattern()) {
 149     if (TraceBiasedLocking) {
 150       ResourceMark rm;
 151       tty->print_cr("  (Skipping revocation of object of type %s because it's no longer biased)",
 152                     obj->klass()->external_name());
 153     }
 154     return BiasedLocking::NOT_BIASED;
 155   }
 156 
 157   uint age = mark->age();
 158   markOop   biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
 159   markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
 160 
 161   if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 162     ResourceMark rm;
 163     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,
 164                   (void *)obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
 165   }
 166 
 167   JavaThread* biased_thread = mark->biased_locker();
 168   if (biased_thread == NULL) {
 169     // Object is anonymously biased. We can get here if, for
 170     // example, we revoke the bias due to an identity hash code
 171     // being computed for an object.
 172     if (!allow_rebias) {
 173       obj->set_mark(unbiased_prototype);
 174     }
 175     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 176       tty->print_cr("  Revoked bias of anonymously-biased object");
 177     }
 178     return BiasedLocking::BIAS_REVOKED;
 179   }
 180 
 181   // Handle case where the thread toward which the object was biased has exited
 182   bool thread_is_alive = false;
 183   if (requesting_thread == biased_thread) {
 184     thread_is_alive = true;


 197       obj->set_mark(unbiased_prototype);
 198     }
 199     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 200       tty->print_cr("  Revoked bias of object biased toward dead thread");
 201     }
 202     return BiasedLocking::BIAS_REVOKED;
 203   }
 204 
 205   // Thread owning bias is alive.
 206   // Check to see whether it currently owns the lock and, if so,
 207   // write down the needed displaced headers to the thread's stack.
 208   // Otherwise, restore the object's header either to the unlocked
 209   // or unbiased state.
 210   GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
 211   BasicLock* highest_lock = NULL;
 212   for (int i = 0; i < cached_monitor_info->length(); i++) {
 213     MonitorInfo* mon_info = cached_monitor_info->at(i);
 214     if (mon_info->owner() == obj) {
 215       if (TraceBiasedLocking && Verbose) {
 216         tty->print_cr("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
 217                       (void *) mon_info->owner(),
 218                       (void *) obj);
 219       }
 220       // Assume recursive case and fix up highest lock later
 221       markOop mark = markOopDesc::encode((BasicLock*) NULL);
 222       highest_lock = mon_info->lock();
 223       highest_lock->set_displaced_header(mark);
 224     } else {
 225       if (TraceBiasedLocking && Verbose) {
 226         tty->print_cr("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
 227                       (void *) mon_info->owner(),
 228                       (void *) obj);
 229       }
 230     }
 231   }
 232   if (highest_lock != NULL) {
 233     // Fix up highest lock to contain displaced header and point
 234     // object at it
 235     highest_lock->set_displaced_header(unbiased_prototype);
 236     // Reset object header to point to displaced mark.
 237     // Must release storing the lock address for platforms without TSO
 238     // ordering (e.g. ppc).
 239     obj->release_set_mark(markOopDesc::encode(highest_lock));
 240     assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
 241     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 242       tty->print_cr("  Revoked bias of currently-locked object");
 243     }
 244   } else {
 245     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 246       tty->print_cr("  Revoked bias of currently-unlocked object");
 247     }
 248     if (allow_rebias) {


 311   }
 312 
 313   if (revocation_count == BiasedLockingBulkRebiasThreshold) {
 314     return HR_BULK_REBIAS;
 315   }
 316 
 317   return HR_SINGLE_REVOKE;
 318 }
 319 
 320 
 321 static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
 322                                                                    bool bulk_rebias,
 323                                                                    bool attempt_rebias_of_object,
 324                                                                    JavaThread* requesting_thread) {
 325   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
 326 
 327   if (TraceBiasedLocking) {
 328     tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
 329                   INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
 330                   (bulk_rebias ? "rebias" : "revoke"),
 331                   (void *) o, (intptr_t) o->mark(), o->klass()->external_name());
 332   }
 333 
 334   jlong cur_time = os::javaTimeMillis();
 335   o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
 336 
 337 
 338   Klass* k_o = o->klass();
 339   Klass* klass = k_o;
 340 
 341   if (bulk_rebias) {
 342     // Use the epoch in the klass of the object to implicitly revoke
 343     // all biases of objects of this data type and force them to be
 344     // reacquired. However, we also need to walk the stacks of all
 345     // threads and update the headers of lightweight locked objects
 346     // with biases to have the current epoch.
 347 
 348     // If the prototype header doesn't have the bias pattern, don't
 349     // try to update the epoch -- assume another VM operation came in
 350     // and reset the header to the unbiased state, which will
 351     // implicitly cause all existing biases to be revoked




 144 
 145 
 146 static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
 147   markOop mark = obj->mark();
 148   if (!mark->has_bias_pattern()) {
 149     if (TraceBiasedLocking) {
 150       ResourceMark rm;
 151       tty->print_cr("  (Skipping revocation of object of type %s because it's no longer biased)",
 152                     obj->klass()->external_name());
 153     }
 154     return BiasedLocking::NOT_BIASED;
 155   }
 156 
 157   uint age = mark->age();
 158   markOop   biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
 159   markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
 160 
 161   if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 162     ResourceMark rm;
 163     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,
 164                   p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
 165   }
 166 
 167   JavaThread* biased_thread = mark->biased_locker();
 168   if (biased_thread == NULL) {
 169     // Object is anonymously biased. We can get here if, for
 170     // example, we revoke the bias due to an identity hash code
 171     // being computed for an object.
 172     if (!allow_rebias) {
 173       obj->set_mark(unbiased_prototype);
 174     }
 175     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 176       tty->print_cr("  Revoked bias of anonymously-biased object");
 177     }
 178     return BiasedLocking::BIAS_REVOKED;
 179   }
 180 
 181   // Handle case where the thread toward which the object was biased has exited
 182   bool thread_is_alive = false;
 183   if (requesting_thread == biased_thread) {
 184     thread_is_alive = true;


 197       obj->set_mark(unbiased_prototype);
 198     }
 199     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 200       tty->print_cr("  Revoked bias of object biased toward dead thread");
 201     }
 202     return BiasedLocking::BIAS_REVOKED;
 203   }
 204 
 205   // Thread owning bias is alive.
 206   // Check to see whether it currently owns the lock and, if so,
 207   // write down the needed displaced headers to the thread's stack.
 208   // Otherwise, restore the object's header either to the unlocked
 209   // or unbiased state.
 210   GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
 211   BasicLock* highest_lock = NULL;
 212   for (int i = 0; i < cached_monitor_info->length(); i++) {
 213     MonitorInfo* mon_info = cached_monitor_info->at(i);
 214     if (mon_info->owner() == obj) {
 215       if (TraceBiasedLocking && Verbose) {
 216         tty->print_cr("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
 217                       p2i((void *) mon_info->owner()),
 218                       p2i((void *) obj));
 219       }
 220       // Assume recursive case and fix up highest lock later
 221       markOop mark = markOopDesc::encode((BasicLock*) NULL);
 222       highest_lock = mon_info->lock();
 223       highest_lock->set_displaced_header(mark);
 224     } else {
 225       if (TraceBiasedLocking && Verbose) {
 226         tty->print_cr("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
 227                       p2i((void *) mon_info->owner()),
 228                       p2i((void *) obj));
 229       }
 230     }
 231   }
 232   if (highest_lock != NULL) {
 233     // Fix up highest lock to contain displaced header and point
 234     // object at it
 235     highest_lock->set_displaced_header(unbiased_prototype);
 236     // Reset object header to point to displaced mark.
 237     // Must release storing the lock address for platforms without TSO
 238     // ordering (e.g. ppc).
 239     obj->release_set_mark(markOopDesc::encode(highest_lock));
 240     assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
 241     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 242       tty->print_cr("  Revoked bias of currently-locked object");
 243     }
 244   } else {
 245     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
 246       tty->print_cr("  Revoked bias of currently-unlocked object");
 247     }
 248     if (allow_rebias) {


 311   }
 312 
 313   if (revocation_count == BiasedLockingBulkRebiasThreshold) {
 314     return HR_BULK_REBIAS;
 315   }
 316 
 317   return HR_SINGLE_REVOKE;
 318 }
 319 
 320 
 321 static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
 322                                                                    bool bulk_rebias,
 323                                                                    bool attempt_rebias_of_object,
 324                                                                    JavaThread* requesting_thread) {
 325   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
 326 
 327   if (TraceBiasedLocking) {
 328     tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
 329                   INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
 330                   (bulk_rebias ? "rebias" : "revoke"),
 331                   p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name());
 332   }
 333 
 334   jlong cur_time = os::javaTimeMillis();
 335   o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
 336 
 337 
 338   Klass* k_o = o->klass();
 339   Klass* klass = k_o;
 340 
 341   if (bulk_rebias) {
 342     // Use the epoch in the klass of the object to implicitly revoke
 343     // all biases of objects of this data type and force them to be
 344     // reacquired. However, we also need to walk the stacks of all
 345     // threads and update the headers of lightweight locked objects
 346     // with biases to have the current epoch.
 347 
 348     // If the prototype header doesn't have the bias pattern, don't
 349     // try to update the epoch -- assume another VM operation came in
 350     // and reset the header to the unbiased state, which will
 351     // implicitly cause all existing biases to be revoked


src/share/vm/runtime/biasedLocking.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File