6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data

Deprecated HandlePromotionFailure, removing the ability to turn off that feature, did away with one epoch look-ahead when deciding if a scavenge is likely to fail, relying on current data.

Reviewed-by: jmasa, johnc, poonam
This commit is contained in:
Y. Srinivas Ramakrishna 2010-10-23 23:03:49 -07:00
parent 554e77efb4
commit cbc7f8756a
14 changed files with 101 additions and 222 deletions

View file

@ -510,7 +510,7 @@ void DefNewGeneration::collect(bool full,
// from this generation, pass on collection; let the next generation
// do it.
if (!collection_attempt_is_safe()) {
gch->set_incremental_collection_will_fail();
gch->set_incremental_collection_failed(); // Slight lie: we did not even attempt one
return;
}
assert(to()->is_empty(), "Else not collection_attempt_is_safe");
@ -596,9 +596,8 @@ void DefNewGeneration::collect(bool full,
if (PrintGC && !PrintGCDetails) {
gch->print_heap_change(gch_prev_used);
}
assert(!gch->incremental_collection_failed(), "Should be clear");
} else {
assert(HandlePromotionFailure,
"Should not be here unless promotion failure handling is on");
assert(_promo_failure_scan_stack.is_empty(), "post condition");
_promo_failure_scan_stack.clear(true); // Clear cached segments.
@ -613,7 +612,7 @@ void DefNewGeneration::collect(bool full,
// and from-space.
swap_spaces(); // For uniformity wrt ParNewGeneration.
from()->set_next_compaction_space(to());
gch->set_incremental_collection_will_fail();
gch->set_incremental_collection_failed();
// Inform the next generation that a promotion failure occurred.
_next_gen->promotion_failure_occurred();
@ -700,12 +699,6 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) {
if (obj == NULL) {
obj = _next_gen->promote(old, s);
if (obj == NULL) {
if (!HandlePromotionFailure) {
// A failed promotion likely means the MaxLiveObjectEvacuationRatio flag
// is incorrectly set. In any case, its seriously wrong to be here!
vm_exit_out_of_memory(s*wordSize, "promotion");
}
handle_promotion_failure(old);
return old;
}
@ -812,31 +805,7 @@ bool DefNewGeneration::collection_attempt_is_safe() {
assert(_next_gen != NULL,
"This must be the youngest gen, and not the only gen");
}
// Decide if there's enough room for a full promotion
// When using extremely large edens, we effectively lose a
// large amount of old space. Use the "MaxLiveObjectEvacuationRatio"
// flag to reduce the minimum evacuation space requirements. If
// there is not enough space to evacuate eden during a scavenge,
// the VM will immediately exit with an out of memory error.
// This flag has not been tested
// with collectors other than simple mark & sweep.
//
// Note that with the addition of promotion failure handling, the
// VM will not immediately exit but will undo the young generation
// collection. The parameter is left here for compatibility.
const double evacuation_ratio = MaxLiveObjectEvacuationRatio / 100.0;
// worst_case_evacuation is based on "used()". For the case where this
// method is called after a collection, this is still appropriate because
// the case that needs to be detected is one in which a full collection
// has been done and has overflowed into the young generation. In that
// case a minor collection will fail (the overflow of the full collection
// means there is no space in the old generation for any promotion).
size_t worst_case_evacuation = (size_t)(used() * evacuation_ratio);
return _next_gen->promotion_attempt_is_safe(worst_case_evacuation,
HandlePromotionFailure);
return _next_gen->promotion_attempt_is_safe(used());
}
void DefNewGeneration::gc_epilogue(bool full) {
@ -845,14 +814,17 @@ void DefNewGeneration::gc_epilogue(bool full) {
// a minimum at the end of a collection. If it is not, then
// the heap is approaching full.
GenCollectedHeap* gch = GenCollectedHeap::heap();
clear_should_allocate_from_space();
if (collection_attempt_is_safe()) {
gch->clear_incremental_collection_will_fail();
} else {
gch->set_incremental_collection_will_fail();
if (full) { // we seem to be running out of space
set_should_allocate_from_space();
if (full) {
assert(!GC_locker::is_active(), "We should not be executing here");
if (!collection_attempt_is_safe()) {
gch->set_incremental_collection_failed(); // Slight lie: a full gc left us in that state
set_should_allocate_from_space(); // we seem to be running out of space
} else {
gch->clear_incremental_collection_failed(); // We just did a full collection
clear_should_allocate_from_space(); // if set
}
} else {
assert(!gch->incremental_collection_failed(), "Error");
}
if (ZapUnusedHeapArea) {