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