annotate src/hotspot/share/gc/shared/collectorPolicy.cpp @ 52321:31b159f30fb2

8180193: Make marking bitmap code available to other GCs Reviewed-by: shade, stefank
author rkennke
date Wed, 29 Aug 2018 20:15:09 +0200
parents f946776e9354
children 2d17750d41e7
rev   line source
duke@1 1 /*
eosterlund@49595 2 * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
duke@1 24
stefank@7397 25 #include "precompiled.hpp"
pliden@30764 26 #include "gc/shared/adaptiveSizePolicy.hpp"
pliden@30764 27 #include "gc/shared/cardTableRS.hpp"
pliden@30764 28 #include "gc/shared/collectorPolicy.hpp"
stefank@50089 29 #include "gc/shared/gcLocker.hpp"
pliden@30764 30 #include "gc/shared/gcPolicyCounters.hpp"
pliden@30764 31 #include "gc/shared/generationSpec.hpp"
pliden@30764 32 #include "gc/shared/space.hpp"
pliden@30764 33 #include "gc/shared/vmGCOperations.hpp"
brutisso@35061 34 #include "logging/log.hpp"
stefank@7397 35 #include "memory/universe.hpp"
stefank@7397 36 #include "runtime/arguments.hpp"
stefank@7397 37 #include "runtime/globals_extension.hpp"
stefank@7397 38 #include "runtime/handles.inline.hpp"
stefank@7397 39 #include "runtime/java.hpp"
stefank@14583 40 #include "runtime/thread.inline.hpp"
stefank@7397 41 #include "runtime/vmThread.hpp"
stefank@46625 42 #include "utilities/align.hpp"
jprovino@15482 43 #include "utilities/macros.hpp"
duke@1 44
jwilhelm@22551 45 // CollectorPolicy methods
duke@1 46
jwilhelm@21561 47 CollectorPolicy::CollectorPolicy() :
jwilhelm@21561 48 _initial_heap_byte_size(InitialHeapSize),
jwilhelm@21561 49 _max_heap_byte_size(MaxHeapSize),
tschatzl@52033 50 _min_heap_byte_size(Arguments::min_heap_size()),
tschatzl@52033 51 _space_alignment(0),
tschatzl@52033 52 _heap_alignment(0)
jwilhelm@21561 53 {}
jwilhelm@21561 54
jwilhelm@21561 55 #ifdef ASSERT
jwilhelm@21561 56 void CollectorPolicy::assert_flags() {
jwilhelm@21561 57 assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");
jwilhelm@21561 58 assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment");
jwilhelm@21561 59 assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment");
jwilhelm@21561 60 }
jwilhelm@21561 61
jwilhelm@21561 62 void CollectorPolicy::assert_size_info() {
jwilhelm@21561 63 assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage");
jwilhelm@21561 64 assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage");
jwilhelm@21561 65 assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes");
jwilhelm@21561 66 assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes");
jwilhelm@21561 67 assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes");
jwilhelm@21561 68 assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment");
jwilhelm@21561 69 assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment");
jwilhelm@21561 70 assert(_max_heap_byte_size % _heap_alignment == 0, "max_heap_byte_size alignment");
jwilhelm@21561 71 }
jwilhelm@21561 72 #endif // ASSERT
jwilhelm@21561 73
duke@1 74 void CollectorPolicy::initialize_flags() {
jwilhelm@21561 75 assert(_space_alignment != 0, "Space alignment not set up properly");
jwilhelm@21561 76 assert(_heap_alignment != 0, "Heap alignment not set up properly");
jwilhelm@21561 77 assert(_heap_alignment >= _space_alignment,
david@33105 78 "heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
david@33105 79 _heap_alignment, _space_alignment);
jwilhelm@21561 80 assert(_heap_alignment % _space_alignment == 0,
david@33105 81 "heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
david@33105 82 _heap_alignment, _space_alignment);
brutisso@17320 83
jwilhelm@21561 84 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
jwilhelm@21561 85 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
jwilhelm@21561 86 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");
jwilhelm@21561 87 }
jwilhelm@21561 88 if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {
jwilhelm@21561 89 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
jwilhelm@21561 90 }
tschatzl@17322 91 }
tschatzl@17322 92
jwilhelm@21561 93 // Check heap parameter properties
pliden@37088 94 if (MaxHeapSize < 2 * M) {
pliden@37088 95 vm_exit_during_initialization("Too small maximum heap");
pliden@37088 96 }
jwilhelm@21561 97 if (InitialHeapSize < M) {
jwilhelm@21561 98 vm_exit_during_initialization("Too small initial heap");
jwilhelm@21561 99 }
jwilhelm@21561 100 if (_min_heap_byte_size < M) {
jwilhelm@21561 101 vm_exit_during_initialization("Too small minimum heap");
jwilhelm@21561 102 }
jwilhelm@21561 103
jwilhelm@21561 104 // User inputs from -Xmx and -Xms must be aligned
stefank@46619 105 _min_heap_byte_size = align_up(_min_heap_byte_size, _heap_alignment);
stefank@46619 106 size_t aligned_initial_heap_size = align_up(InitialHeapSize, _heap_alignment);
stefank@46619 107 size_t aligned_max_heap_size = align_up(MaxHeapSize, _heap_alignment);
jwilhelm@21561 108
jwilhelm@21561 109 // Write back to flags if the values changed
jwilhelm@21561 110 if (aligned_initial_heap_size != InitialHeapSize) {
jwilhelm@29697 111 FLAG_SET_ERGO(size_t, InitialHeapSize, aligned_initial_heap_size);
jwilhelm@21561 112 }
jwilhelm@21561 113 if (aligned_max_heap_size != MaxHeapSize) {
jwilhelm@29697 114 FLAG_SET_ERGO(size_t, MaxHeapSize, aligned_max_heap_size);
jwilhelm@21561 115 }
jwilhelm@21561 116
jwilhelm@21561 117 if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&
jwilhelm@21561 118 InitialHeapSize < _min_heap_byte_size) {
jwilhelm@21561 119 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
jwilhelm@21561 120 }
jwilhelm@21561 121 if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
jwilhelm@29697 122 FLAG_SET_ERGO(size_t, MaxHeapSize, InitialHeapSize);
jwilhelm@21561 123 } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
jwilhelm@29697 124 FLAG_SET_ERGO(size_t, InitialHeapSize, MaxHeapSize);
jwilhelm@21561 125 if (InitialHeapSize < _min_heap_byte_size) {
jwilhelm@21561 126 _min_heap_byte_size = InitialHeapSize;
jwilhelm@21561 127 }
jwilhelm@21561 128 }
jwilhelm@21561 129
jwilhelm@21561 130 _initial_heap_byte_size = InitialHeapSize;
jwilhelm@21561 131 _max_heap_byte_size = MaxHeapSize;
jwilhelm@21561 132
stefank@46619 133 FLAG_SET_ERGO(size_t, MinHeapDeltaBytes, align_up(MinHeapDeltaBytes, _space_alignment));
jwilhelm@21561 134
jwilhelm@21561 135 DEBUG_ONLY(CollectorPolicy::assert_flags();)
duke@1 136 }
duke@1 137
duke@1 138 void CollectorPolicy::initialize_size_info() {
brutisso@35061 139 log_debug(gc, heap)("Minimum heap " SIZE_FORMAT " Initial heap " SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
brutisso@35061 140 _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
jwilhelm@21561 141
jwilhelm@21561 142 DEBUG_ONLY(CollectorPolicy::assert_size_info();)
duke@1 143 }
duke@1 144
jwilhelm@21561 145 size_t CollectorPolicy::compute_heap_alignment() {
tschatzl@19986 146 // The card marking array and the offset arrays for old generations are
tschatzl@19986 147 // committed in os pages as well. Make sure they are entirely full (to
tschatzl@19986 148 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
tschatzl@19986 149 // byte entry and the os page size is 4096, the maximum heap size should
tschatzl@19986 150 // be 512*4096 = 2MB aligned.
tschatzl@19986 151
david@33212 152 size_t alignment = CardTableRS::ct_max_alignment_constraint();
tschatzl@19986 153
jmasa@25943 154 if (UseLargePages) {
jwilhelm@22551 155 // In presence of large pages we have to make sure that our
jmasa@25943 156 // alignment is large page aware.
tschatzl@19986 157 alignment = lcm(os::large_page_size(), alignment);
tschatzl@19986 158 }
tschatzl@19986 159
tschatzl@19986 160 return alignment;
tschatzl@19986 161 }
jmasa@5343 162
jwilhelm@22551 163 // GenCollectorPolicy methods
duke@1 164
jwilhelm@21561 165 GenCollectorPolicy::GenCollectorPolicy() :
jwilhelm@24941 166 _min_young_size(0),
jwilhelm@24941 167 _initial_young_size(0),
jwilhelm@24941 168 _max_young_size(0),
jwilhelm@24941 169 _min_old_size(0),
jwilhelm@24941 170 _initial_old_size(0),
jwilhelm@24941 171 _max_old_size(0),
stefank@49480 172 _gen_alignment(0)
jwilhelm@21561 173 {}
jwilhelm@21561 174
jmasa@186 175 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
stefank@46619 176 return align_down_bounded(base_size / (NewRatio + 1), _gen_alignment);
jmasa@186 177 }
jmasa@186 178
jmasa@186 179 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
jmasa@186 180 size_t maximum_size) {
jwilhelm@21561 181 size_t max_minus = maximum_size - _gen_alignment;
jmasa@186 182 return desired_size < max_minus ? desired_size : max_minus;
jmasa@186 183 }
jmasa@186 184
jwilhelm@21561 185 size_t GenCollectorPolicy::young_gen_size_lower_bound() {
jwilhelm@21561 186 // The young generation must be aligned and have room for eden + two survivors
stefank@46619 187 return align_up(3 * _space_alignment, _gen_alignment);
jwilhelm@21561 188 }
jwilhelm@21561 189
david@32362 190 size_t GenCollectorPolicy::old_gen_size_lower_bound() {
stefank@46619 191 return align_up(_space_alignment, _gen_alignment);
david@32362 192 }
david@32362 193
jwilhelm@21561 194 #ifdef ASSERT
jwilhelm@21561 195 void GenCollectorPolicy::assert_flags() {
jwilhelm@21561 196 CollectorPolicy::assert_flags();
jwilhelm@24941 197 assert(NewSize >= _min_young_size, "Ergonomics decided on a too small young gen size");
jwilhelm@21561 198 assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes");
jwilhelm@21561 199 assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes");
jwilhelm@21561 200 assert(NewSize % _gen_alignment == 0, "NewSize alignment");
jwilhelm@21561 201 assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % _gen_alignment == 0, "MaxNewSize alignment");
jwilhelm@21561 202 assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes");
jwilhelm@21561 203 assert(OldSize % _gen_alignment == 0, "OldSize alignment");
jwilhelm@21561 204 }
jwilhelm@21561 205
jwilhelm@21561 206 void GenCollectorPolicy::assert_size_info() {
jwilhelm@21561 207 CollectorPolicy::assert_size_info();
jwilhelm@21561 208 // GenCollectorPolicy::initialize_size_info may update the MaxNewSize
jwilhelm@21561 209 assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes");
jwilhelm@24941 210 assert(NewSize == _initial_young_size, "Discrepancy between NewSize flag and local storage");
jwilhelm@24941 211 assert(MaxNewSize == _max_young_size, "Discrepancy between MaxNewSize flag and local storage");
jwilhelm@24941 212 assert(OldSize == _initial_old_size, "Discrepancy between OldSize flag and local storage");
jwilhelm@24941 213 assert(_min_young_size <= _initial_young_size, "Ergonomics decided on incompatible minimum and initial young gen sizes");
jwilhelm@24941 214 assert(_initial_young_size <= _max_young_size, "Ergonomics decided on incompatible initial and maximum young gen sizes");
jwilhelm@24941 215 assert(_min_young_size % _gen_alignment == 0, "_min_young_size alignment");
jwilhelm@24941 216 assert(_initial_young_size % _gen_alignment == 0, "_initial_young_size alignment");
jwilhelm@24941 217 assert(_max_young_size % _gen_alignment == 0, "_max_young_size alignment");
jwilhelm@24941 218 assert(_min_young_size <= bound_minus_alignment(_min_young_size, _min_heap_byte_size),
sjohanss@23851 219 "Ergonomics made minimum young generation larger than minimum heap");
jwilhelm@24941 220 assert(_initial_young_size <= bound_minus_alignment(_initial_young_size, _initial_heap_byte_size),
sjohanss@23851 221 "Ergonomics made initial young generation larger than initial heap");
jwilhelm@24941 222 assert(_max_young_size <= bound_minus_alignment(_max_young_size, _max_heap_byte_size),
sjohanss@23851 223 "Ergonomics made maximum young generation lager than maximum heap");
jwilhelm@24941 224 assert(_min_old_size <= _initial_old_size, "Ergonomics decided on incompatible minimum and initial old gen sizes");
jwilhelm@24941 225 assert(_initial_old_size <= _max_old_size, "Ergonomics decided on incompatible initial and maximum old gen sizes");
jwilhelm@24941 226 assert(_max_old_size % _gen_alignment == 0, "_max_old_size alignment");
jwilhelm@24941 227 assert(_initial_old_size % _gen_alignment == 0, "_initial_old_size alignment");
jwilhelm@24941 228 assert(_max_heap_byte_size <= (_max_young_size + _max_old_size), "Total maximum heap sizes must be sum of generation maximum sizes");
jwilhelm@24941 229 assert(_min_young_size + _min_old_size <= _min_heap_byte_size, "Minimum generation sizes exceed minimum heap size");
jwilhelm@24941 230 assert(_initial_young_size + _initial_old_size == _initial_heap_byte_size, "Initial generation sizes should match initial heap size");
jwilhelm@24941 231 assert(_max_young_size + _max_old_size == _max_heap_byte_size, "Maximum generation sizes should match maximum heap size");
jwilhelm@21561 232 }
jwilhelm@21561 233 #endif // ASSERT
jwilhelm@21561 234
duke@1 235 void GenCollectorPolicy::initialize_flags() {
duke@1 236 CollectorPolicy::initialize_flags();
duke@1 237
jwilhelm@21561 238 assert(_gen_alignment != 0, "Generation alignment not set up properly");
jwilhelm@21561 239 assert(_heap_alignment >= _gen_alignment,
david@33105 240 "heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
david@33105 241 _heap_alignment, _gen_alignment);
jwilhelm@21561 242 assert(_gen_alignment % _space_alignment == 0,
david@33105 243 "gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
david@33105 244 _gen_alignment, _space_alignment);
jwilhelm@21561 245 assert(_heap_alignment % _gen_alignment == 0,
david@33105 246 "heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
david@33105 247 _heap_alignment, _gen_alignment);
duke@1 248
jwilhelm@39961 249 // All generational heaps have a young gen; handle those flags here
jwilhelm@21561 250
jwilhelm@21561 251 // Make sure the heap is large enough for two generations
jwilhelm@29697 252 size_t smallest_new_size = young_gen_size_lower_bound();
stefank@46619 253 size_t smallest_heap_size = align_up(smallest_new_size + old_gen_size_lower_bound(),
jwilhelm@21561 254 _heap_alignment);
jwilhelm@21561 255 if (MaxHeapSize < smallest_heap_size) {
jwilhelm@29697 256 FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
jwilhelm@21561 257 _max_heap_byte_size = MaxHeapSize;
jwilhelm@21561 258 }
jwilhelm@21561 259 // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
jwilhelm@21561 260 if (_min_heap_byte_size < smallest_heap_size) {
jwilhelm@21561 261 _min_heap_byte_size = smallest_heap_size;
jwilhelm@21561 262 if (InitialHeapSize < _min_heap_byte_size) {
jwilhelm@29697 263 FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
jwilhelm@21561 264 _initial_heap_byte_size = smallest_heap_size;
jwilhelm@21561 265 }
jwilhelm@21561 266 }
jwilhelm@21561 267
sjohanss@23851 268 // Make sure NewSize allows an old generation to fit even if set on the command line
sjohanss@23851 269 if (FLAG_IS_CMDLINE(NewSize) && NewSize >= _initial_heap_byte_size) {
ehelin@35521 270 log_warning(gc, ergo)("NewSize was set larger than initial heap size, will use initial heap size.");
jwilhelm@39961 271 FLAG_SET_ERGO(size_t, NewSize, bound_minus_alignment(NewSize, _initial_heap_byte_size));
sjohanss@23851 272 }
sjohanss@23851 273
jwilhelm@21561 274 // Now take the actual NewSize into account. We will silently increase NewSize
sjohanss@23224 275 // if the user specified a smaller or unaligned value.
jwilhelm@29697 276 size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
stefank@46619 277 bounded_new_size = MAX2(smallest_new_size, align_down(bounded_new_size, _gen_alignment));
sjohanss@23851 278 if (bounded_new_size != NewSize) {
jwilhelm@39961 279 FLAG_SET_ERGO(size_t, NewSize, bounded_new_size);
jwilhelm@21561 280 }
jwilhelm@24941 281 _min_young_size = smallest_new_size;
jwilhelm@24941 282 _initial_young_size = NewSize;
jwilhelm@21561 283
jwilhelm@21561 284 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
jwilhelm@21561 285 if (MaxNewSize >= MaxHeapSize) {
jwilhelm@21561 286 // Make sure there is room for an old generation
jwilhelm@29697 287 size_t smaller_max_new_size = MaxHeapSize - _gen_alignment;
jwilhelm@21561 288 if (FLAG_IS_CMDLINE(MaxNewSize)) {
ehelin@35521 289 log_warning(gc, ergo)("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
ehelin@35521 290 "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",
ehelin@35521 291 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
jwilhelm@21561 292 }
jwilhelm@29697 293 FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
jwilhelm@21561 294 if (NewSize > MaxNewSize) {
jwilhelm@29697 295 FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
jwilhelm@24941 296 _initial_young_size = NewSize;
jwilhelm@21561 297 }
jwilhelm@24941 298 } else if (MaxNewSize < _initial_young_size) {
jwilhelm@29697 299 FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size);
stefank@46619 300 } else if (!is_aligned(MaxNewSize, _gen_alignment)) {
stefank@46619 301 FLAG_SET_ERGO(size_t, MaxNewSize, align_down(MaxNewSize, _gen_alignment));
jwilhelm@21561 302 }
jwilhelm@24941 303 _max_young_size = MaxNewSize;
jwilhelm@21561 304 }
jwilhelm@21561 305
duke@1 306 if (NewSize > MaxNewSize) {
jwilhelm@21561 307 // At this point this should only happen if the user specifies a large NewSize and/or
jwilhelm@21561 308 // a small (but not too small) MaxNewSize.
jwilhelm@21561 309 if (FLAG_IS_CMDLINE(MaxNewSize)) {
ehelin@35521 310 log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
ehelin@35521 311 "A new max generation size of " SIZE_FORMAT "k will be used.",
ehelin@35521 312 NewSize/K, MaxNewSize/K, NewSize/K);
jwilhelm@21561 313 }
jwilhelm@29697 314 FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
jwilhelm@24941 315 _max_young_size = MaxNewSize;
duke@1 316 }
jwilhelm@21560 317
duke@1 318 if (SurvivorRatio < 1 || NewRatio < 1) {
jwilhelm@20399 319 vm_exit_during_initialization("Invalid young gen ratio specified");
duke@1 320 }
jwilhelm@21561 321
jwilhelm@39961 322 if (OldSize < old_gen_size_lower_bound()) {
jwilhelm@39961 323 FLAG_SET_ERGO(size_t, OldSize, old_gen_size_lower_bound());
jwilhelm@39961 324 }
stefank@46619 325 if (!is_aligned(OldSize, _gen_alignment)) {
stefank@46619 326 FLAG_SET_ERGO(size_t, OldSize, align_down(OldSize, _gen_alignment));
jwilhelm@21561 327 }
jwilhelm@15494 328
jwilhelm@21561 329 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
jwilhelm@15494 330 // NewRatio will be used later to set the young generation size so we use
jwilhelm@15494 331 // it to calculate how big the heap should be based on the requested OldSize
jwilhelm@15494 332 // and NewRatio.
jwilhelm@15494 333 assert(NewRatio > 0, "NewRatio should have been set up earlier");
jwilhelm@15494 334 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
jwilhelm@15494 335
stefank@46619 336 calculated_heapsize = align_up(calculated_heapsize, _heap_alignment);
jwilhelm@29697 337 FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize);
jwilhelm@21561 338 _max_heap_byte_size = MaxHeapSize;
jwilhelm@29697 339 FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize);
jwilhelm@21561 340 _initial_heap_byte_size = InitialHeapSize;
jwilhelm@15494 341 }
duke@1 342
jwilhelm@22551 343 // Adjust NewSize and OldSize or MaxHeapSize to match each other
tschatzl@17322 344 if (NewSize + OldSize > MaxHeapSize) {
jwilhelm@39961 345 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
jwilhelm@22551 346 // Somebody has set a maximum heap size with the intention that we should not
tschatzl@17322 347 // exceed it. Adjust New/OldSize as necessary.
jwilhelm@29697 348 size_t calculated_size = NewSize + OldSize;
tschatzl@17322 349 double shrink_factor = (double) MaxHeapSize / calculated_size;
stefank@46619 350 size_t smaller_new_size = align_down((size_t)(NewSize * shrink_factor), _gen_alignment);
jwilhelm@29697 351 FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
jwilhelm@24941 352 _initial_young_size = NewSize;
jwilhelm@21561 353
tschatzl@17322 354 // OldSize is already aligned because above we aligned MaxHeapSize to
jwilhelm@21561 355 // _heap_alignment, and we just made sure that NewSize is aligned to
jwilhelm@21561 356 // _gen_alignment. In initialize_flags() we verified that _heap_alignment
jwilhelm@21561 357 // is a multiple of _gen_alignment.
jwilhelm@29697 358 FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize);
tschatzl@17322 359 } else {
stefank@46619 360 FLAG_SET_ERGO(size_t, MaxHeapSize, align_up(NewSize + OldSize, _heap_alignment));
jwilhelm@21561 361 _max_heap_byte_size = MaxHeapSize;
tschatzl@17322 362 }
tschatzl@17322 363 }
tschatzl@17389 364
jwilhelm@24941 365 // Update NewSize, if possible, to avoid sizing the young gen too small when only
sjohanss@23851 366 // OldSize is set on the command line.
sjohanss@23851 367 if (FLAG_IS_CMDLINE(OldSize) && !FLAG_IS_CMDLINE(NewSize)) {
sjohanss@23851 368 if (OldSize < _initial_heap_byte_size) {
sjohanss@23851 369 size_t new_size = _initial_heap_byte_size - OldSize;
jwilhelm@24941 370 // Need to compare against the flag value for max since _max_young_size
sjohanss@23851 371 // might not have been set yet.
jwilhelm@24941 372 if (new_size >= _min_young_size && new_size <= MaxNewSize) {
jwilhelm@29697 373 FLAG_SET_ERGO(size_t, NewSize, new_size);
jwilhelm@24941 374 _initial_young_size = NewSize;
sjohanss@23851 375 }
sjohanss@23851 376 }
sjohanss@23851 377 }
sjohanss@23851 378
duke@1 379 always_do_update_barrier = UseConcMarkSweepGC;
duke@1 380
jwilhelm@24353 381 DEBUG_ONLY(GenCollectorPolicy::assert_flags();)
duke@1 382 }
duke@1 383
jmasa@186 384 // Values set on the command line win over any ergonomically
jmasa@186 385 // set command line parameters.
jmasa@186 386 // Ergonomic choice of parameters are done before this
jmasa@186 387 // method is called. Values for command line parameters such as NewSize
jmasa@186 388 // and MaxNewSize feed those ergonomic choices into this method.
jmasa@186 389 // This method makes the final generation sizings consistent with
jmasa@186 390 // themselves and with overall heap sizings.
jmasa@186 391 // In the absence of explicitly set command line flags, policies
jmasa@186 392 // such as the use of NewRatio are used to size the generation.
jwilhelm@24353 393
jwilhelm@24353 394 // Minimum sizes of the generations may be different than
jwilhelm@24353 395 // the initial sizes. An inconsistency is permitted here
jwilhelm@24353 396 // in the total size that can be specified explicitly by
jwilhelm@24353 397 // command line specification of OldSize and NewSize and
jwilhelm@24353 398 // also a command line specification of -Xms. Issue a warning
jwilhelm@24353 399 // but allow the values to pass.
duke@1 400 void GenCollectorPolicy::initialize_size_info() {
duke@1 401 CollectorPolicy::initialize_size_info();
duke@1 402
jwilhelm@24941 403 _initial_young_size = NewSize;
jwilhelm@24941 404 _max_young_size = MaxNewSize;
jwilhelm@24941 405 _initial_old_size = OldSize;
jmasa@186 406
jwilhelm@24941 407 // Determine maximum size of the young generation.
jmasa@186 408
jwilhelm@24940 409 if (FLAG_IS_DEFAULT(MaxNewSize)) {
jwilhelm@24941 410 _max_young_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
jmasa@186 411 // Bound the maximum size by NewSize below (since it historically
duke@1 412 // would have been NewSize and because the NewRatio calculation could
duke@1 413 // yield a size that is too small) and bound it by MaxNewSize above.
jmasa@186 414 // Ergonomics plays here by previously calculating the desired
jmasa@186 415 // NewSize and MaxNewSize.
jwilhelm@24941 416 _max_young_size = MIN2(MAX2(_max_young_size, _initial_young_size), MaxNewSize);
jmasa@186 417 }
jmasa@186 418
jwilhelm@24941 419 // Given the maximum young size, determine the initial and
jwilhelm@24941 420 // minimum young sizes.
jmasa@186 421
sjohanss@23851 422 if (_max_heap_byte_size == _initial_heap_byte_size) {
jwilhelm@24940 423 // The maximum and initial heap sizes are the same so the generation's
sjohanss@23851 424 // initial size must be the same as it maximum size. Use NewSize as the
sjohanss@23851 425 // size if set on command line.
jwilhelm@24941 426 _max_young_size = FLAG_IS_CMDLINE(NewSize) ? NewSize : _max_young_size;
jwilhelm@24941 427 _initial_young_size = _max_young_size;
sjohanss@23851 428
sjohanss@23851 429 // Also update the minimum size if min == initial == max.
sjohanss@23851 430 if (_max_heap_byte_size == _min_heap_byte_size) {
jwilhelm@24941 431 _min_young_size = _max_young_size;
sjohanss@23851 432 }
jmasa@186 433 } else {
sjohanss@22776 434 if (FLAG_IS_CMDLINE(NewSize)) {
sjohanss@23851 435 // If NewSize is set on the command line, we should use it as
sjohanss@23851 436 // the initial size, but make sure it is within the heap bounds.
jwilhelm@24941 437 _initial_young_size =
jwilhelm@24941 438 MIN2(_max_young_size, bound_minus_alignment(NewSize, _initial_heap_byte_size));
jwilhelm@24941 439 _min_young_size = bound_minus_alignment(_initial_young_size, _min_heap_byte_size);
jmasa@186 440 } else {
sjohanss@23851 441 // For the case where NewSize is not set on the command line, use
sjohanss@23851 442 // NewRatio to size the initial generation size. Use the current
sjohanss@23851 443 // NewSize as the floor, because if NewRatio is overly large, the resulting
sjohanss@23851 444 // size can be too small.
jwilhelm@24941 445 _initial_young_size =
jwilhelm@24941 446 MIN2(_max_young_size, MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize));
jmasa@186 447 }
jwilhelm@21561 448 }
jwilhelm@21561 449
brutisso@35061 450 log_trace(gc, heap)("1: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT,
brutisso@35061 451 _min_young_size, _initial_young_size, _max_young_size);
jwilhelm@21561 452
jmasa@186 453 // At this point the minimum, initial and maximum sizes
jwilhelm@24941 454 // of the overall heap and of the young generation have been determined.
jwilhelm@24941 455 // The maximum old size can be determined from the maximum young
jwilhelm@22551 456 // and maximum heap size since no explicit flags exist
jwilhelm@24941 457 // for setting the old generation maximum.
jwilhelm@24941 458 _max_old_size = MAX2(_max_heap_byte_size - _max_young_size, _gen_alignment);
jwilhelm@21561 459
jmasa@186 460 // If no explicit command line flag has been set for the
jwilhelm@24941 461 // old generation size, use what is left.
jwilhelm@21561 462 if (!FLAG_IS_CMDLINE(OldSize)) {
jwilhelm@21561 463 // The user has not specified any value but the ergonomics
jwilhelm@21561 464 // may have chosen a value (which may or may not be consistent
jmasa@186 465 // with the overall heap size). In either case make
jmasa@186 466 // the minimum, maximum and initial sizes consistent
jwilhelm@24941 467 // with the young sizes and the overall heap sizes.
jwilhelm@24941 468 _min_old_size = _gen_alignment;
jwilhelm@24941 469 _initial_old_size = MIN2(_max_old_size, MAX2(_initial_heap_byte_size - _initial_young_size, _min_old_size));
jwilhelm@24941 470 // _max_old_size has already been made consistent above.
jmasa@186 471 } else {
sjohanss@23851 472 // OldSize has been explicitly set on the command line. Use it
sjohanss@23851 473 // for the initial size but make sure the minimum allow a young
sjohanss@23851 474 // generation to fit as well.
jmasa@186 475 // If the user has explicitly set an OldSize that is inconsistent
jmasa@186 476 // with other command line flags, issue a warning.
jwilhelm@22551 477 // The generation minimums and the overall heap minimum should
jwilhelm@21561 478 // be within one generation alignment.
jwilhelm@24941 479 if (_initial_old_size > _max_old_size) {
ehelin@35521 480 log_warning(gc, ergo)("Inconsistency between maximum heap size and maximum "
ehelin@35521 481 "generation sizes: using maximum heap = " SIZE_FORMAT
ehelin@35521 482 ", -XX:OldSize flag is being ignored",
ehelin@35521 483 _max_heap_byte_size);
jwilhelm@24941 484 _initial_old_size = _max_old_size;
ysr@8687 485 }
sjohanss@23851 486
jwilhelm@24941 487 _min_old_size = MIN2(_initial_old_size, _min_heap_byte_size - _min_young_size);
sjohanss@23851 488 }
sjohanss@23851 489
sjohanss@23851 490 // The initial generation sizes should match the initial heap size,
sjohanss@23851 491 // if not issue a warning and resize the generations. This behavior
sjohanss@23851 492 // differs from JDK8 where the generation sizes have higher priority
sjohanss@23851 493 // than the initial heap size.
jwilhelm@24941 494 if ((_initial_old_size + _initial_young_size) != _initial_heap_byte_size) {
ehelin@35521 495 log_warning(gc, ergo)("Inconsistency between generation sizes and heap size, resizing "
ehelin@35521 496 "the generations to fit the heap.");
sjohanss@23851 497
jwilhelm@24941 498 size_t desired_young_size = _initial_heap_byte_size - _initial_old_size;
jwilhelm@24941 499 if (_initial_heap_byte_size < _initial_old_size) {
sjohanss@23851 500 // Old want all memory, use minimum for young and rest for old
jwilhelm@24941 501 _initial_young_size = _min_young_size;
jwilhelm@24941 502 _initial_old_size = _initial_heap_byte_size - _min_young_size;
jwilhelm@24941 503 } else if (desired_young_size > _max_young_size) {
sjohanss@23851 504 // Need to increase both young and old generation
jwilhelm@24941 505 _initial_young_size = _max_young_size;
jwilhelm@24941 506 _initial_old_size = _initial_heap_byte_size - _max_young_size;
jwilhelm@24941 507 } else if (desired_young_size < _min_young_size) {
sjohanss@23851 508 // Need to decrease both young and old generation
jwilhelm@24941 509 _initial_young_size = _min_young_size;
jwilhelm@24941 510 _initial_old_size = _initial_heap_byte_size - _min_young_size;
sjohanss@23851 511 } else {
sjohanss@23851 512 // The young generation boundaries allow us to only update the
sjohanss@23851 513 // young generation.
jwilhelm@24941 514 _initial_young_size = desired_young_size;
jmasa@186 515 }
sjohanss@23851 516
brutisso@35061 517 log_trace(gc, heap)("2: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT,
brutisso@35061 518 _min_young_size, _initial_young_size, _max_young_size);
jmasa@186 519 }
jwilhelm@22551 520
jwilhelm@24941 521 // Write back to flags if necessary.
jwilhelm@24941 522 if (NewSize != _initial_young_size) {
jwilhelm@29697 523 FLAG_SET_ERGO(size_t, NewSize, _initial_young_size);
jwilhelm@21561 524 }
jwilhelm@21561 525
jwilhelm@24941 526 if (MaxNewSize != _max_young_size) {
jwilhelm@29697 527 FLAG_SET_ERGO(size_t, MaxNewSize, _max_young_size);
jwilhelm@21561 528 }
jwilhelm@21561 529
jwilhelm@24941 530 if (OldSize != _initial_old_size) {
jwilhelm@29697 531 FLAG_SET_ERGO(size_t, OldSize, _initial_old_size);
jwilhelm@21561 532 }
jwilhelm@21561 533
brutisso@35061 534 log_trace(gc, heap)("Minimum old " SIZE_FORMAT " Initial old " SIZE_FORMAT " Maximum old " SIZE_FORMAT,
brutisso@35061 535 _min_old_size, _initial_old_size, _max_old_size);
jwilhelm@21561 536
jwilhelm@24353 537 DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
duke@1 538 }
duke@1 539
duke@1 540 //
duke@1 541 // MarkSweepPolicy methods
duke@1 542 //
duke@1 543
jwilhelm@21561 544 void MarkSweepPolicy::initialize_alignments() {
jwilhelm@29697 545 _space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
jwilhelm@21561 546 _heap_alignment = compute_heap_alignment();
duke@1 547 }