1 /* 2 * Copyright (c) 2015, 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 #include "precompiled.hpp" 26 #include "classfile/stringTable.hpp" 27 #include "classfile/symbolTable.hpp" 28 #include "gc/shared/jvmFlagConstraintsGC.hpp" 29 #include "runtime/arguments.hpp" 30 #include "runtime/flags/jvmFlag.hpp" 31 #include "runtime/flags/jvmFlagConstraintList.hpp" 32 #include "runtime/flags/jvmFlagConstraintsCompiler.hpp" 33 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp" 34 #include "runtime/globals.hpp" 35 #include "runtime/globals_extension.hpp" 36 #include "runtime/os.hpp" 37 #include "utilities/macros.hpp" 38 39 class JVMFlagConstraint_bool : public JVMFlagConstraint { 40 JVMFlagConstraintFunc_bool _constraint; 41 42 public: 43 JVMFlagConstraint_bool(const JVMFlag* flag, 44 JVMFlagConstraintFunc_bool func, 45 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 46 47 JVMFlag::Error apply(bool verbose) { 48 return _constraint(_flag->get_bool(), verbose); 49 } 50 51 JVMFlag::Error apply_bool(bool value, bool verbose) { 52 return _constraint(value, verbose); 53 } 54 }; 55 56 class JVMFlagConstraint_int : public JVMFlagConstraint { 57 JVMFlagConstraintFunc_int _constraint; 58 59 public: 60 JVMFlagConstraint_int(const JVMFlag* flag, 61 JVMFlagConstraintFunc_int func, 62 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 63 64 JVMFlag::Error apply(bool verbose) { 65 return _constraint(_flag->get_int(), verbose); 66 } 67 68 JVMFlag::Error apply_int(int value, bool verbose) { 69 return _constraint(value, verbose); 70 } 71 }; 72 73 class JVMFlagConstraint_intx : public JVMFlagConstraint { 74 JVMFlagConstraintFunc_intx _constraint; 75 76 public: 77 JVMFlagConstraint_intx(const JVMFlag* flag, 78 JVMFlagConstraintFunc_intx func, 79 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 80 81 JVMFlag::Error apply(bool verbose) { 82 return _constraint(_flag->get_intx(), verbose); 83 } 84 85 JVMFlag::Error apply_intx(intx value, bool verbose) { 86 return _constraint(value, verbose); 87 } 88 }; 89 90 class JVMFlagConstraint_uint : public JVMFlagConstraint { 91 JVMFlagConstraintFunc_uint _constraint; 92 93 public: 94 JVMFlagConstraint_uint(const JVMFlag* flag, 95 JVMFlagConstraintFunc_uint func, 96 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 97 98 JVMFlag::Error apply(bool verbose) { 99 return _constraint(_flag->get_uint(), verbose); 100 } 101 102 JVMFlag::Error apply_uint(uint value, bool verbose) { 103 return _constraint(value, verbose); 104 } 105 }; 106 107 class JVMFlagConstraint_uintx : public JVMFlagConstraint { 108 JVMFlagConstraintFunc_uintx _constraint; 109 110 public: 111 JVMFlagConstraint_uintx(const JVMFlag* flag, 112 JVMFlagConstraintFunc_uintx func, 113 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 114 115 JVMFlag::Error apply(bool verbose) { 116 return _constraint(_flag->get_uintx(), verbose); 117 } 118 119 JVMFlag::Error apply_uintx(uintx value, bool verbose) { 120 return _constraint(value, verbose); 121 } 122 }; 123 124 class JVMFlagConstraint_uint64_t : public JVMFlagConstraint { 125 JVMFlagConstraintFunc_uint64_t _constraint; 126 127 public: 128 JVMFlagConstraint_uint64_t(const JVMFlag* flag, 129 JVMFlagConstraintFunc_uint64_t func, 130 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 131 132 JVMFlag::Error apply(bool verbose) { 133 return _constraint(_flag->get_uint64_t(), verbose); 134 } 135 136 JVMFlag::Error apply_uint64_t(uint64_t value, bool verbose) { 137 return _constraint(value, verbose); 138 } 139 }; 140 141 class JVMFlagConstraint_size_t : public JVMFlagConstraint { 142 JVMFlagConstraintFunc_size_t _constraint; 143 144 public: 145 JVMFlagConstraint_size_t(const JVMFlag* flag, 146 JVMFlagConstraintFunc_size_t func, 147 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 148 149 JVMFlag::Error apply(bool verbose) { 150 return _constraint(_flag->get_size_t(), verbose); 151 } 152 153 JVMFlag::Error apply_size_t(size_t value, bool verbose) { 154 return _constraint(value, verbose); 155 } 156 }; 157 158 class JVMFlagConstraint_double : public JVMFlagConstraint { 159 JVMFlagConstraintFunc_double _constraint; 160 161 public: 162 JVMFlagConstraint_double(const JVMFlag* flag, 163 JVMFlagConstraintFunc_double func, 164 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {} 165 166 JVMFlag::Error apply(bool verbose) { 167 return _constraint(_flag->get_double(), verbose); 168 } 169 170 JVMFlag::Error apply_double(double value, bool verbose) { 171 return _constraint(value, verbose); 172 } 173 }; 174 175 // No constraint emitting 176 void emit_constraint_no(...) { /* NOP */ } 177 178 // No constraint emitting if function argument is NOT provided 179 void emit_constraint_bool(const JVMFlag* /*flag*/) { /* NOP */ } 180 void emit_constraint_ccstr(const JVMFlag* /*flag*/) { /* NOP */ } 181 void emit_constraint_ccstrlist(const JVMFlag* /*flag*/) { /* NOP */ } 182 void emit_constraint_int(const JVMFlag* /*flag*/) { /* NOP */ } 183 void emit_constraint_intx(const JVMFlag* /*flag*/) { /* NOP */ } 184 void emit_constraint_uint(const JVMFlag* /*flag*/) { /* NOP */ } 185 void emit_constraint_uintx(const JVMFlag* /*flag*/) { /* NOP */ } 186 void emit_constraint_uint64_t(const JVMFlag* /*flag*/) { /* NOP */ } 187 void emit_constraint_size_t(const JVMFlag* /*flag*/) { /* NOP */ } 188 void emit_constraint_double(const JVMFlag* /*flag*/) { /* NOP */ } 189 190 // JVMFlagConstraint emitting code functions if function argument is provided 191 void emit_constraint_bool(const JVMFlag* flag, JVMFlagConstraintFunc_bool func, JVMFlagConstraint::ConstraintType type) { 192 JVMFlagConstraintList::add(new JVMFlagConstraint_bool(flag, func, type)); 193 } 194 void emit_constraint_int(const JVMFlag* flag, JVMFlagConstraintFunc_int func, JVMFlagConstraint::ConstraintType type) { 195 JVMFlagConstraintList::add(new JVMFlagConstraint_int(flag, func, type)); 196 } 197 void emit_constraint_intx(const JVMFlag* flag, JVMFlagConstraintFunc_intx func, JVMFlagConstraint::ConstraintType type) { 198 JVMFlagConstraintList::add(new JVMFlagConstraint_intx(flag, func, type)); 199 } 200 void emit_constraint_uint(const JVMFlag* flag, JVMFlagConstraintFunc_uint func, JVMFlagConstraint::ConstraintType type) { 201 JVMFlagConstraintList::add(new JVMFlagConstraint_uint(flag, func, type)); 202 } 203 void emit_constraint_uintx(const JVMFlag* flag, JVMFlagConstraintFunc_uintx func, JVMFlagConstraint::ConstraintType type) { 204 JVMFlagConstraintList::add(new JVMFlagConstraint_uintx(flag, func, type)); 205 } 206 void emit_constraint_uint64_t(const JVMFlag* flag, JVMFlagConstraintFunc_uint64_t func, JVMFlagConstraint::ConstraintType type) { 207 JVMFlagConstraintList::add(new JVMFlagConstraint_uint64_t(flag, func, type)); 208 } 209 void emit_constraint_size_t(const JVMFlag* flag, JVMFlagConstraintFunc_size_t func, JVMFlagConstraint::ConstraintType type) { 210 JVMFlagConstraintList::add(new JVMFlagConstraint_size_t(flag, func, type)); 211 } 212 void emit_constraint_double(const JVMFlag* flag, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) { 213 JVMFlagConstraintList::add(new JVMFlagConstraint_double(flag, func, type)); 214 } 215 216 // Generate code to call emit_constraint_xxx function 217 #define EMIT_CONSTRAINT_START (void)(0 218 #define EMIT_CONSTRAINT(type, name) ); emit_constraint_##type(JVMFlagEx::flag_from_enum(FLAG_MEMBER_ENUM(name)) 219 #define EMIT_CONSTRAINT_NO ); emit_constraint_no(0 220 #define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 221 #define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 222 #define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 223 #define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 224 #define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 225 #define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc) EMIT_CONSTRAINT(type, name) 226 #define EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG(type, name, doc) EMIT_CONSTRAINT(type, name) 227 #ifndef PRODUCT 228 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 229 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) EMIT_CONSTRAINT(type, name) 230 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 231 #else 232 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO 233 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) EMIT_CONSTRAINT_NO 234 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO 235 #endif 236 #ifdef _LP64 237 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name) 238 #else 239 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO 240 #endif 241 #define EMIT_CONSTRAINT_END ); 242 243 // Generate func argument to pass into emit_constraint_xxx functions 244 #define EMIT_CONSTRAINT_CHECK(func, type) , func, JVMFlagConstraint::type 245 246 // the "name" argument must be a string literal 247 #define INITIAL_CONSTRAINTS_SIZE 72 248 GrowableArray<JVMFlagConstraint*>* JVMFlagConstraintList::_constraints = NULL; 249 JVMFlagConstraint::ConstraintType JVMFlagConstraintList::_validating_type = JVMFlagConstraint::AtParse; 250 251 // Check the ranges of all flags that have them or print them out and exit if requested 252 void JVMFlagConstraintList::init(void) { 253 _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, mtArguments); 254 255 EMIT_CONSTRAINT_START 256 257 ALL_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 258 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 259 EMIT_CONSTRAINT_PRODUCT_FLAG, 260 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 261 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 262 EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG, 263 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 264 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 265 EMIT_CONSTRAINT_MANAGEABLE_FLAG, 266 EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 267 EMIT_CONSTRAINT_LP64_PRODUCT_FLAG, 268 IGNORE_RANGE, 269 EMIT_CONSTRAINT_CHECK) 270 271 EMIT_CONSTRAINT_END 272 } 273 274 JVMFlagConstraint* JVMFlagConstraintList::find(const JVMFlag* flag) { 275 JVMFlagConstraint* found = NULL; 276 for (int i=0; i<length(); i++) { 277 JVMFlagConstraint* constraint = at(i); 278 if (constraint->flag() == flag) { 279 found = constraint; 280 break; 281 } 282 } 283 return found; 284 } 285 286 // Find constraints and return only if found constraint's type is equal or lower than current validating type. 287 JVMFlagConstraint* JVMFlagConstraintList::find_if_needs_check(const JVMFlag* flag) { 288 JVMFlagConstraint* found = NULL; 289 JVMFlagConstraint* constraint = find(flag); 290 if (constraint != NULL && (constraint->type() <= _validating_type)) { 291 found = constraint; 292 } 293 return found; 294 } 295 296 // Check constraints for specific constraint type. 297 bool JVMFlagConstraintList::check_constraints(JVMFlagConstraint::ConstraintType type) { 298 guarantee(type > _validating_type, "Constraint check is out of order."); 299 _validating_type = type; 300 301 bool status = true; 302 for (int i=0; i<length(); i++) { 303 JVMFlagConstraint* constraint = at(i); 304 if (type != constraint->type()) continue; 305 if (constraint->apply(true) != JVMFlag::SUCCESS) status = false; 306 } 307 return status; 308 }