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 || UseParallelGC) && (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 || UseParallelGC) && (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 G1HeapRegionSizeConstraintFunc(size_t value, bool verbose) { 316 if (!UseG1GC) return Flag::SUCCESS; 317 318 // Default value of G1HeapRegionSize=0 means will be set ergonomically. 319 if (FLAG_IS_CMDLINE(G1HeapRegionSize) && (value < HeapRegionBounds::min_size())) { 320 CommandLineError::print(verbose, 321 "G1HeapRegionSize (" SIZE_FORMAT ") must be " 322 "greater than or equal to ergonomic heap region minimum size\n", 323 value); 324 return Flag::VIOLATES_CONSTRAINT; 325 } else { 326 return Flag::SUCCESS; 327 } 328 } 329 330 Flag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose) { 331 if (!UseG1GC) return Flag::SUCCESS; 332 333 if (value > G1MaxNewSizePercent) { 334 CommandLineError::print(verbose, 335 "G1NewSizePercent (" UINTX_FORMAT ") must be " 336 "less than or equal to G1MaxNewSizePercent (" UINTX_FORMAT ")\n", 337 value, G1MaxNewSizePercent); 338 return Flag::VIOLATES_CONSTRAINT; 339 } else { 340 return Flag::SUCCESS; 341 } 342 } 343 344 Flag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose) { 345 if (!UseG1GC) return Flag::SUCCESS; 346 347 if (value < G1NewSizePercent) { 348 CommandLineError::print(verbose, 349 "G1MaxNewSizePercent (" UINTX_FORMAT ") must be " 350 "greater than or equal to G1NewSizePercent (" UINTX_FORMAT ")\n", 351 value, G1NewSizePercent); 352 return Flag::VIOLATES_CONSTRAINT; 353 } else { 354 return Flag::SUCCESS; 355 } 356 } 357 #endif // INCLUDE_ALL_GCS 358 359 Flag::Error ParGCStridesPerThreadConstraintFunc(uintx value, bool verbose) { 360 #if INCLUDE_ALL_GCS 361 if (UseConcMarkSweepGC && (value > ((uintx)max_jint / (uintx)ParallelGCThreads))) { 362 CommandLineError::print(verbose, 363 "ParGCStridesPerThread (" UINTX_FORMAT ") must be " 364 "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n", 365 value, ((uintx)max_jint / (uintx)ParallelGCThreads)); 366 return Flag::VIOLATES_CONSTRAINT; 367 } 368 #endif 369 return Flag::SUCCESS; 370 } 371 372 Flag::Error ParGCCardsPerStrideChunkConstraintFunc(intx value, bool verbose) { 373 #if INCLUDE_ALL_GCS 374 if (UseConcMarkSweepGC) { 375 // ParGCCardsPerStrideChunk should be compared with card table size. 376 size_t heap_size = Universe::heap()->reserved_region().word_size(); 377 CardTableModRefBS* bs = (CardTableModRefBS*)GenCollectedHeap::heap()->rem_set()->bs(); 378 size_t card_table_size = bs->cards_required(heap_size) - 1; // Valid card table size 379 380 if ((size_t)value > card_table_size) { 381 CommandLineError::print(verbose, 382 "ParGCCardsPerStrideChunk (" INTX_FORMAT ") is too large for the heap size and " 383 "must be less than or equal to card table size (" SIZE_FORMAT ")\n", 384 value, card_table_size); 385 return Flag::VIOLATES_CONSTRAINT; 386 } 387 388 // ParGCCardsPerStrideChunk is used with n_strides(ParallelGCThreads*ParGCStridesPerThread) 389 // from CardTableModRefBSForCTRS::process_stride(). Note that ParGCStridesPerThread is already checked 390 // not to make an overflow with ParallelGCThreads from its constraint function. 391 uintx n_strides = ParallelGCThreads * ParGCStridesPerThread; 392 uintx ergo_max = max_uintx / n_strides; 393 if ((uintx)value > ergo_max) { 394 CommandLineError::print(verbose, 395 "ParGCCardsPerStrideChunk (" INTX_FORMAT ") must be " 396 "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n", 397 value, ergo_max); 398 return Flag::VIOLATES_CONSTRAINT; 399 } 400 } 401 #endif 402 return Flag::SUCCESS; 403 } 404 405 Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose) { 406 Flag::Error status = Flag::SUCCESS; 407 408 #if INCLUDE_ALL_GCS 409 if (UseConcMarkSweepGC) { 410 if (value > CMSOldPLABMax) { 411 CommandLineError::print(verbose, 412 "CMSOldPLABMin (" SIZE_FORMAT ") must be " 413 "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n", 414 value, CMSOldPLABMax); 415 return Flag::VIOLATES_CONSTRAINT; 416 } 417 status = MaxPLABSizeBounds("CMSOldPLABMin", value, verbose); 418 } 419 #endif 420 return status; 421 } 422 423 Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose) { 424 Flag::Error status = Flag::SUCCESS; 425 426 #if INCLUDE_ALL_GCS 427 if (UseConcMarkSweepGC) { 428 status = MaxPLABSizeBounds("CMSOldPLABMax", value, verbose); 429 } 430 #endif 431 return status; 432 } 433 434 Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose) { 435 if (value > MarkStackSizeMax) { 436 CommandLineError::print(verbose, 437 "MarkStackSize (" SIZE_FORMAT ") must be " 438 "less than or equal to MarkStackSizeMax (" SIZE_FORMAT ")\n", 439 value, MarkStackSizeMax); 440 return Flag::VIOLATES_CONSTRAINT; 441 } else { 442 return Flag::SUCCESS; 443 } 444 } 445 446 static Flag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) { 447 #if INCLUDE_ALL_GCS 448 if (UseConcMarkSweepGC) { 449 ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*)GenCollectedHeap::heap()->old_gen(); 450 const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size(); 451 if (value > ergo_max) { 452 CommandLineError::print(verbose, 453 "%s (" SIZE_FORMAT ") must be " 454 "less than or equal to ergonomic maximum (" SIZE_FORMAT ") " 455 "which is based on the maximum size of the old generation of the Java heap\n", 456 name, value, ergo_max); 457 return Flag::VIOLATES_CONSTRAINT; 458 } 459 } 460 #endif 461 462 return Flag::SUCCESS; 463 } 464 465 Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose) { 466 Flag::Error status = CMSReservedAreaConstraintFunc("CMSRescanMultiple", value, verbose); 467 468 #if INCLUDE_ALL_GCS 469 if (status == Flag::SUCCESS && UseConcMarkSweepGC) { 470 // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size() 471 // to be aligned to CardTableModRefBS::card_size * BitsPerWord. 472 // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize' 473 // because rescan_task_size() is CardTableModRefBS::card_size / HeapWordSize * BitsPerWord. 474 if (value % HeapWordSize != 0) { 475 CommandLineError::print(verbose, 476 "CMSRescanMultiple (" SIZE_FORMAT ") must be " 477 "a multiple of " SIZE_FORMAT "\n", 478 value, HeapWordSize); 479 status = Flag::VIOLATES_CONSTRAINT; 480 } 481 } 482 #endif 483 484 return status; 485 } 486 487 Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose) { 488 return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose); 489 } 490 491 Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) { 492 #if INCLUDE_ALL_GCS 493 if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) { 494 CommandLineError::print(verbose, 495 "CMSPrecleanDenominator (" UINTX_FORMAT ") must be " 496 "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n", 497 value, CMSPrecleanNumerator); 498 return Flag::VIOLATES_CONSTRAINT; 499 } 500 #endif 501 return Flag::SUCCESS; 502 } 503 504 Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) { 505 #if INCLUDE_ALL_GCS 506 if (UseConcMarkSweepGC && (value >= CMSPrecleanDenominator)) { 507 CommandLineError::print(verbose, 508 "CMSPrecleanNumerator (" UINTX_FORMAT ") must be " 509 "less than CMSPrecleanDenominator (" UINTX_FORMAT ")\n", 510 value, CMSPrecleanDenominator); 511 return Flag::VIOLATES_CONSTRAINT; 512 } 513 #endif 514 return Flag::SUCCESS; 515 } 516 517 Flag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose) { 518 #if INCLUDE_ALL_GCS 519 if (UseConcMarkSweepGC) { 520 size_t max_capacity = GenCollectedHeap::heap()->young_gen()->max_capacity(); 521 if (value > max_uintx - max_capacity) { 522 CommandLineError::print(verbose, 523 "CMSSamplingGrain (" UINTX_FORMAT ") must be " 524 "less than or equal to ergonomic maximum (" SIZE_FORMAT ")\n", 525 value, max_uintx - max_capacity); 526 return Flag::VIOLATES_CONSTRAINT; 527 } 528 } 529 #endif 530 return Flag::SUCCESS; 531 } 532 533 Flag::Error CMSWorkQueueDrainThresholdConstraintFunc(uintx value, bool verbose) { 534 #if INCLUDE_ALL_GCS 535 if (UseConcMarkSweepGC) { 536 return ParallelGCThreadsAndCMSWorkQueueDrainThreshold(ParallelGCThreads, value, verbose); 537 } 538 #endif 539 return Flag::SUCCESS; 540 } 541 542 Flag::Error CMSBitMapYieldQuantumConstraintFunc(size_t value, bool verbose) { 543 #if INCLUDE_ALL_GCS 544 // Skip for current default value. 545 if (UseConcMarkSweepGC && FLAG_IS_CMDLINE(CMSBitMapYieldQuantum)) { 546 // CMSBitMapYieldQuantum should be compared with mark bitmap size. 547 ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*)GenCollectedHeap::heap()->old_gen(); 548 size_t bitmap_size = cms->collector()->markBitMap()->sizeInWords(); 549 550 if (value > bitmap_size) { 551 CommandLineError::print(verbose, 552 "CMSBitMapYieldQuantum (" SIZE_FORMAT ") must " 553 "be less than or equal to bitmap size (" SIZE_FORMAT ") " 554 "whose size corresponds to the size of old generation of the Java heap\n", 555 value, bitmap_size); 556 return Flag::VIOLATES_CONSTRAINT; 557 } 558 } 559 #endif 560 return Flag::SUCCESS; 561 } 562 563 Flag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose) { 564 #if INCLUDE_ALL_GCS 565 if (UseG1GC && FLAG_IS_CMDLINE(MaxGCPauseMillis) && (value >= GCPauseIntervalMillis)) { 566 CommandLineError::print(verbose, 567 "MaxGCPauseMillis (" UINTX_FORMAT ") must be " 568 "less than GCPauseIntervalMillis (" UINTX_FORMAT ")\n", 569 value, GCPauseIntervalMillis); 570 return Flag::VIOLATES_CONSTRAINT; 571 } 572 #endif 573 574 return Flag::SUCCESS; 575 } 576 577 Flag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose) { 578 #if INCLUDE_ALL_GCS 579 if (UseG1GC) { 580 if (FLAG_IS_CMDLINE(GCPauseIntervalMillis)) { 581 if (value < 1) { 582 CommandLineError::print(verbose, 583 "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " 584 "greater than or equal to 1\n", 585 value); 586 return Flag::VIOLATES_CONSTRAINT; 587 } 588 589 if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) { 590 CommandLineError::print(verbose, 591 "GCPauseIntervalMillis cannot be set " 592 "without setting MaxGCPauseMillis\n"); 593 return Flag::VIOLATES_CONSTRAINT; 594 } 595 596 if (value <= MaxGCPauseMillis) { 597 CommandLineError::print(verbose, 598 "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " 599 "greater than MaxGCPauseMillis (" UINTX_FORMAT ")\n", 600 value, MaxGCPauseMillis); 601 return Flag::VIOLATES_CONSTRAINT; 602 } 603 } 604 } 605 #endif 606 return Flag::SUCCESS; 607 } 608 609 Flag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose) { 610 size_t aligned_max = (size_t)align_size_down(max_uintx/2, Metaspace::reserve_alignment_words()); 611 if (value > aligned_max) { 612 CommandLineError::print(verbose, 613 "InitialBootClassLoaderMetaspaceSize (" SIZE_FORMAT ") must be " 614 "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", 615 value, aligned_max); 616 return Flag::VIOLATES_CONSTRAINT; 617 } 618 return Flag::SUCCESS; 619 } 620 621 // To avoid an overflow by 'align_size_up(value, alignment)'. 622 static Flag::Error MaxSizeForAlignment(const char* name, size_t value, size_t alignment, bool verbose) { 623 size_t aligned_max = ((max_uintx - alignment) & ~(alignment-1)); 624 if (value > aligned_max) { 625 CommandLineError::print(verbose, 626 "%s (" SIZE_FORMAT ") must be " 627 "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", 628 name, value, aligned_max); 629 return Flag::VIOLATES_CONSTRAINT; 630 } 631 return Flag::SUCCESS; 632 } 633 634 static Flag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bool verbose) { 635 // For G1 GC, we don't know until G1CollectorPolicy is created. 636 size_t heap_alignment; 637 638 #if INCLUDE_ALL_GCS 639 if (UseG1GC) { 640 heap_alignment = HeapRegionBounds::max_size(); 641 } else 642 #endif 643 { 644 heap_alignment = CollectorPolicy::compute_heap_alignment(); 645 } 646 647 return MaxSizeForAlignment(name, value, heap_alignment, verbose); 648 } 649 650 Flag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose) { 651 return MaxSizeForHeapAlignment("InitialHeapSize", value, verbose); 652 } 653 654 Flag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose) { 655 Flag::Error status = MaxSizeForHeapAlignment("MaxHeapSize", value, verbose); 656 657 if (status == Flag::SUCCESS) { 658 status = CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(value, SoftRefLRUPolicyMSPerMB, verbose); 659 } 660 return status; 661 } 662 663 Flag::Error HeapBaseMinAddressConstraintFunc(size_t value, bool verbose) { 664 // If an overflow happened in Arguments::set_heap_size(), MaxHeapSize will have too large a value. 665 // Check for this by ensuring that MaxHeapSize plus the requested min base address still fit within max_uintx. 666 if (UseCompressedOops && FLAG_IS_ERGO(MaxHeapSize) && (value > (max_uintx - MaxHeapSize))) { 667 CommandLineError::print(verbose, 668 "HeapBaseMinAddress (" SIZE_FORMAT ") or MaxHeapSize (" SIZE_FORMAT ") is too large. " 669 "Sum of them must be less than or equal to maximum of size_t (" SIZE_FORMAT ")\n", 670 value, MaxHeapSize, max_uintx); 671 return Flag::VIOLATES_CONSTRAINT; 672 } 673 674 return MaxSizeForHeapAlignment("HeapBaseMinAddress", value, verbose); 675 } 676 677 Flag::Error NewSizeConstraintFunc(size_t value, bool verbose) { 678 #ifdef _LP64 679 #if INCLUDE_ALL_GCS 680 // Overflow would happen for uint type variable of YoungGenSizer::_min_desired_young_length 681 // when the value to be assigned exceeds uint range. 682 // i.e. result of '(uint)(NewSize / region size(1~32MB))' 683 // So maximum of NewSize should be 'max_juint * 1M' 684 if (UseG1GC && (value > (max_juint * 1 * M))) { 685 CommandLineError::print(verbose, 686 "NewSize (" SIZE_FORMAT ") must be less than ergonomic maximum value\n", 687 value); 688 return Flag::VIOLATES_CONSTRAINT; 689 } 690 #endif // INCLUDE_ALL_GCS 691 #endif // _LP64 692 return Flag::SUCCESS; 693 } 694 695 Flag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose) { 696 // At least, alignment reserve area is needed. 697 if (value < ThreadLocalAllocBuffer::alignment_reserve_in_bytes()) { 698 CommandLineError::print(verbose, 699 "MinTLABSize (" SIZE_FORMAT ") must be " 700 "greater than or equal to reserved area in TLAB (" SIZE_FORMAT ")\n", 701 value, ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); 702 return Flag::VIOLATES_CONSTRAINT; 703 } 704 if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { 705 CommandLineError::print(verbose, 706 "MinTLABSize (" SIZE_FORMAT ") must be " 707 "less than or equal to ergonomic TLAB maximum (" SIZE_FORMAT ")\n", 708 value, ThreadLocalAllocBuffer::max_size() * HeapWordSize); 709 return Flag::VIOLATES_CONSTRAINT; 710 } 711 return Flag::SUCCESS; 712 } 713 714 Flag::Error TLABSizeConstraintFunc(size_t value, bool verbose) { 715 // Skip for default value of zero which means set ergonomically. 716 if (FLAG_IS_CMDLINE(TLABSize)) { 717 if (value < MinTLABSize) { 718 CommandLineError::print(verbose, 719 "TLABSize (" SIZE_FORMAT ") must be " 720 "greater than or equal to MinTLABSize (" SIZE_FORMAT ")\n", 721 value, MinTLABSize); 722 return Flag::VIOLATES_CONSTRAINT; 723 } 724 if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { 725 CommandLineError::print(verbose, 726 "TLABSize (" SIZE_FORMAT ") must be " 727 "less than or equal to ergonomic TLAB maximum size (" SIZE_FORMAT ")\n", 728 value, (ThreadLocalAllocBuffer::max_size() * HeapWordSize)); 729 return Flag::VIOLATES_CONSTRAINT; 730 } 731 } 732 return Flag::SUCCESS; 733 } 734 735 // We will protect overflow from ThreadLocalAllocBuffer::record_slow_allocation(), 736 // so AfterMemoryInit type is enough to check. 737 Flag::Error TLABWasteIncrementConstraintFunc(uintx value, bool verbose) { 738 if (UseTLAB) { 739 size_t refill_waste_limit = Thread::current()->tlab().refill_waste_limit(); 740 741 // Compare with 'max_uintx' as ThreadLocalAllocBuffer::_refill_waste_limit is 'size_t'. 742 if (refill_waste_limit > (max_uintx - value)) { 743 CommandLineError::print(verbose, 744 "TLABWasteIncrement (" UINTX_FORMAT ") must be " 745 "less than or equal to ergonomic TLAB waste increment maximum size(" SIZE_FORMAT ")\n", 746 value, (max_uintx - refill_waste_limit)); 747 return Flag::VIOLATES_CONSTRAINT; 748 } 749 } 750 return Flag::SUCCESS; 751 } 752 753 Flag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) { 754 if (FLAG_IS_CMDLINE(SurvivorRatio) && 755 (value > (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment()))) { 756 CommandLineError::print(verbose, 757 "SurvivorRatio (" UINTX_FORMAT ") must be " 758 "less than or equal to ergonomic SurvivorRatio maximum (" SIZE_FORMAT ")\n", 759 value, 760 (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment())); 761 return Flag::VIOLATES_CONSTRAINT; 762 } else { 763 return Flag::SUCCESS; 764 } 765 } 766 767 Flag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) { 768 if (value > MaxMetaspaceSize) { 769 CommandLineError::print(verbose, 770 "MetaspaceSize (" SIZE_FORMAT ") must be " 771 "less than or equal to MaxMetaspaceSize (" SIZE_FORMAT ")\n", 772 value, MaxMetaspaceSize); 773 return Flag::VIOLATES_CONSTRAINT; 774 } else { 775 return Flag::SUCCESS; 776 } 777 } 778 779 Flag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) { 780 if (value < MetaspaceSize) { 781 CommandLineError::print(verbose, 782 "MaxMetaspaceSize (" SIZE_FORMAT ") must be " 783 "greater than or equal to MetaspaceSize (" SIZE_FORMAT ")\n", 784 value, MaxMetaspaceSize); 785 return Flag::VIOLATES_CONSTRAINT; 786 } else { 787 return Flag::SUCCESS; 788 } 789 } 790 791 Flag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose) { 792 if (value != 0) { 793 if (!is_power_of_2(value)) { 794 CommandLineError::print(verbose, 795 "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " 796 "power of 2\n", 797 value); 798 return Flag::VIOLATES_CONSTRAINT; 799 } 800 if (value < ObjectAlignmentInBytes) { 801 CommandLineError::print(verbose, 802 "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " 803 "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n", 804 value, ObjectAlignmentInBytes); 805 return Flag::VIOLATES_CONSTRAINT; 806 } 807 } 808 return Flag::SUCCESS; 809 }