1 /*
   2  * Copyright (c) 2015, 2019, 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/cardTableRS.hpp"
  27 #include "gc/shared/collectedHeap.hpp"
  28 #include "gc/shared/gcArguments.hpp"
  29 #include "gc/shared/gcConfig.hpp"
  30 #include "gc/shared/jvmFlagConstraintsGC.hpp"
  31 #include "gc/shared/plab.hpp"
  32 #include "gc/shared/threadLocalAllocBuffer.hpp"
  33 #include "runtime/arguments.hpp"
  34 #include "runtime/globals.hpp"
  35 #include "runtime/thread.inline.hpp"
  36 #include "utilities/align.hpp"
  37 #include "utilities/macros.hpp"
  38 #include "utilities/powerOfTwo.hpp"
  39 #if INCLUDE_G1GC
  40 #include "gc/g1/jvmFlagConstraintsG1.hpp"
  41 #endif
  42 #if INCLUDE_PARALLELGC
  43 #include "gc/parallel/jvmFlagConstraintsParallel.hpp"
  44 #endif
  45 
  46 // Some flags that have default values that indicate that the
  47 // JVM should automatically determine an appropriate value
  48 // for that flag.  In those cases it is only appropriate for the
  49 // constraint checking to be done if the user has specified the
  50 // value(s) of the flag(s) on the command line.  In the constraint
  51 // checking functions,  FLAG_IS_CMDLINE() is used to check if
  52 // the flag has been set by the user and so should be checked.
  53 
  54 // As ParallelGCThreads differs among GC modes, we need constraint function.
  55 JVMFlag::Error ParallelGCThreadsConstraintFunc(uint value, bool verbose) {
  56   JVMFlag::Error status = JVMFlag::SUCCESS;
  57 
  58 #if INCLUDE_PARALLELGC
  59   status = ParallelGCThreadsConstraintFuncParallel(value, verbose);
  60   if (status != JVMFlag::SUCCESS) {
  61     return status;
  62   }
  63 #endif
  64 
  65   return status;
  66 }
  67 
  68 // As ConcGCThreads should be smaller than ParallelGCThreads,
  69 // we need constraint function.
  70 JVMFlag::Error ConcGCThreadsConstraintFunc(uint value, bool verbose) {
  71   // G1 GC use ConcGCThreads.
  72   if (GCConfig::is_gc_selected(CollectedHeap::G1) && (value > ParallelGCThreads)) {
  73     JVMFlag::printError(verbose,
  74                         "ConcGCThreads (" UINT32_FORMAT ") must be "
  75                         "less than or equal to ParallelGCThreads (" UINT32_FORMAT ")\n",
  76                         value, ParallelGCThreads);
  77     return JVMFlag::VIOLATES_CONSTRAINT;
  78   }
  79 
  80   return JVMFlag::SUCCESS;
  81 }
  82 
  83 static JVMFlag::Error MinPLABSizeBounds(const char* name, size_t value, bool verbose) {
  84   if ((GCConfig::is_gc_selected(CollectedHeap::G1) || GCConfig::is_gc_selected(CollectedHeap::Parallel)) &&
  85       (value < PLAB::min_size())) {
  86     JVMFlag::printError(verbose,
  87                         "%s (" SIZE_FORMAT ") must be "
  88                         "greater than or equal to ergonomic PLAB minimum size (" SIZE_FORMAT ")\n",
  89                         name, value, PLAB::min_size());
  90     return JVMFlag::VIOLATES_CONSTRAINT;
  91   }
  92 
  93   return JVMFlag::SUCCESS;
  94 }
  95 
  96 JVMFlag::Error MaxPLABSizeBounds(const char* name, size_t value, bool verbose) {
  97   if ((GCConfig::is_gc_selected(CollectedHeap::G1) ||
  98        GCConfig::is_gc_selected(CollectedHeap::Parallel)) && (value > PLAB::max_size())) {
  99     JVMFlag::printError(verbose,
 100                         "%s (" SIZE_FORMAT ") must be "
 101                         "less than or equal to ergonomic PLAB maximum size (" SIZE_FORMAT ")\n",
 102                         name, value, PLAB::max_size());
 103     return JVMFlag::VIOLATES_CONSTRAINT;
 104   }
 105 
 106   return JVMFlag::SUCCESS;
 107 }
 108 
 109 static JVMFlag::Error MinMaxPLABSizeBounds(const char* name, size_t value, bool verbose) {
 110   JVMFlag::Error status = MinPLABSizeBounds(name, value, verbose);
 111 
 112   if (status == JVMFlag::SUCCESS) {
 113     return MaxPLABSizeBounds(name, value, verbose);
 114   }
 115   return status;
 116 }
 117 
 118 JVMFlag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose) {
 119   return MinMaxPLABSizeBounds("YoungPLABSize", value, verbose);
 120 }
 121 
 122 JVMFlag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose) {
 123   JVMFlag::Error status = JVMFlag::SUCCESS;
 124 
 125   {
 126     status = MinMaxPLABSizeBounds("OldPLABSize", value, verbose);
 127   }
 128 
 129   return status;
 130 }
 131 
 132 JVMFlag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) {
 133   if (value > MaxHeapFreeRatio) {
 134     JVMFlag::printError(verbose,
 135                         "MinHeapFreeRatio (" UINTX_FORMAT ") must be "
 136                         "less than or equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
 137                         value, MaxHeapFreeRatio);
 138     return JVMFlag::VIOLATES_CONSTRAINT;
 139   } else {
 140     return JVMFlag::SUCCESS;
 141   }
 142 }
 143 
 144 JVMFlag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose) {
 145   if (value < MinHeapFreeRatio) {
 146     JVMFlag::printError(verbose,
 147                         "MaxHeapFreeRatio (" UINTX_FORMAT ") must be "
 148                         "greater than or equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n",
 149                         value, MinHeapFreeRatio);
 150     return JVMFlag::VIOLATES_CONSTRAINT;
 151   } else {
 152     return JVMFlag::SUCCESS;
 153   }
 154 }
 155 
 156 static JVMFlag::Error CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(size_t maxHeap, intx softRef, bool verbose) {
 157   if ((softRef > 0) && ((maxHeap / M) > (max_uintx / softRef))) {
 158     JVMFlag::printError(verbose,
 159                         "Desired lifetime of SoftReferences cannot be expressed correctly. "
 160                         "MaxHeapSize (" SIZE_FORMAT ") or SoftRefLRUPolicyMSPerMB "
 161                         "(" INTX_FORMAT ") is too large\n",
 162                         maxHeap, softRef);
 163     return JVMFlag::VIOLATES_CONSTRAINT;
 164   } else {
 165     return JVMFlag::SUCCESS;
 166   }
 167 }
 168 
 169 JVMFlag::Error SoftRefLRUPolicyMSPerMBConstraintFunc(intx value, bool verbose) {
 170   return CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(MaxHeapSize, value, verbose);
 171 }
 172 
 173 JVMFlag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose) {
 174   // value == 0 is handled by the range constraint.
 175   if (value > MarkStackSizeMax) {
 176     JVMFlag::printError(verbose,
 177                         "MarkStackSize (" SIZE_FORMAT ") must be "
 178                         "less than or equal to MarkStackSizeMax (" SIZE_FORMAT ")\n",
 179                         value, MarkStackSizeMax);
 180     return JVMFlag::VIOLATES_CONSTRAINT;
 181   } else {
 182     return JVMFlag::SUCCESS;
 183   }
 184 }
 185 
 186 JVMFlag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) {
 187   if (value > MaxMetaspaceFreeRatio) {
 188     JVMFlag::printError(verbose,
 189                         "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be "
 190                         "less than or equal to MaxMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
 191                         value, MaxMetaspaceFreeRatio);
 192     return JVMFlag::VIOLATES_CONSTRAINT;
 193   } else {
 194     return JVMFlag::SUCCESS;
 195   }
 196 }
 197 
 198 JVMFlag::Error MaxMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) {
 199   if (value < MinMetaspaceFreeRatio) {
 200     JVMFlag::printError(verbose,
 201                         "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be "
 202                         "greater than or equal to MinMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
 203                         value, MinMetaspaceFreeRatio);
 204     return JVMFlag::VIOLATES_CONSTRAINT;
 205   } else {
 206     return JVMFlag::SUCCESS;
 207   }
 208 }
 209 
 210 JVMFlag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose) {
 211 #if INCLUDE_PARALLELGC
 212   JVMFlag::Error status = InitialTenuringThresholdConstraintFuncParallel(value, verbose);
 213   if (status != JVMFlag::SUCCESS) {
 214     return status;
 215   }
 216 #endif
 217 
 218   return JVMFlag::SUCCESS;
 219 }
 220 
 221 JVMFlag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose) {
 222 #if INCLUDE_PARALLELGC
 223   JVMFlag::Error status = MaxTenuringThresholdConstraintFuncParallel(value, verbose);
 224   if (status != JVMFlag::SUCCESS) {
 225     return status;
 226   }
 227 #endif
 228 
 229   // MaxTenuringThreshold=0 means NeverTenure=false && AlwaysTenure=true
 230   if ((value == 0) && (NeverTenure || !AlwaysTenure)) {
 231     JVMFlag::printError(verbose,
 232                         "MaxTenuringThreshold (0) should match to NeverTenure=false "
 233                         "&& AlwaysTenure=true. But we have NeverTenure=%s "
 234                         "AlwaysTenure=%s\n",
 235                         NeverTenure ? "true" : "false",
 236                         AlwaysTenure ? "true" : "false");
 237     return JVMFlag::VIOLATES_CONSTRAINT;
 238   }
 239   return JVMFlag::SUCCESS;
 240 }
 241 
 242 JVMFlag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose) {
 243 #if INCLUDE_G1GC
 244   JVMFlag::Error status = MaxGCPauseMillisConstraintFuncG1(value, verbose);
 245   if (status != JVMFlag::SUCCESS) {
 246     return status;
 247   }
 248 #endif
 249 
 250   return JVMFlag::SUCCESS;
 251 }
 252 
 253 JVMFlag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose) {
 254 #if INCLUDE_G1GC
 255   JVMFlag::Error status = GCPauseIntervalMillisConstraintFuncG1(value, verbose);
 256   if (status != JVMFlag::SUCCESS) {
 257     return status;
 258   }
 259 #endif
 260 
 261   return JVMFlag::SUCCESS;
 262 }
 263 
 264 JVMFlag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose) {
 265   size_t aligned_max = align_down(max_uintx/2, Metaspace::reserve_alignment_words());
 266   if (value > aligned_max) {
 267     JVMFlag::printError(verbose,
 268                         "InitialBootClassLoaderMetaspaceSize (" SIZE_FORMAT ") must be "
 269                         "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n",
 270                         value, aligned_max);
 271     return JVMFlag::VIOLATES_CONSTRAINT;
 272   }
 273   return JVMFlag::SUCCESS;
 274 }
 275 
 276 // To avoid an overflow by 'align_up(value, alignment)'.
 277 static JVMFlag::Error MaxSizeForAlignment(const char* name, size_t value, size_t alignment, bool verbose) {
 278   size_t aligned_max = ((max_uintx - alignment) & ~(alignment-1));
 279   if (value > aligned_max) {
 280     JVMFlag::printError(verbose,
 281                         "%s (" SIZE_FORMAT ") must be "
 282                         "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n",
 283                         name, value, aligned_max);
 284     return JVMFlag::VIOLATES_CONSTRAINT;
 285   }
 286   return JVMFlag::SUCCESS;
 287 }
 288 
 289 static JVMFlag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bool verbose) {
 290   size_t heap_alignment;
 291 
 292 #if INCLUDE_G1GC
 293   if (UseG1GC) {
 294     // For G1 GC, we don't know until G1CollectedHeap is created.
 295     heap_alignment = MaxSizeForHeapAlignmentG1();
 296   } else
 297 #endif
 298   {
 299     heap_alignment = GCArguments::compute_heap_alignment();
 300   }
 301 
 302   return MaxSizeForAlignment(name, value, heap_alignment, verbose);
 303 }
 304 
 305 JVMFlag::Error MinHeapSizeConstraintFunc(size_t value, bool verbose) {
 306   return MaxSizeForHeapAlignment("MinHeapSize", value, verbose);
 307 }
 308 
 309 JVMFlag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose) {
 310   return MaxSizeForHeapAlignment("InitialHeapSize", value, verbose);
 311 }
 312 
 313 JVMFlag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose) {
 314   JVMFlag::Error status = MaxSizeForHeapAlignment("MaxHeapSize", value, verbose);
 315 
 316   if (status == JVMFlag::SUCCESS) {
 317     status = CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(value, SoftRefLRUPolicyMSPerMB, verbose);
 318   }
 319   return status;
 320 }
 321 
 322 JVMFlag::Error SoftMaxHeapSizeConstraintFunc(size_t value, bool verbose) {
 323   if (value > MaxHeapSize) {
 324     JVMFlag::printError(verbose, "SoftMaxHeapSize must be less than or equal to the maximum heap size\n");
 325     return JVMFlag::VIOLATES_CONSTRAINT;
 326   }
 327 
 328   return JVMFlag::SUCCESS;
 329 }
 330 
 331 JVMFlag::Error HeapBaseMinAddressConstraintFunc(size_t value, bool verbose) {
 332   // If an overflow happened in Arguments::set_heap_size(), MaxHeapSize will have too large a value.
 333   // Check for this by ensuring that MaxHeapSize plus the requested min base address still fit within max_uintx.
 334   if (UseCompressedOops && FLAG_IS_ERGO(MaxHeapSize) && (value > (max_uintx - MaxHeapSize))) {
 335     JVMFlag::printError(verbose,
 336                         "HeapBaseMinAddress (" SIZE_FORMAT ") or MaxHeapSize (" SIZE_FORMAT ") is too large. "
 337                         "Sum of them must be less than or equal to maximum of size_t (" SIZE_FORMAT ")\n",
 338                         value, MaxHeapSize, max_uintx);
 339     return JVMFlag::VIOLATES_CONSTRAINT;
 340   }
 341 
 342   return MaxSizeForHeapAlignment("HeapBaseMinAddress", value, verbose);
 343 }
 344 
 345 JVMFlag::Error NewSizeConstraintFunc(size_t value, bool verbose) {
 346 #if INCLUDE_G1GC
 347   JVMFlag::Error status = NewSizeConstraintFuncG1(value, verbose);
 348   if (status != JVMFlag::SUCCESS) {
 349     return status;
 350   }
 351 #endif
 352 
 353   return JVMFlag::SUCCESS;
 354 }
 355 
 356 JVMFlag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose) {
 357   // At least, alignment reserve area is needed.
 358   if (value < ThreadLocalAllocBuffer::alignment_reserve_in_bytes()) {
 359     JVMFlag::printError(verbose,
 360                         "MinTLABSize (" SIZE_FORMAT ") must be "
 361                         "greater than or equal to reserved area in TLAB (" SIZE_FORMAT ")\n",
 362                         value, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
 363     return JVMFlag::VIOLATES_CONSTRAINT;
 364   }
 365   if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) {
 366     JVMFlag::printError(verbose,
 367                         "MinTLABSize (" SIZE_FORMAT ") must be "
 368                         "less than or equal to ergonomic TLAB maximum (" SIZE_FORMAT ")\n",
 369                         value, ThreadLocalAllocBuffer::max_size() * HeapWordSize);
 370     return JVMFlag::VIOLATES_CONSTRAINT;
 371   }
 372   return JVMFlag::SUCCESS;
 373 }
 374 
 375 JVMFlag::Error TLABSizeConstraintFunc(size_t value, bool verbose) {
 376   // Skip for default value of zero which means set ergonomically.
 377   if (FLAG_IS_CMDLINE(TLABSize)) {
 378     if (value < MinTLABSize) {
 379       JVMFlag::printError(verbose,
 380                           "TLABSize (" SIZE_FORMAT ") must be "
 381                           "greater than or equal to MinTLABSize (" SIZE_FORMAT ")\n",
 382                           value, MinTLABSize);
 383       return JVMFlag::VIOLATES_CONSTRAINT;
 384     }
 385     if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) {
 386       JVMFlag::printError(verbose,
 387                           "TLABSize (" SIZE_FORMAT ") must be "
 388                           "less than or equal to ergonomic TLAB maximum size (" SIZE_FORMAT ")\n",
 389                           value, (ThreadLocalAllocBuffer::max_size() * HeapWordSize));
 390       return JVMFlag::VIOLATES_CONSTRAINT;
 391     }
 392   }
 393   return JVMFlag::SUCCESS;
 394 }
 395 
 396 // We will protect overflow from ThreadLocalAllocBuffer::record_slow_allocation(),
 397 // so AfterMemoryInit type is enough to check.
 398 JVMFlag::Error TLABWasteIncrementConstraintFunc(uintx value, bool verbose) {
 399   if (UseTLAB) {
 400     size_t refill_waste_limit = Thread::current()->tlab().refill_waste_limit();
 401 
 402     // Compare with 'max_uintx' as ThreadLocalAllocBuffer::_refill_waste_limit is 'size_t'.
 403     if (refill_waste_limit > (max_uintx - value)) {
 404       JVMFlag::printError(verbose,
 405                           "TLABWasteIncrement (" UINTX_FORMAT ") must be "
 406                           "less than or equal to ergonomic TLAB waste increment maximum size(" SIZE_FORMAT ")\n",
 407                           value, (max_uintx - refill_waste_limit));
 408       return JVMFlag::VIOLATES_CONSTRAINT;
 409     }
 410   }
 411   return JVMFlag::SUCCESS;
 412 }
 413 
 414 JVMFlag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) {
 415   if (FLAG_IS_CMDLINE(SurvivorRatio) &&
 416       (value > (MaxHeapSize / SpaceAlignment))) {
 417     JVMFlag::printError(verbose,
 418                         "SurvivorRatio (" UINTX_FORMAT ") must be "
 419                         "less than or equal to ergonomic SurvivorRatio maximum (" SIZE_FORMAT ")\n",
 420                         value,
 421                         (MaxHeapSize / SpaceAlignment));
 422     return JVMFlag::VIOLATES_CONSTRAINT;
 423   } else {
 424     return JVMFlag::SUCCESS;
 425   }
 426 }
 427 
 428 JVMFlag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) {
 429   if (value > MaxMetaspaceSize) {
 430     JVMFlag::printError(verbose,
 431                         "MetaspaceSize (" SIZE_FORMAT ") must be "
 432                         "less than or equal to MaxMetaspaceSize (" SIZE_FORMAT ")\n",
 433                         value, MaxMetaspaceSize);
 434     return JVMFlag::VIOLATES_CONSTRAINT;
 435   } else {
 436     return JVMFlag::SUCCESS;
 437   }
 438 }
 439 
 440 JVMFlag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) {
 441   if (value < MetaspaceSize) {
 442     JVMFlag::printError(verbose,
 443                         "MaxMetaspaceSize (" SIZE_FORMAT ") must be "
 444                         "greater than or equal to MetaspaceSize (" SIZE_FORMAT ")\n",
 445                         value, MaxMetaspaceSize);
 446     return JVMFlag::VIOLATES_CONSTRAINT;
 447   } else {
 448     return JVMFlag::SUCCESS;
 449   }
 450 }
 451 
 452 JVMFlag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose) {
 453   if (value != 0) {
 454     if (!is_power_of_2(value)) {
 455       JVMFlag::printError(verbose,
 456                           "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be "
 457                           "power of 2\n",
 458                           value);
 459       return JVMFlag::VIOLATES_CONSTRAINT;
 460     }
 461     if (value < ObjectAlignmentInBytes) {
 462       JVMFlag::printError(verbose,
 463                           "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be "
 464                           "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n",
 465                           value, ObjectAlignmentInBytes);
 466       return JVMFlag::VIOLATES_CONSTRAINT;
 467     }
 468   }
 469   return JVMFlag::SUCCESS;
 470 }