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 }