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