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