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