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