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 ") " 490 "whose size corresponds to the size of old generation of the Java heap\n", 491 value, bitmap_size); 492 return Flag::VIOLATES_CONSTRAINT; 493 } 494 } 495 #endif 496 return Flag::SUCCESS; 497 } 498 499 Flag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose) { 500 #if INCLUDE_ALL_GCS 501 if (UseG1GC && FLAG_IS_CMDLINE(MaxGCPauseMillis) && (value >= GCPauseIntervalMillis)) { 502 CommandLineError::print(verbose, 503 "MaxGCPauseMillis (" UINTX_FORMAT ") must be " 504 "less than GCPauseIntervalMillis (" UINTX_FORMAT ")\n", 505 value, GCPauseIntervalMillis); 506 return Flag::VIOLATES_CONSTRAINT; 507 } 508 #endif 509 510 return Flag::SUCCESS; 511 } 512 513 Flag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose) { 514 #if INCLUDE_ALL_GCS 515 if (UseG1GC) { 516 if (FLAG_IS_CMDLINE(GCPauseIntervalMillis)) { 517 if (value < 1) { 518 CommandLineError::print(verbose, 519 "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " 520 "greater than or equal to 1\n", 521 value); 522 return Flag::VIOLATES_CONSTRAINT; 523 } 524 if (value <= MaxGCPauseMillis) { 525 CommandLineError::print(verbose, 526 "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " 527 "greater than MaxGCPauseMillis (" UINTX_FORMAT ")\n", 528 value, MaxGCPauseMillis); 529 return Flag::VIOLATES_CONSTRAINT; 530 } 531 } 532 } 533 #endif 534 return Flag::SUCCESS; 535 } 536 537 Flag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose) { 538 size_t aligned_max = (size_t)align_size_down(max_uintx/2, Metaspace::reserve_alignment_words()); 539 if (value > aligned_max) { 540 CommandLineError::print(verbose, 541 "InitialBootClassLoaderMetaspaceSize (" SIZE_FORMAT ") must be " 542 "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", 543 value, aligned_max); 544 return Flag::VIOLATES_CONSTRAINT; 545 } 546 return Flag::SUCCESS; 547 } 548 549 // To avoid an overflow by 'align_size_up(value, alignment)'. 550 static Flag::Error MaxSizeForAlignment(const char* name, size_t value, size_t alignment, bool verbose) { 551 size_t aligned_max = ((max_uintx - alignment) & ~(alignment-1)); 552 if (value > aligned_max) { 553 CommandLineError::print(verbose, 554 "%s (" SIZE_FORMAT ") must be " 555 "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", 556 name, value, aligned_max); 557 return Flag::VIOLATES_CONSTRAINT; 558 } 559 return Flag::SUCCESS; 560 } 561 562 static Flag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bool verbose) { 563 // For G1 GC, we don't know until G1CollectorPolicy is created. 564 size_t heap_alignment; 565 566 #if INCLUDE_ALL_GCS 567 if (UseG1GC) { 568 heap_alignment = HeapRegionBounds::max_size(); 569 } else 570 #endif 571 { 572 heap_alignment = CollectorPolicy::compute_heap_alignment(); 573 } 574 575 return MaxSizeForAlignment(name, value, heap_alignment, verbose); 576 } 577 578 Flag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose) { 579 return MaxSizeForHeapAlignment("InitialHeapSize", value, verbose); 580 } 581 582 Flag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose) { 583 Flag::Error status = MaxSizeForHeapAlignment("MaxHeapSize", value, verbose); 584 585 if (status == Flag::SUCCESS) { 586 status = CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(value, SoftRefLRUPolicyMSPerMB, verbose); 587 } 588 return status; 589 } 590 591 Flag::Error HeapBaseMinAddressConstraintFunc(size_t value, bool verbose) { 592 // If an overflow happened in Arguments::set_heap_size(), MaxHeapSize will have too large a value. 593 // Check for this by ensuring that MaxHeapSize plus the requested min base address still fit within max_uintx. 594 if (UseCompressedOops && FLAG_IS_ERGO(MaxHeapSize) && (value > (max_uintx - MaxHeapSize))) { 595 CommandLineError::print(verbose, 596 "HeapBaseMinAddress (" SIZE_FORMAT ") or MaxHeapSize (" SIZE_FORMAT ") is too large. " 597 "Sum of them must be less than or equal to maximum of size_t (" SIZE_FORMAT ")\n", 598 value, MaxHeapSize, max_uintx); 599 return Flag::VIOLATES_CONSTRAINT; 600 } 601 602 return MaxSizeForHeapAlignment("HeapBaseMinAddress", value, verbose); 603 } 604 605 Flag::Error NewSizeConstraintFunc(size_t value, bool verbose) { 606 #ifdef _LP64 607 #if INCLUDE_ALL_GCS 608 // Overflow would happen for uint type variable of YoungGenSizer::_min_desired_young_length 609 // when the value to be assigned exceeds uint range. 610 // i.e. result of '(uint)(NewSize / region size(1~32MB))' 611 // So maximum of NewSize should be 'max_juint * 1M' 612 if (UseG1GC && (value > (max_juint * 1 * M))) { 613 CommandLineError::print(verbose, 614 "NewSize (" SIZE_FORMAT ") must be less than ergonomic maximum value\n", 615 value); 616 return Flag::VIOLATES_CONSTRAINT; 617 } 618 #endif // INCLUDE_ALL_GCS 619 #endif // _LP64 620 return Flag::SUCCESS; 621 } 622 623 Flag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose) { 624 // At least, alignment reserve area is needed. 625 if (value < ThreadLocalAllocBuffer::alignment_reserve_in_bytes()) { 626 CommandLineError::print(verbose, 627 "MinTLABSize (" SIZE_FORMAT ") must be " 628 "greater than or equal to reserved area in TLAB (" SIZE_FORMAT ")\n", 629 value, ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); 630 return Flag::VIOLATES_CONSTRAINT; 631 } 632 if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { 633 CommandLineError::print(verbose, 634 "MinTLABSize (" SIZE_FORMAT ") must be " 635 "less than or equal to ergonomic TLAB maximum (" SIZE_FORMAT ")\n", 636 value, ThreadLocalAllocBuffer::max_size() * HeapWordSize); 637 return Flag::VIOLATES_CONSTRAINT; 638 } 639 return Flag::SUCCESS; 640 } 641 642 Flag::Error TLABSizeConstraintFunc(size_t value, bool verbose) { 643 // Skip for default value of zero which means set ergonomically. 644 if (FLAG_IS_CMDLINE(TLABSize)) { 645 if (value < MinTLABSize) { 646 CommandLineError::print(verbose, 647 "TLABSize (" SIZE_FORMAT ") must be " 648 "greater than or equal to MinTLABSize (" SIZE_FORMAT ")\n", 649 value, MinTLABSize); 650 return Flag::VIOLATES_CONSTRAINT; 651 } 652 if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { 653 CommandLineError::print(verbose, 654 "TLABSize (" SIZE_FORMAT ") must be " 655 "less than or equal to ergonomic TLAB maximum size (" SIZE_FORMAT ")\n", 656 value, (ThreadLocalAllocBuffer::max_size() * HeapWordSize)); 657 return Flag::VIOLATES_CONSTRAINT; 658 } 659 } 660 return Flag::SUCCESS; 661 } 662 663 // We will protect overflow from ThreadLocalAllocBuffer::record_slow_allocation(), 664 // so AfterMemoryInit type is enough to check. 665 Flag::Error TLABWasteIncrementConstraintFunc(uintx value, bool verbose) { 666 if (UseTLAB) { 667 size_t refill_waste_limit = Thread::current()->tlab().refill_waste_limit(); 668 669 // Compare with 'max_uintx' as ThreadLocalAllocBuffer::_refill_waste_limit is 'size_t'. 670 if (refill_waste_limit > (max_uintx - value)) { 671 CommandLineError::print(verbose, 672 "TLABWasteIncrement (" UINTX_FORMAT ") must be " 673 "less than or equal to ergonomic TLAB waste increment maximum size(" SIZE_FORMAT ")\n", 674 value, (max_uintx - refill_waste_limit)); 675 return Flag::VIOLATES_CONSTRAINT; 676 } 677 } 678 return Flag::SUCCESS; 679 } 680 681 Flag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) { 682 if (FLAG_IS_CMDLINE(SurvivorRatio) && 683 (value > (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment()))) { 684 CommandLineError::print(verbose, 685 "SurvivorRatio (" UINTX_FORMAT ") must be " 686 "less than or equal to ergonomic SurvivorRatio maximum (" SIZE_FORMAT ")\n", 687 value, 688 (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment())); 689 return Flag::VIOLATES_CONSTRAINT; 690 } else { 691 return Flag::SUCCESS; 692 } 693 } 694 695 Flag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) { 696 if (value > MaxMetaspaceSize) { 697 CommandLineError::print(verbose, 698 "MetaspaceSize (" SIZE_FORMAT ") must be " 699 "less than or equal to MaxMetaspaceSize (" SIZE_FORMAT ")\n", 700 value, MaxMetaspaceSize); 701 return Flag::VIOLATES_CONSTRAINT; 702 } else { 703 return Flag::SUCCESS; 704 } 705 } 706 707 Flag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) { 708 if (value < MetaspaceSize) { 709 CommandLineError::print(verbose, 710 "MaxMetaspaceSize (" SIZE_FORMAT ") must be " 711 "greater than or equal to MetaspaceSize (" SIZE_FORMAT ")\n", 712 value, MaxMetaspaceSize); 713 return Flag::VIOLATES_CONSTRAINT; 714 } else { 715 return Flag::SUCCESS; 716 } 717 } 718 719 Flag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose) { 720 if (value != 0) { 721 if (!is_power_of_2(value)) { 722 CommandLineError::print(verbose, 723 "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " 724 "power of 2\n", 725 value); 726 return Flag::VIOLATES_CONSTRAINT; 727 } 728 if (value < ObjectAlignmentInBytes) { 729 CommandLineError::print(verbose, 730 "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " 731 "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n", 732 value, ObjectAlignmentInBytes); 733 return Flag::VIOLATES_CONSTRAINT; 734 } 735 } 736 return Flag::SUCCESS; 737 }