1 /* 2 * Copyright (c) 2020, 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 #ifndef SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP 26 #define SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP 27 28 #include "runtime/flags/jvmFlag.hpp" 29 30 class outputStream; 31 template <typename T> class JVMTypedFlagLimit; 32 33 enum class JVMFlagConstraintPhase : int { 34 // Will be validated during argument processing (Arguments::parse_argument). 35 AtParse = 0, 36 // Will be validated inside Threads::create_vm(), right after Arguments::apply_ergo(). 37 AfterErgo = 1, 38 // Will be validated inside universe_init(), right after Metaspace::global_initialize(). 39 AfterMemoryInit = 2 40 }; 41 42 43 typedef JVMFlag::Error (*JVMFlagConstraintFunc_bool)(bool value, bool verbose); 44 typedef JVMFlag::Error (*JVMFlagConstraintFunc_int)(int value, bool verbose); 45 typedef JVMFlag::Error (*JVMFlagConstraintFunc_intx)(intx value, bool verbose); 46 typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint)(uint value, bool verbose); 47 typedef JVMFlag::Error (*JVMFlagConstraintFunc_uintx)(uintx value, bool verbose); 48 typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint64_t)(uint64_t value, bool verbose); 49 typedef JVMFlag::Error (*JVMFlagConstraintFunc_size_t)(size_t value, bool verbose); 50 typedef JVMFlag::Error (*JVMFlagConstraintFunc_double)(double value, bool verbose); 51 52 // A JVMFlagLimit is created for each JVMFlag that has a range() and/or constraint() in its declaration in 53 // the globals_xxx.hpp file. 54 // 55 // To query the range information of a JVMFlag: 56 // JVMFlagLimit::get_range(JVMFlag*) 57 // JVMFlagLimit::get_range_at(int flag_enum) 58 // If the given flag doesn't have a range, NULL is returned. 59 // 60 // To query the constraint information of a JVMFlag: 61 // JVMFlagLimit::get_constraint(JVMFlag*) 62 // JVMFlagLimit::get_constraint_at(int flag_enum) 63 // If the given flag doesn't have a constraint, NULL is returned. 64 65 class JVMFlagLimit { 66 short _constraint_func; 67 char _phase; 68 char _kind; 69 70 static const JVMFlagLimit* const* flagLimits; 71 static JVMFlagsEnum _last_checked; 72 static JVMFlagConstraintPhase _validating_phase; 73 74 protected: 75 static constexpr int HAS_RANGE = 1; 76 static constexpr int HAS_CONSTRAINT = 2; 77 78 private: get_kind_at(JVMFlagsEnum flag_enum,int required_kind)79 static const JVMFlagLimit* get_kind_at(JVMFlagsEnum flag_enum, int required_kind) { 80 const JVMFlagLimit* limit = at(flag_enum); 81 if (limit != NULL && (limit->_kind & required_kind) != 0) { 82 _last_checked = flag_enum; 83 return limit; 84 } else { 85 return NULL; 86 } 87 } 88 at(JVMFlagsEnum flag_enum)89 static const JVMFlagLimit* at(JVMFlagsEnum flag_enum) { 90 JVMFlag::assert_valid_flag_enum(flag_enum); 91 return flagLimits[static_cast<int>(flag_enum)]; 92 } 93 94 public: 95 void* constraint_func() const; phase() const96 char phase() const { return _phase; } kind() const97 char kind() const { return _kind; } 98 JVMFlagLimit(short func,short phase,short kind)99 constexpr JVMFlagLimit(short func, short phase, short kind) : _constraint_func(func), _phase(phase), _kind(kind) {} 100 get_range(const JVMFlag * flag)101 static const JVMFlagLimit* get_range(const JVMFlag* flag) { 102 return get_range_at(flag->flag_enum()); 103 } get_range_at(JVMFlagsEnum flag_enum)104 static const JVMFlagLimit* get_range_at(JVMFlagsEnum flag_enum) { 105 return get_kind_at(flag_enum, HAS_RANGE); 106 } 107 get_constraint(const JVMFlag * flag)108 static const JVMFlagLimit* get_constraint(const JVMFlag* flag) { 109 return get_constraint_at(flag->flag_enum()); 110 } get_constraint_at(JVMFlagsEnum flag_enum)111 static const JVMFlagLimit* get_constraint_at(JVMFlagsEnum flag_enum) { 112 return get_kind_at(flag_enum, HAS_CONSTRAINT); 113 } 114 115 static const JVMFlag* last_checked_flag(); 116 117 // Is the current value of each JVM flag within the allowed range (if specified) 118 static bool check_all_ranges(); 119 void print_range(outputStream* st, const JVMFlag* flag) const; 120 121 // Does the current value of each JVM flag satisfy the specified constraint 122 static bool check_all_constraints(JVMFlagConstraintPhase phase); 123 124 // If range/constraint checks fail, print verbose error messages only if we are parsing 125 // arguments from the command-line. Silently ignore any invalid values that are 126 // set programmatically via FLAG_SET_ERGO, etc. verbose_checks_needed()127 static bool verbose_checks_needed() { 128 return _validating_phase == JVMFlagConstraintPhase::AtParse; 129 } 130 validating_phase()131 static JVMFlagConstraintPhase validating_phase() { return _validating_phase; } 132 }; 133 134 enum ConstraintMarker { 135 next_two_args_are_constraint, 136 }; 137 138 template <typename T> 139 class JVMTypedFlagLimit : public JVMFlagLimit { 140 const T _min; 141 const T _max; 142 143 public: 144 // dummy - no range or constraint. This object will not be emitted into the .o file 145 // because we declare it as "const" but has no reference to it. JVMTypedFlagLimit(int dummy)146 constexpr JVMTypedFlagLimit(int dummy) : 147 JVMFlagLimit(0, 0, 0), _min(0), _max(0) {} 148 149 // range only JVMTypedFlagLimit(int dummy,T min,T max)150 constexpr JVMTypedFlagLimit(int dummy, T min, T max) : 151 JVMFlagLimit(0, 0, HAS_RANGE), _min(min), _max(max) {} 152 153 // constraint only JVMTypedFlagLimit(int dummy,ConstraintMarker dummy2,short func,int phase)154 constexpr JVMTypedFlagLimit(int dummy, ConstraintMarker dummy2, short func, int phase) : 155 JVMFlagLimit(func, phase, HAS_CONSTRAINT), _min(0), _max(0) {} 156 157 // range and constraint JVMTypedFlagLimit(int dummy,T min,T max,ConstraintMarker dummy2,short func,int phase)158 constexpr JVMTypedFlagLimit(int dummy, T min, T max, ConstraintMarker dummy2, short func, int phase) : 159 JVMFlagLimit(func, phase, HAS_RANGE | HAS_CONSTRAINT), _min(min), _max(max) {} 160 161 // constraint and range JVMTypedFlagLimit(int dummy,ConstraintMarker dummy2,short func,int phase,T min,T max)162 constexpr JVMTypedFlagLimit(int dummy, ConstraintMarker dummy2, short func, int phase, T min, T max) : 163 JVMFlagLimit(func, phase, HAS_RANGE | HAS_CONSTRAINT), _min(min), _max(max) {} 164 min() const165 T min() const { return _min; } max() const166 T max() const { return _max; } 167 }; 168 169 #endif // SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP 170