// Similar to PSYoungGen::resize_generation() but // allows sum of eden_size and 2 * survivor_size to exceed _max_gen_size // expands at the low end of the virtual space // moves the boundary between the generations in order to expand // some additional diagnostics // If no additional changes are required, this can be deleted // and the changes factored back into PSYoungGen::resize_generation(). bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { const size_t alignment = virtual_space()->alignment(); size_t orig_size = virtual_space()->committed_size(); bool size_changed = false; // There used to be a guarantee here that // (eden_size + 2*survivor_size) <= _max_gen_size // This requirement is enforced by the calculation of desired_size // below. It may not be true on entry since the size of the // eden_size is no bounded by the generation size. assert(max_size() == reserved().byte_size(), "max gen size problem?"); assert(min_gen_size() <= orig_size && orig_size <= max_size(), "just checking"); // Adjust new generation size const size_t eden_plus_survivors = align_size_up(eden_size + 2 * survivor_size, alignment); size_t desired_size = MAX2(MIN2(eden_plus_survivors, gen_size_limit()), min_gen_size()); assert(desired_size <= gen_size_limit(), "just checking"); if (desired_size > orig_size) { // Grow the generation size_t change = desired_size - orig_size; HeapWord* prev_low = (HeapWord*) virtual_space()->low(); if (!virtual_space()->expand_by(change)) { return false; } if (ZapUnusedHeapArea) { // Mangle newly committed space immediately because it // can be done here more simply that after the new // spaces have been computed. HeapWord* new_low = (HeapWord*) virtual_space()->low(); assert(new_low < prev_low, "Did not grow"); MemRegion mangle_region(new_low, prev_low); SpaceMangler::mangle_region(mangle_region); } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; // How much is available for shrinking. size_t available_bytes = limit_gen_shrink(desired_change); size_t change = MIN2(desired_change, available_bytes); virtual_space()->shrink_by(change); size_changed = true; } else { if (Verbose && PrintGC) { if (orig_size == gen_size_limit()) { gclog_or_tty->print_cr("ASPSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K); } else if (orig_size == min_gen_size()) { gclog_or_tty->print_cr("ASPSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K); } } } if (size_changed) { reset_after_change(); if (Verbose && PrintGC) { size_t current_size = virtual_space()->committed_size(); gclog_or_tty->print_cr("ASPSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", orig_size/K, current_size/K); } } guarantee(eden_plus_survivors <= virtual_space()->committed_size() || virtual_space()->committed_size() == max_size(), "Sanity"); return true; }
bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { const size_t alignment = virtual_space()->alignment(); size_t orig_size = virtual_space()->committed_size(); bool size_changed = false; // There used to be this guarantee there. // guarantee ((eden_size + 2*survivor_size) <= _max_gen_size, "incorrect input arguments"); // Code below forces this requirement. In addition the desired eden // size and disired survivor sizes are desired goals and may // exceed the total generation size. assert(min_gen_size() <= orig_size && orig_size <= max_size(), "just checking"); // Adjust new generation size const size_t eden_plus_survivors = align_size_up(eden_size + 2 * survivor_size, alignment); size_t desired_size = MAX2(MIN2(eden_plus_survivors, max_size()), min_gen_size()); assert(desired_size <= max_size(), "just checking"); if (desired_size > orig_size) { // Grow the generation size_t change = desired_size - orig_size; assert(change % alignment == 0, "just checking"); HeapWord* prev_high = (HeapWord*) virtual_space()->high(); if (!virtual_space()->expand_by(change)) { return false; // Error if we fail to resize! } if (ZapUnusedHeapArea) { // Mangle newly committed space immediately because it // can be done here more simply that after the new // spaces have been computed. HeapWord* new_high = (HeapWord*) virtual_space()->high(); MemRegion mangle_region(prev_high, new_high); SpaceMangler::mangle_region(mangle_region); } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; assert(desired_change % alignment == 0, "just checking"); desired_change = limit_gen_shrink(desired_change); if (desired_change > 0) { virtual_space()->shrink_by(desired_change); reset_survivors_after_shrink(); size_changed = true; } } else { if (Verbose && PrintGC) { if (orig_size == gen_size_limit()) { gclog_or_tty->print_cr("PSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K); } else if (orig_size == min_gen_size()) { gclog_or_tty->print_cr("PSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K); } } } if (size_changed) { post_resize(); if (Verbose && PrintGC) { size_t current_size = virtual_space()->committed_size(); gclog_or_tty->print_cr("PSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", orig_size/K, current_size/K); } } guarantee(eden_plus_survivors <= virtual_space()->committed_size() || virtual_space()->committed_size() == max_size(), "Sanity"); return true; }
// Note that the the alignment used is the OS page size as // opposed to an alignment associated with the virtual space // (as is done in the ASPSYoungGen/ASPSOldGen) bool ASParNewGeneration::resize_generation(size_t eden_size, size_t survivor_size) { const size_t alignment = os::vm_page_size(); size_t orig_size = virtual_space()->committed_size(); bool size_changed = false; // There used to be this guarantee there. // guarantee ((eden_size + 2*survivor_size) <= _max_gen_size, "incorrect input arguments"); // Code below forces this requirement. In addition the desired eden // size and disired survivor sizes are desired goals and may // exceed the total generation size. assert(min_gen_size() <= orig_size && orig_size <= max_gen_size(), "just checking"); // Adjust new generation size const size_t eden_plus_survivors = align_size_up(eden_size + 2 * survivor_size, alignment); size_t desired_size = MAX2(MIN2(eden_plus_survivors, max_gen_size()), min_gen_size()); assert(desired_size <= max_gen_size(), "just checking"); if (desired_size > orig_size) { // Grow the generation size_t change = desired_size - orig_size; assert(change % alignment == 0, "just checking"); if (expand(change)) { return false; // Error if we fail to resize! } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; assert(desired_change % alignment == 0, "just checking"); desired_change = limit_gen_shrink(desired_change); if (desired_change > 0) { virtual_space()->shrink_by(desired_change); reset_survivors_after_shrink(); size_changed = true; } } else { if (Verbose && PrintGC) { if (orig_size == max_gen_size()) { gclog_or_tty->print_cr("ASParNew generation size at maximum: " SIZE_FORMAT "K", orig_size/K); } else if (orig_size == min_gen_size()) { gclog_or_tty->print_cr("ASParNew generation size at minium: " SIZE_FORMAT "K", orig_size/K); } } } if (size_changed) { MemRegion cmr((HeapWord*)virtual_space()->low(), (HeapWord*)virtual_space()->high()); GenCollectedHeap::heap()->barrier_set()->resize_covered_region(cmr); if (Verbose && PrintGC) { size_t current_size = virtual_space()->committed_size(); gclog_or_tty->print_cr("ASParNew generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", orig_size/K, current_size/K); } } guarantee(eden_plus_survivors <= virtual_space()->committed_size() || virtual_space()->committed_size() == max_gen_size(), "Sanity"); return true; }