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