388 |
385 |
389 |
386 |
390 Klass* k_o = o->klass(); |
387 Klass* k_o = o->klass(); |
391 Klass* klass = k_o; |
388 Klass* klass = k_o; |
392 |
389 |
393 if (bulk_rebias) { |
390 { |
394 // Use the epoch in the klass of the object to implicitly revoke |
391 JavaThreadIteratorWithHandle jtiwh; |
395 // all biases of objects of this data type and force them to be |
392 |
396 // reacquired. However, we also need to walk the stacks of all |
393 if (bulk_rebias) { |
397 // threads and update the headers of lightweight locked objects |
394 // Use the epoch in the klass of the object to implicitly revoke |
398 // with biases to have the current epoch. |
395 // all biases of objects of this data type and force them to be |
399 |
396 // reacquired. However, we also need to walk the stacks of all |
400 // If the prototype header doesn't have the bias pattern, don't |
397 // threads and update the headers of lightweight locked objects |
401 // try to update the epoch -- assume another VM operation came in |
398 // with biases to have the current epoch. |
402 // and reset the header to the unbiased state, which will |
399 |
403 // implicitly cause all existing biases to be revoked |
400 // If the prototype header doesn't have the bias pattern, don't |
404 if (klass->prototype_header()->has_bias_pattern()) { |
401 // try to update the epoch -- assume another VM operation came in |
405 int prev_epoch = klass->prototype_header()->bias_epoch(); |
402 // and reset the header to the unbiased state, which will |
406 klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch()); |
403 // implicitly cause all existing biases to be revoked |
407 int cur_epoch = klass->prototype_header()->bias_epoch(); |
404 if (klass->prototype_header()->has_bias_pattern()) { |
408 |
405 int prev_epoch = klass->prototype_header()->bias_epoch(); |
409 // Now walk all threads' stacks and adjust epochs of any biased |
406 klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch()); |
410 // and locked objects of this data type we encounter |
407 int cur_epoch = klass->prototype_header()->bias_epoch(); |
411 for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) { |
408 |
|
409 // Now walk all threads' stacks and adjust epochs of any biased |
|
410 // and locked objects of this data type we encounter |
|
411 for (; JavaThread *thr = jtiwh.next(); ) { |
|
412 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr); |
|
413 for (int i = 0; i < cached_monitor_info->length(); i++) { |
|
414 MonitorInfo* mon_info = cached_monitor_info->at(i); |
|
415 oop owner = mon_info->owner(); |
|
416 markOop mark = owner->mark(); |
|
417 if ((owner->klass() == k_o) && mark->has_bias_pattern()) { |
|
418 // We might have encountered this object already in the case of recursive locking |
|
419 assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment"); |
|
420 owner->set_mark(mark->set_bias_epoch(cur_epoch)); |
|
421 } |
|
422 } |
|
423 } |
|
424 } |
|
425 |
|
426 // At this point we're done. All we have to do is potentially |
|
427 // adjust the header of the given object to revoke its bias. |
|
428 revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL); |
|
429 } else { |
|
430 if (log_is_enabled(Info, biasedlocking)) { |
|
431 ResourceMark rm; |
|
432 log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name()); |
|
433 } |
|
434 |
|
435 // Disable biased locking for this data type. Not only will this |
|
436 // cause future instances to not be biased, but existing biased |
|
437 // instances will notice that this implicitly caused their biases |
|
438 // to be revoked. |
|
439 klass->set_prototype_header(markOopDesc::prototype()); |
|
440 |
|
441 // Now walk all threads' stacks and forcibly revoke the biases of |
|
442 // any locked and biased objects of this data type we encounter. |
|
443 for (; JavaThread *thr = jtiwh.next(); ) { |
412 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr); |
444 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr); |
413 for (int i = 0; i < cached_monitor_info->length(); i++) { |
445 for (int i = 0; i < cached_monitor_info->length(); i++) { |
414 MonitorInfo* mon_info = cached_monitor_info->at(i); |
446 MonitorInfo* mon_info = cached_monitor_info->at(i); |
415 oop owner = mon_info->owner(); |
447 oop owner = mon_info->owner(); |
416 markOop mark = owner->mark(); |
448 markOop mark = owner->mark(); |
417 if ((owner->klass() == k_o) && mark->has_bias_pattern()) { |
449 if ((owner->klass() == k_o) && mark->has_bias_pattern()) { |
418 // We might have encountered this object already in the case of recursive locking |
450 revoke_bias(owner, false, true, requesting_thread, NULL); |
419 assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment"); |
|
420 owner->set_mark(mark->set_bias_epoch(cur_epoch)); |
|
421 } |
451 } |
422 } |
452 } |
423 } |
453 } |
424 } |
454 |
425 |
455 // Must force the bias of the passed object to be forcibly revoked |
426 // At this point we're done. All we have to do is potentially |
456 // as well to ensure guarantees to callers |
427 // adjust the header of the given object to revoke its bias. |
457 revoke_bias(o, false, true, requesting_thread, NULL); |
428 revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL); |
458 } |
429 } else { |
459 } // ThreadsListHandle is destroyed here. |
430 if (log_is_enabled(Info, biasedlocking)) { |
|
431 ResourceMark rm; |
|
432 log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name()); |
|
433 } |
|
434 |
|
435 // Disable biased locking for this data type. Not only will this |
|
436 // cause future instances to not be biased, but existing biased |
|
437 // instances will notice that this implicitly caused their biases |
|
438 // to be revoked. |
|
439 klass->set_prototype_header(markOopDesc::prototype()); |
|
440 |
|
441 // Now walk all threads' stacks and forcibly revoke the biases of |
|
442 // any locked and biased objects of this data type we encounter. |
|
443 for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) { |
|
444 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr); |
|
445 for (int i = 0; i < cached_monitor_info->length(); i++) { |
|
446 MonitorInfo* mon_info = cached_monitor_info->at(i); |
|
447 oop owner = mon_info->owner(); |
|
448 markOop mark = owner->mark(); |
|
449 if ((owner->klass() == k_o) && mark->has_bias_pattern()) { |
|
450 revoke_bias(owner, false, true, requesting_thread, NULL); |
|
451 } |
|
452 } |
|
453 } |
|
454 |
|
455 // Must force the bias of the passed object to be forcibly revoked |
|
456 // as well to ensure guarantees to callers |
|
457 revoke_bias(o, false, true, requesting_thread, NULL); |
|
458 } |
|
459 |
460 |
460 log_info(biasedlocking)("* Ending bulk revocation"); |
461 log_info(biasedlocking)("* Ending bulk revocation"); |
461 |
462 |
462 BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED; |
463 BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED; |
463 |
464 |