Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp
38921 views
/*1* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "gc_implementation/parallelScavenge/asPSOldGen.hpp"26#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"27#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"28#include "gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp"29#include "memory/cardTableModRefBS.hpp"30#include "oops/oop.inline.hpp"31#include "runtime/java.hpp"3233// Whereas PSOldGen takes the maximum size of the generation34// (which doesn't change in the case of PSOldGen) as a parameter,35// ASPSOldGen takes the upper limit on the size of36// the generation as a parameter. In ASPSOldGen the37// maximum size of the generation can change as the boundary38// moves. The "maximum size of the generation" is still a valid39// concept since the generation can grow and shrink within that40// maximum. There are lots of useful checks that use that41// maximum. In PSOldGen the method max_gen_size() returns42// _max_gen_size (as set by the PSOldGen constructor). This43// is how it always worked. In ASPSOldGen max_gen_size()44// returned the size of the reserved space for the generation.45// That can change as the boundary moves. Below the limit of46// the size of the generation is passed to the PSOldGen constructor47// for "_max_gen_size" (have to pass something) but it is not used later.48//49ASPSOldGen::ASPSOldGen(size_t initial_size,50size_t min_size,51size_t size_limit,52const char* gen_name,53int level) :54PSOldGen(initial_size, min_size, size_limit, gen_name, level),55_gen_size_limit(size_limit)56{}5758ASPSOldGen::ASPSOldGen(PSVirtualSpace* vs,59size_t initial_size,60size_t min_size,61size_t size_limit,62const char* gen_name,63int level) :64PSOldGen(initial_size, min_size, size_limit, gen_name, level),65_gen_size_limit(size_limit)66{67_virtual_space = vs;68}6970void ASPSOldGen::initialize_work(const char* perf_data_name, int level) {71PSOldGen::initialize_work(perf_data_name, level);7273// The old gen can grow to gen_size_limit(). _reserve reflects only74// the current maximum that can be committed.75assert(_reserved.byte_size() <= gen_size_limit(), "Consistency check");7677initialize_performance_counters(perf_data_name, level);78}7980void ASPSOldGen::reset_after_change() {81_reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),82(HeapWord*)virtual_space()->high_boundary());83post_resize();84}858687size_t ASPSOldGen::available_for_expansion() {88assert(virtual_space()->is_aligned(gen_size_limit()), "not aligned");89assert(gen_size_limit() >= virtual_space()->committed_size(), "bad gen size");9091ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();92size_t result = gen_size_limit() - virtual_space()->committed_size();93size_t result_aligned = align_size_down(result, heap->generation_alignment());94return result_aligned;95}9697size_t ASPSOldGen::available_for_contraction() {98size_t uncommitted_bytes = virtual_space()->uncommitted_size();99if (uncommitted_bytes != 0) {100return uncommitted_bytes;101}102103ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();104const size_t gen_alignment = heap->generation_alignment();105PSAdaptiveSizePolicy* policy = heap->size_policy();106const size_t working_size =107used_in_bytes() + (size_t) policy->avg_promoted()->padded_average();108const size_t working_aligned = align_size_up(working_size, gen_alignment);109const size_t working_or_min = MAX2(working_aligned, min_gen_size());110if (working_or_min > reserved().byte_size()) {111// If the used or minimum gen size (aligned up) is greater112// than the total reserved size, then the space available113// for contraction should (after proper alignment) be 0114return 0;115}116const size_t max_contraction =117reserved().byte_size() - working_or_min;118119// Use the "increment" fraction instead of the "decrement" fraction120// to allow the other gen to expand more aggressively. The121// "decrement" fraction is conservative because its intent is to122// only reduce the footprint.123124size_t result = policy->promo_increment_aligned_down(max_contraction);125// Also adjust for inter-generational alignment126size_t result_aligned = align_size_down(result, gen_alignment);127if (PrintAdaptiveSizePolicy && Verbose) {128gclog_or_tty->print_cr("\nASPSOldGen::available_for_contraction:"129" " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX, (result_aligned/K), result_aligned);130gclog_or_tty->print_cr(" reserved().byte_size() " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX " ",131(reserved().byte_size()/K), reserved().byte_size());132size_t working_promoted = (size_t) policy->avg_promoted()->padded_average();133gclog_or_tty->print_cr(" padded promoted " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX,134(working_promoted/K), working_promoted);135gclog_or_tty->print_cr(" used " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX,136(used_in_bytes()/K), used_in_bytes());137gclog_or_tty->print_cr(" min_gen_size() " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX,138(min_gen_size()/K), min_gen_size());139gclog_or_tty->print_cr(" max_contraction " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX,140(max_contraction/K), max_contraction);141gclog_or_tty->print_cr(" without alignment " SSIZE_FORMAT " K / " SIZE_FORMAT_HEX,142(policy->promo_increment(max_contraction)/K),143policy->promo_increment(max_contraction));144gclog_or_tty->print_cr(" alignment " SIZE_FORMAT_HEX, gen_alignment);145}146assert(result_aligned <= max_contraction, "arithmetic is wrong");147return result_aligned;148}149150151