1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Dec 14 13:34:57 2011 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Dec 21 22:13:31 2011 +0100 1.3 @@ -136,7 +136,6 @@ 1.4 _stop_world_start(0.0), 1.5 _all_stop_world_times_ms(new NumberSeq()), 1.6 _all_yield_times_ms(new NumberSeq()), 1.7 - _using_new_ratio_calculations(false), 1.8 1.9 _summary(new Summary()), 1.10 1.11 @@ -409,11 +408,7 @@ 1.12 1.13 initialize_all(); 1.14 _collectionSetChooser = new CollectionSetChooser(); 1.15 -} 1.16 - 1.17 -// Increment "i", mod "len" 1.18 -static void inc_mod(int& i, int len) { 1.19 - i++; if (i == len) i = 0; 1.20 + _young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags 1.21 } 1.22 1.23 void G1CollectorPolicy::initialize_flags() { 1.24 @@ -425,71 +420,88 @@ 1.25 CollectorPolicy::initialize_flags(); 1.26 } 1.27 1.28 -// The easiest way to deal with the parsing of the NewSize / 1.29 -// MaxNewSize / etc. parameteres is to re-use the code in the 1.30 -// TwoGenerationCollectorPolicy class. This is similar to what 1.31 -// ParallelScavenge does with its GenerationSizer class (see 1.32 -// ParallelScavengeHeap::initialize()). We might change this in the 1.33 -// future, but it's a good start. 1.34 -class G1YoungGenSizer : public TwoGenerationCollectorPolicy { 1.35 -private: 1.36 - size_t size_to_region_num(size_t byte_size) { 1.37 - return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes); 1.38 - } 1.39 - 1.40 -public: 1.41 - G1YoungGenSizer() { 1.42 - initialize_flags(); 1.43 - initialize_size_info(); 1.44 - } 1.45 - size_t min_young_region_num() { 1.46 - return size_to_region_num(_min_gen0_size); 1.47 - } 1.48 - size_t initial_young_region_num() { 1.49 - return size_to_region_num(_initial_gen0_size); 1.50 - } 1.51 - size_t max_young_region_num() { 1.52 - return size_to_region_num(_max_gen0_size); 1.53 - } 1.54 -}; 1.55 - 1.56 -void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) { 1.57 - assert(number_of_heap_regions > 0, "Heap must be initialized"); 1.58 - size_t young_size = number_of_heap_regions / (NewRatio + 1); 1.59 - _min_desired_young_length = young_size; 1.60 - _max_desired_young_length = young_size; 1.61 -} 1.62 - 1.63 -void G1CollectorPolicy::init() { 1.64 - // Set aside an initial future to_space. 1.65 - _g1 = G1CollectedHeap::heap(); 1.66 - 1.67 - assert(Heap_lock->owned_by_self(), "Locking discipline."); 1.68 - 1.69 - initialize_gc_policy_counters(); 1.70 - 1.71 - G1YoungGenSizer sizer; 1.72 - _min_desired_young_length = sizer.min_young_region_num(); 1.73 - _max_desired_young_length = sizer.max_young_region_num(); 1.74 +G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true) { 1.75 + assert(G1DefaultMinNewGenPercent <= G1DefaultMaxNewGenPercent, "Min larger than max"); 1.76 + assert(G1DefaultMinNewGenPercent > 0 && G1DefaultMinNewGenPercent < 100, "Min out of bounds"); 1.77 + assert(G1DefaultMaxNewGenPercent > 0 && G1DefaultMaxNewGenPercent < 100, "Max out of bounds"); 1.78 1.79 if (FLAG_IS_CMDLINE(NewRatio)) { 1.80 if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) { 1.81 warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio"); 1.82 } else { 1.83 - // Treat NewRatio as a fixed size that is only recalculated when the heap size changes 1.84 - update_young_list_size_using_newratio(_g1->n_regions()); 1.85 - _using_new_ratio_calculations = true; 1.86 + _sizer_kind = SizerNewRatio; 1.87 + _adaptive_size = false; 1.88 + return; 1.89 } 1.90 } 1.91 1.92 + if (FLAG_IS_CMDLINE(NewSize)) { 1.93 + _min_desired_young_length = MAX2((size_t) 1, NewSize / HeapRegion::GrainBytes); 1.94 + if (FLAG_IS_CMDLINE(MaxNewSize)) { 1.95 + _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes); 1.96 + _sizer_kind = SizerMaxAndNewSize; 1.97 + _adaptive_size = _min_desired_young_length == _max_desired_young_length; 1.98 + } else { 1.99 + _sizer_kind = SizerNewSizeOnly; 1.100 + } 1.101 + } else if (FLAG_IS_CMDLINE(MaxNewSize)) { 1.102 + _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes); 1.103 + _sizer_kind = SizerMaxNewSizeOnly; 1.104 + } 1.105 +} 1.106 + 1.107 +size_t G1YoungGenSizer::calculate_default_min_length(size_t new_number_of_heap_regions) { 1.108 + size_t default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100; 1.109 + return MAX2((size_t)1, default_value); 1.110 +} 1.111 + 1.112 +size_t G1YoungGenSizer::calculate_default_max_length(size_t new_number_of_heap_regions) { 1.113 + size_t default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100; 1.114 + return MAX2((size_t)1, default_value); 1.115 +} 1.116 + 1.117 +void G1YoungGenSizer::heap_size_changed(size_t new_number_of_heap_regions) { 1.118 + assert(new_number_of_heap_regions > 0, "Heap must be initialized"); 1.119 + 1.120 + switch (_sizer_kind) { 1.121 + case SizerDefaults: 1.122 + _min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions); 1.123 + _max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions); 1.124 + break; 1.125 + case SizerNewSizeOnly: 1.126 + _max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions); 1.127 + _max_desired_young_length = MAX2(_min_desired_young_length, _max_desired_young_length); 1.128 + break; 1.129 + case SizerMaxNewSizeOnly: 1.130 + _min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions); 1.131 + _min_desired_young_length = MIN2(_min_desired_young_length, _max_desired_young_length); 1.132 + break; 1.133 + case SizerMaxAndNewSize: 1.134 + // Do nothing. Values set on the command line, don't update them at runtime. 1.135 + break; 1.136 + case SizerNewRatio: 1.137 + _min_desired_young_length = new_number_of_heap_regions / (NewRatio + 1); 1.138 + _max_desired_young_length = _min_desired_young_length; 1.139 + break; 1.140 + default: 1.141 + ShouldNotReachHere(); 1.142 + } 1.143 + 1.144 assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values"); 1.145 - 1.146 - set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length); 1.147 +} 1.148 + 1.149 +void G1CollectorPolicy::init() { 1.150 + // Set aside an initial future to_space. 1.151 + _g1 = G1CollectedHeap::heap(); 1.152 + 1.153 + assert(Heap_lock->owned_by_self(), "Locking discipline."); 1.154 + 1.155 + initialize_gc_policy_counters(); 1.156 + 1.157 if (adaptive_young_list_length()) { 1.158 _young_list_fixed_length = 0; 1.159 } else { 1.160 - assert(_min_desired_young_length == _max_desired_young_length, "Min and max young size differ"); 1.161 - _young_list_fixed_length = _min_desired_young_length; 1.162 + _young_list_fixed_length = _young_gen_sizer->min_desired_young_length(); 1.163 } 1.164 _free_regions_at_end_of_collection = _g1->free_regions(); 1.165 update_young_list_target_length(); 1.166 @@ -543,11 +555,7 @@ 1.167 // smaller than 1.0) we'll get 1. 1.168 _reserve_regions = (size_t) ceil(reserve_regions_d); 1.169 1.170 - if (_using_new_ratio_calculations) { 1.171 - // -XX:NewRatio was specified so we need to update the 1.172 - // young gen length when the heap size has changed. 1.173 - update_young_list_size_using_newratio(new_number_of_regions); 1.174 - } 1.175 + _young_gen_sizer->heap_size_changed(new_number_of_regions); 1.176 } 1.177 1.178 size_t G1CollectorPolicy::calculate_young_list_desired_min_length( 1.179 @@ -565,14 +573,14 @@ 1.180 } 1.181 desired_min_length += base_min_length; 1.182 // make sure we don't go below any user-defined minimum bound 1.183 - return MAX2(_min_desired_young_length, desired_min_length); 1.184 + return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length); 1.185 } 1.186 1.187 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { 1.188 // Here, we might want to also take into account any additional 1.189 // constraints (i.e., user-defined minimum bound). Currently, we 1.190 // effectively don't set this bound. 1.191 - return _max_desired_young_length; 1.192 + return _young_gen_sizer->max_desired_young_length(); 1.193 } 1.194 1.195 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {