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