1 /*
   2  * Copyright (c) 2015, 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 "runtime/arguments.hpp"
  27 #include "runtime/commandLineFlagConstraintsGC.hpp"
  28 #include "runtime/globals.hpp"
  29 #include "utilities/defaultStream.hpp"
  30 
  31 #if INCLUDE_ALL_GCS
  32 #include "gc/g1/g1_globals.hpp"
  33 #include "gc/g1/heapRegionBounds.inline.hpp"
  34 #include "gc/parallel/parallelScavengeHeap.hpp"
  35 #include "gc/shared/plab.hpp"
  36 #endif // INCLUDE_ALL_GCS
  37 #ifdef COMPILER1
  38 #include "c1/c1_globals.hpp"
  39 #endif // COMPILER1
  40 #ifdef COMPILER2
  41 #include "opto/c2_globals.hpp"
  42 #endif // COMPILER2
  43 
  44 static void print_error_if_needed(bool verbose, const char* msg, ...) {
  45   if (verbose) {
  46     va_list listPointer;
  47     va_start(listPointer, msg);
  48     jio_vfprintf(defaultStream::error_stream(), msg, listPointer);
  49     va_end(listPointer);
  50   }
  51 }
  52 
  53 static Flag::Error MinPLABSizeBounds(const char* name, bool verbose, size_t value) {
  54 #if INCLUDE_ALL_GCS
  55   if ((UseConcMarkSweepGC || UseG1GC) && (value < PLAB::min_size())) {
  56     print_error_if_needed(verbose,
  57                           "%s (" SIZE_FORMAT ") must be "
  58                           "greater than ergonomic PLAB minimum size (" SIZE_FORMAT ")\n",
  59                           name, value, PLAB::min_size());
  60     return Flag::VIOLATES_CONSTRAINT;
  61   }
  62 #endif // INCLUDE_ALL_GCS
  63   return Flag::SUCCESS;
  64 }
  65 
  66 static Flag::Error MaxPLABSizeBounds(const char* name, bool verbose, size_t value) {
  67 #if INCLUDE_ALL_GCS
  68   if ((UseConcMarkSweepGC || UseG1GC) && (value > PLAB::max_size())) {
  69     print_error_if_needed(verbose,
  70                           "%s (" SIZE_FORMAT ") must be "
  71                           "greater than ergonomic PLAB minimum size (" SIZE_FORMAT ")\n",
  72                           name, value, PLAB::min_size());
  73     return Flag::VIOLATES_CONSTRAINT;
  74   }
  75 #endif // INCLUDE_ALL_GCS
  76   return Flag::SUCCESS;
  77 }
  78 
  79 static Flag::Error MinMaxPLABSizeBounds(const char* name, bool verbose, size_t value) {
  80   if (MinPLABSizeBounds(name, verbose, value) == Flag::SUCCESS) {
  81     return MaxPLABSizeBounds(name, verbose, value);
  82   }
  83   return Flag::VIOLATES_CONSTRAINT;
  84 }
  85 
  86 Flag::Error YoungPLABSizeConstraintFunc(bool verbose, size_t value) {
  87   return MinMaxPLABSizeBounds("YoungPLABSize", verbose, value);
  88 }
  89 
  90 Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx value) {
  91   if (value > MaxHeapFreeRatio) {
  92     print_error_if_needed(verbose,
  93                           "MinHeapFreeRatio (" UINTX_FORMAT ") must be "
  94                           "less than or equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
  95                           value, MaxHeapFreeRatio);
  96     return Flag::VIOLATES_CONSTRAINT;
  97   } else {
  98     return Flag::SUCCESS;
  99   }
 100 }
 101 
 102 Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx value) {
 103   if (value < MinHeapFreeRatio) {
 104     print_error_if_needed(verbose,
 105                           "MaxHeapFreeRatio (" UINTX_FORMAT ") must be "
 106                           "greater than or equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n",
 107                           value, MinHeapFreeRatio);
 108     return Flag::VIOLATES_CONSTRAINT;
 109   } else {
 110     return Flag::SUCCESS;
 111   }
 112 }
 113 
 114 Flag::Error MinMetaspaceFreeRatioConstraintFunc(bool verbose, uintx value) {
 115   if (value > MaxMetaspaceFreeRatio) {
 116     print_error_if_needed(verbose,
 117                           "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be "
 118                           "less than or equal to MaxMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
 119                           value, MaxMetaspaceFreeRatio);
 120     return Flag::VIOLATES_CONSTRAINT;
 121   } else {
 122     return Flag::SUCCESS;
 123   }
 124 }
 125 
 126 Flag::Error MaxMetaspaceFreeRatioConstraintFunc(bool verbose, uintx value) {
 127   if (value < MinMetaspaceFreeRatio) {
 128     print_error_if_needed(verbose,
 129                           "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be "
 130                           "greater than or equal to MinMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
 131                           value, MinMetaspaceFreeRatio);
 132     return Flag::VIOLATES_CONSTRAINT;
 133   } else {
 134     return Flag::SUCCESS;
 135   }
 136 }
 137 
 138 // GC workaround for "-XX:+UseConcMarkSweepGC"
 139 // which sets InitialTenuringThreshold to 7 but leaves MaxTenuringThreshold remaining at 6
 140 // and therefore would invalidate the constraint
 141 #define UseConcMarkSweepGCWorkaroundIfNeeded(initial, max) { \
 142   if ((initial == 7) && (max == 6)) { \
 143     return Flag::SUCCESS; \
 144   } \
 145 }
 146 
 147 Flag::Error InitialTenuringThresholdConstraintFunc(bool verbose, uintx value) {
 148   UseConcMarkSweepGCWorkaroundIfNeeded(value, MaxTenuringThreshold);
 149 
 150   if (value > MaxTenuringThreshold) {
 151     print_error_if_needed(verbose,
 152                           "InitialTenuringThreshold (" UINTX_FORMAT ") must be "
 153                           "less than or equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n",
 154                           value, MaxTenuringThreshold);
 155     return Flag::VIOLATES_CONSTRAINT;
 156   } else {
 157     return Flag::SUCCESS;
 158   }
 159 }
 160 
 161 Flag::Error MaxTenuringThresholdConstraintFunc(bool verbose, uintx value) {
 162   UseConcMarkSweepGCWorkaroundIfNeeded(InitialTenuringThreshold, value);
 163 
 164   if (value < InitialTenuringThreshold) {
 165     print_error_if_needed(verbose,
 166                           "MaxTenuringThreshold (" UINTX_FORMAT ") must be "
 167                           "greater than or equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n",
 168                           value, InitialTenuringThreshold);
 169     return Flag::VIOLATES_CONSTRAINT;
 170   } else {
 171     return Flag::SUCCESS;
 172   }
 173 }
 174 
 175 #if INCLUDE_ALL_GCS
 176 Flag::Error G1NewSizePercentConstraintFunc(bool verbose, uintx value) {
 177   if (value > G1MaxNewSizePercent) {
 178     print_error_if_needed(verbose,
 179                           "G1NewSizePercent (" UINTX_FORMAT ") must be "
 180                           "less than or equal to G1MaxNewSizePercent (" UINTX_FORMAT ")\n",
 181                           value, G1MaxNewSizePercent);
 182     return Flag::VIOLATES_CONSTRAINT;
 183   } else {
 184     return Flag::SUCCESS;
 185   }
 186 }
 187 
 188 Flag::Error G1MaxNewSizePercentConstraintFunc(bool verbose, uintx value) {
 189   if (value < G1NewSizePercent) {
 190     print_error_if_needed(verbose,
 191                           "G1MaxNewSizePercent (" UINTX_FORMAT ") must be "
 192                           "greater than or equal to G1NewSizePercent (" UINTX_FORMAT ")\n",
 193                           value, G1NewSizePercent);
 194     return Flag::VIOLATES_CONSTRAINT;
 195   } else {
 196     return Flag::SUCCESS;
 197   }
 198 }
 199 
 200 #endif // INCLUDE_ALL_GCS
 201 
 202 Flag::Error CMSOldPLABMinConstraintFunc(bool verbose, size_t value) {
 203   if (value > CMSOldPLABMax) {
 204     print_error_if_needed(verbose,
 205                           "CMSOldPLABMin (" SIZE_FORMAT ") must be "
 206                           "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
 207                           value, CMSOldPLABMax);
 208     return Flag::VIOLATES_CONSTRAINT;
 209   } else {
 210     return Flag::SUCCESS;
 211   }
 212 }
 213 
 214 Flag::Error CMSPrecleanDenominatorConstraintFunc(bool verbose, uintx value) {
 215   if (value <= CMSPrecleanNumerator) {
 216     print_error_if_needed(verbose,
 217                           "CMSPrecleanDenominator (" UINTX_FORMAT ") must be "
 218                           "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
 219                           value, CMSPrecleanNumerator);
 220     return Flag::VIOLATES_CONSTRAINT;
 221   } else {
 222     return Flag::SUCCESS;
 223   }
 224 }
 225 
 226 Flag::Error CMSPrecleanNumeratorConstraintFunc(bool verbose, uintx value) {
 227   if (value > (CMSPrecleanDenominator - 1)) {
 228     print_error_if_needed(verbose,
 229                           "CMSPrecleanNumerator (" UINTX_FORMAT ") must be "
 230                           "less than or equal to CMSPrecleanDenominator - 1 (" UINTX_FORMAT ")\n",
 231                           value, CMSPrecleanDenominator - 1);
 232     return Flag::VIOLATES_CONSTRAINT;
 233   } else {
 234     return Flag::SUCCESS;
 235   }
 236 }
 237 
 238 Flag::Error SurvivorAlignmentInBytesConstraintFunc(bool verbose, intx value) {
 239   if (value != 0) {
 240     if (!is_power_of_2(value)) {
 241       print_error_if_needed(verbose,
 242                             "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be "
 243                             "power of 2\n",
 244                             value);
 245       return Flag::VIOLATES_CONSTRAINT;
 246     }
 247     if (value < ObjectAlignmentInBytes) {
 248       print_error_if_needed(verbose,
 249                             "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be "
 250                             "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n",
 251                             value, ObjectAlignmentInBytes);
 252       return Flag::VIOLATES_CONSTRAINT;
 253     }
 254   }
 255   return Flag::SUCCESS;
 256 }