1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "gc/shared/collectedHeap.hpp" 27 #include "gc/shared/collectorPolicy.hpp" 28 #include "gc/shared/threadLocalAllocBuffer.hpp" 29 #include "runtime/arguments.hpp" 30 #include "runtime/commandLineFlagConstraintsGC.hpp" 31 #include "runtime/commandLineFlagRangeList.hpp" 32 #include "runtime/globals.hpp" 33 #include "runtime/globals_extension.hpp" 34 #include "runtime/thread.inline.hpp" 35 #include "utilities/defaultStream.hpp" 36 37 #if INCLUDE_ALL_GCS 38 #include "gc/g1/g1_globals.hpp" 39 #include "gc/g1/heapRegionBounds.inline.hpp" 40 #include "gc/shared/plab.hpp" 41 #endif // INCLUDE_ALL_GCS 42 #ifdef COMPILER1 43 #include "c1/c1_globals.hpp" 44 #endif // COMPILER1 45 #ifdef COMPILER2 46 #include "opto/c2_globals.hpp" 47 #endif // COMPILER2 48 49 // Some flags that have default values that indicate that the 50 // JVM should automatically determine an appropriate value 51 // for that flag. In those cases it is only appropriate for the 52 // constraint checking to be done if the user has specified the 53 // value(s) of the flag(s) on the command line. In the constraint 54 // checking functions, FLAG_IS_CMDLINE() is used to check if 55 // the flag has been set by the user and so should be checked. 56 57 #if INCLUDE_ALL_GCS 58 static Flag::Error ParallelGCThreadsAndCMSWorkQueueDrainThreshold(uint threads, uintx threshold, bool verbose) { 59 // CMSWorkQueueDrainThreshold is verified to be less than max_juint 60 if (UseConcMarkSweepGC && (threads > (uint)(max_jint / (uint)threshold))) { 61 CommandLineError::print(verbose, 62 "ParallelGCThreads (" UINT32_FORMAT ") or CMSWorkQueueDrainThreshold (" 63 UINTX_FORMAT ") is too large\n", 64 threads, threshold); 65 return Flag::VIOLATES_CONSTRAINT; 66 } 67 return Flag::SUCCESS; 68 } 69 #endif 70 71 // As ParallelGCThreads differs among GC modes, we need constraint function. 72 Flag::Error ParallelGCThreadsConstraintFunc(uint value, bool verbose) { 73 Flag::Error status = Flag::SUCCESS; 74 75 #if INCLUDE_ALL_GCS 76 // Parallel GC passes ParallelGCThreads when creating GrowableArray as 'int' type parameter. 77 // So can't exceed with "max_jint" 78 if (UseParallelGC && (value > (uint)max_jint)) { 79 CommandLineError::print(verbose, 80 "ParallelGCThreads (" UINT32_FORMAT ") must be " 81 "less than or equal to " UINT32_FORMAT " for Parallel GC\n", 82 value, max_jint); 83 return Flag::VIOLATES_CONSTRAINT; 84 } 85 // To avoid overflow at ParScanClosure::do_oop_work. 86 if (UseConcMarkSweepGC && (value > (max_jint / 10))) { 87 CommandLineError::print(verbose, 88 "ParallelGCThreads (" UINT32_FORMAT ") must be " 89 "less than or equal to " UINT32_FORMAT " for CMS GC\n", 90 value, (max_jint / 10)); 91 return Flag::VIOLATES_CONSTRAINT; 92 } 93 status = ParallelGCThreadsAndCMSWorkQueueDrainThreshold(value, CMSWorkQueueDrainThreshold, verbose); 94 #endif 95 return status; 96 } 97 98 // As ConcGCThreads should be smaller than ParallelGCThreads, 99 // we need constraint function. 100 Flag::Error ConcGCThreadsConstraintFunc(uint value, bool verbose) { 101 #if INCLUDE_ALL_GCS 102 // CMS and G1 GCs use ConcGCThreads. 103 if ((UseConcMarkSweepGC || UseG1GC) && (value > ParallelGCThreads)) { 104 CommandLineError::print(verbose, 105 "ConcGCThreads (" UINT32_FORMAT ") must be " 106 "less than or equal to ParallelGCThreads (" UINT32_FORMAT ")\n", 107 value, ParallelGCThreads); 108 return Flag::VIOLATES_CONSTRAINT; 109 } 110 #endif 111 return Flag::SUCCESS; 112 } 113 114 static Flag::Error MinPLABSizeBounds(const char* name, size_t value, bool verbose) { 115 #if INCLUDE_ALL_GCS 116 if ((UseConcMarkSweepGC || UseG1GC) && (value < PLAB::min_size())) { 117 CommandLineError::print(verbose, 118 "%s (" SIZE_FORMAT ") must be " 119 "greater than or equal to ergonomic PLAB minimum size (" SIZE_FORMAT ")\n", 120 name, value, PLAB::min_size()); 121 return Flag::VIOLATES_CONSTRAINT; 122 } 123 #endif // INCLUDE_ALL_GCS 124 return Flag::SUCCESS; 125 } 126 127 static Flag::Error MaxPLABSizeBounds(const char* name, size_t value, bool verbose) { 128 #if INCLUDE_ALL_GCS 129 if ((UseConcMarkSweepGC || UseG1GC) && (value > PLAB::max_size())) { 130 CommandLineError::print(verbose, 131 "%s (" SIZE_FORMAT ") must be " 132 "less than or equal to ergonomic PLAB maximum size (" SIZE_FORMAT ")\n", 133 name, value, PLAB::max_size()); 134 return Flag::VIOLATES_CONSTRAINT; 135 } 136 #endif // INCLUDE_ALL_GCS 137 return Flag::SUCCESS; 138 } 139 140 static Flag::Error MinMaxPLABSizeBounds(const char* name, size_t value, bool verbose) { 141 Flag::Error status = MinPLABSizeBounds(name, value, verbose); 142 143 if (status == Flag::SUCCESS) { 144 return MaxPLABSizeBounds(name, value, verbose); 145 } 146 return status; 147 } 148 149 Flag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose) { 150 return MinMaxPLABSizeBounds("YoungPLABSize", value, verbose); 151 } 152 153 Flag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose) { 154 Flag::Error status = Flag::SUCCESS; 155 156 #if INCLUDE_ALL_GCS 157 if (UseConcMarkSweepGC) { 158 if (value == 0) { 159 CommandLineError::print(verbose, 160 "OldPLABSize (" SIZE_FORMAT ") must be greater than 0", 161 value); 162 return Flag::VIOLATES_CONSTRAINT; 163 } 164 // For CMS, OldPLABSize is the number of free blocks of a given size that are used when 165 // replenishing the local per-worker free list caches. 166 // For more details, please refer to Arguments::set_cms_and_parnew_gc_flags(). 167 status = MaxPLABSizeBounds("OldPLABSize", value, verbose); 168 } else { 169 status = MinMaxPLABSizeBounds("OldPLABSize", value, verbose); 170 } 171 #endif 172 return status; 173 } 174 175 Flag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) { 176 if (value > MaxHeapFreeRatio) { 177 CommandLineError::print(verbose, 178 "MinHeapFreeRatio (" UINTX_FORMAT ") must be " 179 "less than or equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n", 180 value, MaxHeapFreeRatio); 181 return Flag::VIOLATES_CONSTRAINT; 182 } else { 183 return Flag::SUCCESS; 184 } 185 } 186 187 Flag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose) { 188 if (value < MinHeapFreeRatio) { 189 CommandLineError::print(verbose, 190 "MaxHeapFreeRatio (" UINTX_FORMAT ") must be " 191 "greater than or equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n", 192 value, MinHeapFreeRatio); 193 return Flag::VIOLATES_CONSTRAINT; 194 } else { 195 return Flag::SUCCESS; 196 } 197 } 198 199 static Flag::Error CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(size_t maxHeap, intx softRef, bool verbose) { 200 if ((softRef > 0) && ((maxHeap / M) > (max_uintx / softRef))) { 201 CommandLineError::print(verbose, 202 "Desired lifetime of SoftReferences cannot be expressed correctly. " 203 "MaxHeapSize (" SIZE_FORMAT ") or SoftRefLRUPolicyMSPerMB " 204 "(" INTX_FORMAT ") is too large\n", 205 maxHeap, softRef); 206 return Flag::VIOLATES_CONSTRAINT; 207 } else { 208 return Flag::SUCCESS; 209 } 210 } 211 212 Flag::Error SoftRefLRUPolicyMSPerMBConstraintFunc(intx value, bool verbose) { 213 return CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(MaxHeapSize, value, verbose); 214 } 215 216 Flag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) { 217 if (value > MaxMetaspaceFreeRatio) { 218 CommandLineError::print(verbose, 219 "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be " 220 "less than or equal to MaxMetaspaceFreeRatio (" UINTX_FORMAT ")\n", 221 value, MaxMetaspaceFreeRatio); 222 return Flag::VIOLATES_CONSTRAINT; 223 } else { 224 return Flag::SUCCESS; 225 } 226 } 227 228 Flag::Error MaxMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) { 229 if (value < MinMetaspaceFreeRatio) { 230 CommandLineError::print(verbose, 231 "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be " 232 "greater than or equal to MinMetaspaceFreeRatio (" UINTX_FORMAT ")\n", 233 value, MinMetaspaceFreeRatio); 234 return Flag::VIOLATES_CONSTRAINT; 235 } else { 236 return Flag::SUCCESS; 237 } 238 } 239 240 Flag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose) { 241 #if INCLUDE_ALL_GCS 242 // InitialTenuringThreshold is only used for ParallelGC. 243 if (UseParallelGC && (value > MaxTenuringThreshold)) { 244 CommandLineError::print(verbose, 245 "InitialTenuringThreshold (" UINTX_FORMAT ") must be " 246 "less than or equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n", 247 value, MaxTenuringThreshold); 248 return Flag::VIOLATES_CONSTRAINT; 249 } 250 #endif 251 return Flag::SUCCESS; 252 } 253 254 Flag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose) { 255 #if INCLUDE_ALL_GCS 256 // As only ParallelGC uses InitialTenuringThreshold, 257 // we don't need to compare InitialTenuringThreshold with MaxTenuringThreshold. 258 if (UseParallelGC && (value < InitialTenuringThreshold)) { 259 CommandLineError::print(verbose, 260 "MaxTenuringThreshold (" UINTX_FORMAT ") must be " 261 "greater than or equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n", 262 value, InitialTenuringThreshold); 263 return Flag::VIOLATES_CONSTRAINT; 264 } 265 #endif 266 267 // MaxTenuringThreshold=0 means NeverTenure=false && AlwaysTenure=true 268 if ((value == 0) && (NeverTenure || !AlwaysTenure)) { 269 CommandLineError::print(verbose, 270 "MaxTenuringThreshold (0) should match to NeverTenure=false " 271 "&& AlwaysTenure=true. But we have NeverTenure=%s " 272 "AlwaysTenure=%s\n", 273 NeverTenure ? "true" : "false", 274 AlwaysTenure ? "true" : "false"); 275 return Flag::VIOLATES_CONSTRAINT; 276 } 277 return Flag::SUCCESS; 278 } 279 280 #if INCLUDE_ALL_GCS 281 Flag::Error G1RSetRegionEntriesConstraintFunc(intx value, bool verbose) { 282 if (!UseG1GC) return Flag::SUCCESS; 283 284 // Default value of G1RSetRegionEntries=0 means will be set ergonomically. 285 // Minimum value is 1. 286 if (FLAG_IS_CMDLINE(G1RSetRegionEntries) && (value < 1)) { 287 CommandLineError::print(verbose, 288 "G1RSetRegionEntries (" INTX_FORMAT ") must be " 289 "greater than or equal to 1\n", 290 value); 291 return Flag::VIOLATES_CONSTRAINT; 292 } else { 293 return Flag::SUCCESS; 294 } 295 } 296 297 Flag::Error G1RSetSparseRegionEntriesConstraintFunc(intx value, bool verbose) { 298 if (!UseG1GC) return Flag::SUCCESS; 299 300 // Default value of G1RSetSparseRegionEntries=0 means will be set ergonomically. 301 // Minimum value is 1. 302 if (FLAG_IS_CMDLINE(G1RSetSparseRegionEntries) && (value < 1)) { 303 CommandLineError::print(verbose, 304 "G1RSetSparseRegionEntries (" INTX_FORMAT ") must be " 305 "greater than or equal to 1\n", 306 value); 307 return Flag::VIOLATES_CONSTRAINT; 308 } else { 309 return Flag::SUCCESS; 310 } 311 } 312 313 Flag::Error G1YoungSurvRateNumRegionsSummaryConstraintFunc(intx value, bool verbose) { 314 if (!UseG1GC) return Flag::SUCCESS; 315 316 if (value > (intx)HeapRegionBounds::target_number()) { 317 CommandLineError::print(verbose, 318 "G1YoungSurvRateNumRegionsSummary (" INTX_FORMAT ") must be " 319 "less than or equal to region count (" SIZE_FORMAT ")\n", 320 value, HeapRegionBounds::target_number()); 321 return Flag::VIOLATES_CONSTRAINT; 322 } else { 323 return Flag::SUCCESS; 324 } 325 } 326 327 Flag::Error G1HeapRegionSizeConstraintFunc(size_t value, bool verbose) { 328 if (!UseG1GC) return Flag::SUCCESS; 329 330 // Default value of G1HeapRegionSize=0 means will be set ergonomically. 331 if (FLAG_IS_CMDLINE(G1HeapRegionSize) && (value < HeapRegionBounds::min_size())) { 332 CommandLineError::print(verbose, 333 "G1HeapRegionSize (" SIZE_FORMAT ") must be " 334 "greater than or equal to ergonomic heap region minimum size\n", 335 value); 336 return Flag::VIOLATES_CONSTRAINT; 337 } else { 338 return Flag::SUCCESS; 339 } 340 } 341 342 Flag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose) { 343 if (!UseG1GC) return Flag::SUCCESS; 344 345 if (value > G1MaxNewSizePercent) { 346 CommandLineError::print(verbose, 347 "G1NewSizePercent (" UINTX_FORMAT ") must be " 348 "less than or equal to G1MaxNewSizePercent (" UINTX_FORMAT ")\n", 349 value, G1MaxNewSizePercent); 350 return Flag::VIOLATES_CONSTRAINT; 351 } else { 352 return Flag::SUCCESS; 353 } 354 } 355 356 Flag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose) { 357 if (!UseG1GC) return Flag::SUCCESS; 358 359 if (value < G1NewSizePercent) { 360 CommandLineError::print(verbose, 361 "G1MaxNewSizePercent (" UINTX_FORMAT ") must be " 362 "greater than or equal to G1NewSizePercent (" UINTX_FORMAT ")\n", 363 value, G1NewSizePercent); 364 return Flag::VIOLATES_CONSTRAINT; 365 } else { 366 return Flag::SUCCESS; 367 } 368 } 369 #endif // INCLUDE_ALL_GCS 370 371 Flag::Error ParGCStridesPerThreadConstraintFunc(uintx value, bool verbose) { 372 #if INCLUDE_ALL_GCS 373 if (UseConcMarkSweepGC && (value > ((uintx)max_jint / (uintx)ParallelGCThreads))) { 374 CommandLineError::print(verbose, 375 "ParGCStridesPerThread (" UINTX_FORMAT ") must be " 376 "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n", 377 value, ((uintx)max_jint / (uintx)ParallelGCThreads)); 378 return Flag::VIOLATES_CONSTRAINT; 379 } 380 #endif 381 return Flag::SUCCESS; 382 } 383 384 Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose) { 385 Flag::Error status = Flag::SUCCESS; 386 387 #if INCLUDE_ALL_GCS 388 if (UseConcMarkSweepGC) { 389 if (value > CMSOldPLABMax) { 390 CommandLineError::print(verbose, 391 "CMSOldPLABMin (" SIZE_FORMAT ") must be " 392 "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n", 393 value, CMSOldPLABMax); 394 return Flag::VIOLATES_CONSTRAINT; 395 } 396 status = MaxPLABSizeBounds("CMSOldPLABMin", value, verbose); 397 } 398 #endif 399 return status; 400 } 401 402 Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose) { 403 Flag::Error status = Flag::SUCCESS; 404 405 #if INCLUDE_ALL_GCS 406 if (UseConcMarkSweepGC) { 407 status = MaxPLABSizeBounds("CMSOldPLABMax", value, verbose); 408 } 409 #endif 410 return status; 411 } 412 413 Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose) { 414 if (value > MarkStackSizeMax) { 415 CommandLineError::print(verbose, 416 "MarkStackSize (" SIZE_FORMAT ") must be " 417 "less than or equal to MarkStackSizeMax (" SIZE_FORMAT ")\n", 418 value, MarkStackSizeMax); 419 return Flag::VIOLATES_CONSTRAINT; 420 } else { 421 return Flag::SUCCESS; 422 } 423 } 424 425 Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) { 426 #if INCLUDE_ALL_GCS 427 if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) { 428 CommandLineError::print(verbose, 429 "CMSPrecleanDenominator (" UINTX_FORMAT ") must be " 430 "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n", 431 value, CMSPrecleanNumerator); 432 return Flag::VIOLATES_CONSTRAINT; 433 } 434 #endif 435 return Flag::SUCCESS; 436 } 437 438 Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) { 439 #if INCLUDE_ALL_GCS 440 if (UseConcMarkSweepGC && (value >= CMSPrecleanDenominator)) { 441 CommandLineError::print(verbose, 442 "CMSPrecleanNumerator (" UINTX_FORMAT ") must be " 443 "less than CMSPrecleanDenominator (" UINTX_FORMAT ")\n", 444 value, CMSPrecleanDenominator); 445 return Flag::VIOLATES_CONSTRAINT; 446 } 447 #endif 448 return Flag::SUCCESS; 449 } 450 451 Flag::Error CMSWorkQueueDrainThresholdConstraintFunc(uintx value, bool verbose) { 452 #if INCLUDE_ALL_GCS 453 if (UseConcMarkSweepGC) { 454 return ParallelGCThreadsAndCMSWorkQueueDrainThreshold(ParallelGCThreads, value, verbose); 455 } 456 #endif 457 return Flag::SUCCESS; 458 } 459 460 Flag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose) { 461 #if INCLUDE_ALL_GCS 462 if (UseG1GC && FLAG_IS_CMDLINE(MaxGCPauseMillis) && (value >= GCPauseIntervalMillis)) { 463 CommandLineError::print(verbose, 464 "MaxGCPauseMillis (" UINTX_FORMAT ") must be " 465 "less than GCPauseIntervalMillis (" UINTX_FORMAT ")\n", 466 value, GCPauseIntervalMillis); 467 return Flag::VIOLATES_CONSTRAINT; 468 } 469 #endif 470 471 return Flag::SUCCESS; 472 } 473 474 Flag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose) { 475 #if INCLUDE_ALL_GCS 476 if (UseG1GC) { 477 if (FLAG_IS_CMDLINE(GCPauseIntervalMillis)) { 478 if (value < 1) { 479 CommandLineError::print(verbose, 480 "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " 481 "greater than or equal to 1\n", 482 value); 483 return Flag::VIOLATES_CONSTRAINT; 484 } 485 if (value <= MaxGCPauseMillis) { 486 CommandLineError::print(verbose, 487 "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " 488 "greater than MaxGCPauseMillis (" UINTX_FORMAT ")\n", 489 value, MaxGCPauseMillis); 490 return Flag::VIOLATES_CONSTRAINT; 491 } 492 } 493 } 494 #endif 495 return Flag::SUCCESS; 496 } 497 498 Flag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose) { 499 size_t aligned_max = (size_t)align_size_down(max_uintx/2, Metaspace::reserve_alignment_words()); 500 if (value > aligned_max) { 501 CommandLineError::print(verbose, 502 "InitialBootClassLoaderMetaspaceSize (" SIZE_FORMAT ") must be " 503 "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", 504 value, aligned_max); 505 return Flag::VIOLATES_CONSTRAINT; 506 } 507 return Flag::SUCCESS; 508 } 509 510 // To avoid an overflow by 'align_size_up(value, alignment)'. 511 static Flag::Error MaxSizeForAlignment(const char* name, size_t value, size_t alignment, bool verbose) { 512 size_t aligned_max = ((max_uintx - alignment) & ~(alignment-1)); 513 if (value > aligned_max) { 514 CommandLineError::print(verbose, 515 "%s (" SIZE_FORMAT ") must be " 516 "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", 517 name, value, aligned_max); 518 return Flag::VIOLATES_CONSTRAINT; 519 } 520 return Flag::SUCCESS; 521 } 522 523 static Flag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bool verbose) { 524 // For G1 GC, we don't know until G1CollectorPolicy is created. 525 size_t heap_alignment; 526 527 #if INCLUDE_ALL_GCS 528 if (UseG1GC) { 529 heap_alignment = HeapRegionBounds::max_size(); 530 } else 531 #endif 532 { 533 heap_alignment = CollectorPolicy::compute_heap_alignment(); 534 } 535 536 return MaxSizeForAlignment(name, value, heap_alignment, verbose); 537 } 538 539 Flag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose) { 540 return MaxSizeForHeapAlignment("InitialHeapSize", value, verbose); 541 } 542 543 Flag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose) { 544 Flag::Error status = MaxSizeForHeapAlignment("MaxHeapSize", value, verbose); 545 546 if (status == Flag::SUCCESS) { 547 status = CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(value, SoftRefLRUPolicyMSPerMB, verbose); 548 } 549 return status; 550 } 551 552 Flag::Error HeapBaseMinAddressConstraintFunc(size_t value, bool verbose) { 553 // If an overflow happened in Arguments::set_heap_size(), MaxHeapSize will have too large a value. 554 // Check for this by ensuring that MaxHeapSize plus the requested min base address still fit within max_uintx. 555 if (UseCompressedOops && FLAG_IS_ERGO(MaxHeapSize) && (value > (max_uintx - MaxHeapSize))) { 556 CommandLineError::print(verbose, 557 "HeapBaseMinAddress (" SIZE_FORMAT ") or MaxHeapSize (" SIZE_FORMAT ") is too large. " 558 "Sum of them must be less than or equal to maximum of size_t (" SIZE_FORMAT ")\n", 559 value, MaxHeapSize, max_uintx); 560 return Flag::VIOLATES_CONSTRAINT; 561 } 562 563 return MaxSizeForHeapAlignment("HeapBaseMinAddress", value, verbose); 564 } 565 566 Flag::Error NewSizeConstraintFunc(size_t value, bool verbose) { 567 #ifdef _LP64 568 #if INCLUDE_ALL_GCS 569 // Overflow would happen for uint type variable of YoungGenSizer::_min_desired_young_length 570 // when the value to be assigned exceeds uint range. 571 // i.e. result of '(uint)(NewSize / region size(1~32MB))' 572 // So maximum of NewSize should be 'max_juint * 1M' 573 if (UseG1GC && (value > (max_juint * 1 * M))) { 574 CommandLineError::print(verbose, 575 "NewSize (" SIZE_FORMAT ") must be less than ergonomic maximum value\n", 576 value); 577 return Flag::VIOLATES_CONSTRAINT; 578 } 579 #endif // INCLUDE_ALL_GCS 580 #endif // _LP64 581 return Flag::SUCCESS; 582 } 583 584 Flag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose) { 585 // At least, alignment reserve area is needed. 586 if (value < ThreadLocalAllocBuffer::alignment_reserve_in_bytes()) { 587 CommandLineError::print(verbose, 588 "MinTLABSize (" SIZE_FORMAT ") must be " 589 "greater than or equal to reserved area in TLAB (" SIZE_FORMAT ")\n", 590 value, ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); 591 return Flag::VIOLATES_CONSTRAINT; 592 } else { 593 return Flag::SUCCESS; 594 } 595 } 596 597 Flag::Error TLABSizeConstraintFunc(size_t value, bool verbose) { 598 // Skip for default value of zero which means set ergonomically. 599 if (FLAG_IS_CMDLINE(TLABSize)) { 600 if (value < MinTLABSize) { 601 CommandLineError::print(verbose, 602 "TLABSize (" SIZE_FORMAT ") must be " 603 "greater than or equal to MinTLABSize (" SIZE_FORMAT ")\n", 604 value, MinTLABSize); 605 return Flag::VIOLATES_CONSTRAINT; 606 } 607 if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { 608 CommandLineError::print(verbose, 609 "TLABSize (" SIZE_FORMAT ") must be " 610 "less than or equal to ergonomic TLAB maximum size (" SIZE_FORMAT ")\n", 611 value, (ThreadLocalAllocBuffer::max_size() * HeapWordSize)); 612 return Flag::VIOLATES_CONSTRAINT; 613 } 614 } 615 return Flag::SUCCESS; 616 } 617 618 // We will protect overflow from ThreadLocalAllocBuffer::record_slow_allocation(), 619 // so AfterMemoryInit type is enough to check. 620 Flag::Error TLABWasteIncrementConstraintFunc(uintx value, bool verbose) { 621 if (UseTLAB) { 622 size_t refill_waste_limit = Thread::current()->tlab().refill_waste_limit(); 623 624 // Compare with 'max_uintx' as ThreadLocalAllocBuffer::_refill_waste_limit is 'size_t'. 625 if (refill_waste_limit > (max_uintx - value)) { 626 CommandLineError::print(verbose, 627 "TLABWasteIncrement (" UINTX_FORMAT ") must be " 628 "less than or equal to ergonomic TLAB waste increment maximum size(" SIZE_FORMAT ")\n", 629 value, (max_uintx - refill_waste_limit)); 630 return Flag::VIOLATES_CONSTRAINT; 631 } 632 } 633 return Flag::SUCCESS; 634 } 635 636 Flag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) { 637 if (FLAG_IS_CMDLINE(SurvivorRatio) && 638 (value > (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment()))) { 639 CommandLineError::print(verbose, 640 "SurvivorRatio (" UINTX_FORMAT ") must be " 641 "less than or equal to ergonomic SurvivorRatio maximum (" SIZE_FORMAT ")\n", 642 value, 643 (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment())); 644 return Flag::VIOLATES_CONSTRAINT; 645 } else { 646 return Flag::SUCCESS; 647 } 648 } 649 650 Flag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) { 651 if (value > MaxMetaspaceSize) { 652 CommandLineError::print(verbose, 653 "MetaspaceSize (" SIZE_FORMAT ") must be " 654 "less than or equal to MaxMetaspaceSize (" SIZE_FORMAT ")\n", 655 value, MaxMetaspaceSize); 656 return Flag::VIOLATES_CONSTRAINT; 657 } else { 658 return Flag::SUCCESS; 659 } 660 } 661 662 Flag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) { 663 if (value < MetaspaceSize) { 664 CommandLineError::print(verbose, 665 "MaxMetaspaceSize (" SIZE_FORMAT ") must be " 666 "greater than or equal to MetaspaceSize (" SIZE_FORMAT ")\n", 667 value, MaxMetaspaceSize); 668 return Flag::VIOLATES_CONSTRAINT; 669 } else { 670 return Flag::SUCCESS; 671 } 672 } 673 674 Flag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose) { 675 if (value != 0) { 676 if (!is_power_of_2(value)) { 677 CommandLineError::print(verbose, 678 "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " 679 "power of 2\n", 680 value); 681 return Flag::VIOLATES_CONSTRAINT; 682 } 683 if (value < ObjectAlignmentInBytes) { 684 CommandLineError::print(verbose, 685 "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " 686 "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n", 687 value, ObjectAlignmentInBytes); 688 return Flag::VIOLATES_CONSTRAINT; 689 } 690 } 691 return Flag::SUCCESS; 692 }