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