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