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 "classfile/stringTable.hpp" 27 #include "classfile/symbolTable.hpp" 28 #include "gc/shared/referenceProcessor.hpp" 29 #include "runtime/arguments.hpp" 30 #include "runtime/flags/jvmFlagConstraintList.hpp" 31 #include "runtime/flags/jvmFlagConstraintsCompiler.hpp" 32 #include "runtime/flags/jvmFlagConstraintsGC.hpp" 33 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp" 34 #include "runtime/os.hpp" 35 #include "utilities/macros.hpp" 36 #if INCLUDE_ALL_GCS 37 #include "gc/g1/g1_globals.hpp" 38 #endif 39 #ifdef COMPILER1 40 #include "c1/c1_globals.hpp" 41 #endif 42 #ifdef COMPILER2 43 #include "opto/c2_globals.hpp" 44 #endif 45 46 47 class JVMFlagConstraint_bool : public JVMFlagConstraint { 48 JVMFlagConstraintFunc_bool _constraint; 49 const bool* _ptr; 50 51 public: 52 // the "name" argument must be a string literal 53 JVMFlagConstraint_bool(const char* name, const bool* ptr, 54 JVMFlagConstraintFunc_bool func, 55 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 56 57 JVMFlag::Error apply(bool verbose) { 58 bool value = *_ptr; 59 return _constraint(value, verbose); 60 } 61 62 JVMFlag::Error apply_bool(bool value, bool verbose) { 63 return _constraint(value, verbose); 64 } 65 }; 66 67 class JVMFlagConstraint_int : public JVMFlagConstraint { 68 JVMFlagConstraintFunc_int _constraint; 69 const int* _ptr; 70 71 public: 72 // the "name" argument must be a string literal 73 JVMFlagConstraint_int(const char* name, const int* ptr, 74 JVMFlagConstraintFunc_int func, 75 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 76 77 JVMFlag::Error apply(bool verbose) { 78 int value = *_ptr; 79 return _constraint(value, verbose); 80 } 81 82 JVMFlag::Error apply_int(int value, bool verbose) { 83 return _constraint(value, verbose); 84 } 85 }; 86 87 class JVMFlagConstraint_intx : public JVMFlagConstraint { 88 JVMFlagConstraintFunc_intx _constraint; 89 const intx* _ptr; 90 91 public: 92 // the "name" argument must be a string literal 93 JVMFlagConstraint_intx(const char* name, const intx* ptr, 94 JVMFlagConstraintFunc_intx func, 95 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 96 97 JVMFlag::Error apply(bool verbose) { 98 intx value = *_ptr; 99 return _constraint(value, verbose); 100 } 101 102 JVMFlag::Error apply_intx(intx value, bool verbose) { 103 return _constraint(value, verbose); 104 } 105 }; 106 107 class JVMFlagConstraint_uint : public JVMFlagConstraint { 108 JVMFlagConstraintFunc_uint _constraint; 109 const uint* _ptr; 110 111 public: 112 // the "name" argument must be a string literal 113 JVMFlagConstraint_uint(const char* name, const uint* ptr, 114 JVMFlagConstraintFunc_uint func, 115 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 116 117 JVMFlag::Error apply(bool verbose) { 118 uint value = *_ptr; 119 return _constraint(value, verbose); 120 } 121 122 JVMFlag::Error apply_uint(uint value, bool verbose) { 123 return _constraint(value, verbose); 124 } 125 }; 126 127 class JVMFlagConstraint_uintx : public JVMFlagConstraint { 128 JVMFlagConstraintFunc_uintx _constraint; 129 const uintx* _ptr; 130 131 public: 132 // the "name" argument must be a string literal 133 JVMFlagConstraint_uintx(const char* name, const uintx* ptr, 134 JVMFlagConstraintFunc_uintx func, 135 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 136 137 JVMFlag::Error apply(bool verbose) { 138 uintx value = *_ptr; 139 return _constraint(value, verbose); 140 } 141 142 JVMFlag::Error apply_uintx(uintx value, bool verbose) { 143 return _constraint(value, verbose); 144 } 145 }; 146 147 class JVMFlagConstraint_uint64_t : public JVMFlagConstraint { 148 JVMFlagConstraintFunc_uint64_t _constraint; 149 const uint64_t* _ptr; 150 151 public: 152 // the "name" argument must be a string literal 153 JVMFlagConstraint_uint64_t(const char* name, const uint64_t* ptr, 154 JVMFlagConstraintFunc_uint64_t func, 155 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 156 157 JVMFlag::Error apply(bool verbose) { 158 uint64_t value = *_ptr; 159 return _constraint(value, verbose); 160 } 161 162 JVMFlag::Error apply_uint64_t(uint64_t value, bool verbose) { 163 return _constraint(value, verbose); 164 } 165 }; 166 167 class JVMFlagConstraint_size_t : public JVMFlagConstraint { 168 JVMFlagConstraintFunc_size_t _constraint; 169 const size_t* _ptr; 170 public: 171 // the "name" argument must be a string literal 172 JVMFlagConstraint_size_t(const char* name, const size_t* ptr, 173 JVMFlagConstraintFunc_size_t func, 174 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 175 176 JVMFlag::Error apply(bool verbose) { 177 size_t value = *_ptr; 178 return _constraint(value, verbose); 179 } 180 181 JVMFlag::Error apply_size_t(size_t value, bool verbose) { 182 return _constraint(value, verbose); 183 } 184 }; 185 186 class JVMFlagConstraint_double : public JVMFlagConstraint { 187 JVMFlagConstraintFunc_double _constraint; 188 const double* _ptr; 189 190 public: 191 // the "name" argument must be a string literal 192 JVMFlagConstraint_double(const char* name, const double* ptr, 193 JVMFlagConstraintFunc_double func, 194 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {} 195 196 JVMFlag::Error apply(bool verbose) { 197 double value = *_ptr; 198 return _constraint(value, verbose); 199 } 200 201 JVMFlag::Error apply_double(double value, bool verbose) { 202 return _constraint(value, verbose); 203 } 204 }; 205 206 // No constraint emitting 207 void emit_constraint_no(...) { /* NOP */ } 208 209 // No constraint emitting if function argument is NOT provided 210 void emit_constraint_bool(const char* /*name*/, const bool* /*value*/) { /* NOP */ } 211 void emit_constraint_ccstr(const char* /*name*/, const ccstr* /*value*/) { /* NOP */ } 212 void emit_constraint_ccstrlist(const char* /*name*/, const ccstrlist* /*value*/) { /* NOP */ } 213 void emit_constraint_int(const char* /*name*/, const int* /*value*/) { /* NOP */ } 214 void emit_constraint_intx(const char* /*name*/, const intx* /*value*/) { /* NOP */ } 215 void emit_constraint_uint(const char* /*name*/, const uint* /*value*/) { /* NOP */ } 216 void emit_constraint_uintx(const char* /*name*/, const uintx* /*value*/) { /* NOP */ } 217 void emit_constraint_uint64_t(const char* /*name*/, const uint64_t* /*value*/) { /* NOP */ } 218 void emit_constraint_size_t(const char* /*name*/, const size_t* /*value*/) { /* NOP */ } 219 void emit_constraint_double(const char* /*name*/, const double* /*value*/) { /* NOP */ } 220 221 // JVMFlagConstraint emitting code functions if function argument is provided 222 void emit_constraint_bool(const char* name, const bool* ptr, JVMFlagConstraintFunc_bool func, JVMFlagConstraint::ConstraintType type) { 223 JVMFlagConstraintList::add(new JVMFlagConstraint_bool(name, ptr, func, type)); 224 } 225 void emit_constraint_int(const char* name, const int* ptr, JVMFlagConstraintFunc_int func, JVMFlagConstraint::ConstraintType type) { 226 JVMFlagConstraintList::add(new JVMFlagConstraint_int(name, ptr, func, type)); 227 } 228 void emit_constraint_intx(const char* name, const intx* ptr, JVMFlagConstraintFunc_intx func, JVMFlagConstraint::ConstraintType type) { 229 JVMFlagConstraintList::add(new JVMFlagConstraint_intx(name, ptr, func, type)); 230 } 231 void emit_constraint_uint(const char* name, const uint* ptr, JVMFlagConstraintFunc_uint func, JVMFlagConstraint::ConstraintType type) { 232 JVMFlagConstraintList::add(new JVMFlagConstraint_uint(name, ptr, func, type)); 233 } 234 void emit_constraint_uintx(const char* name, const uintx* ptr, JVMFlagConstraintFunc_uintx func, JVMFlagConstraint::ConstraintType type) { 235 JVMFlagConstraintList::add(new JVMFlagConstraint_uintx(name, ptr, func, type)); 236 } 237 void emit_constraint_uint64_t(const char* name, const uint64_t* ptr, JVMFlagConstraintFunc_uint64_t func, JVMFlagConstraint::ConstraintType type) { 238 JVMFlagConstraintList::add(new JVMFlagConstraint_uint64_t(name, ptr, func, type)); 239 } 240 void emit_constraint_size_t(const char* name, const size_t* ptr, JVMFlagConstraintFunc_size_t func, JVMFlagConstraint::ConstraintType type) { 241 JVMFlagConstraintList::add(new JVMFlagConstraint_size_t(name, ptr, func, type)); 242 } 243 void emit_constraint_double(const char* name, const double* ptr, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) { 244 JVMFlagConstraintList::add(new JVMFlagConstraint_double(name, ptr, func, type)); 245 } 246 247 // Generate code to call emit_constraint_xxx function 248 #define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 249 #define EMIT_CONSTRAINT_COMMERCIAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 250 #define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 251 #define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 252 #define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 253 #define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 254 #define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc) ); emit_constraint_##type(#name,&name 255 #define EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG(type, name, doc) ); emit_constraint_##type(#name,&name 256 #ifndef PRODUCT 257 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 258 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) ); emit_constraint_##type(#name,&name 259 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 260 #else 261 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) ); emit_constraint_no(#name,&name 262 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) ); emit_constraint_no(#name,&name 263 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_constraint_no(#name,&name 264 #endif 265 #ifdef _LP64 266 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name 267 #else 268 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_no(#name,&name 269 #endif 270 271 // Generate func argument to pass into emit_constraint_xxx functions 272 #define EMIT_CONSTRAINT_CHECK(func, type) , func, JVMFlagConstraint::type 273 274 // the "name" argument must be a string literal 275 #define INITIAL_CONSTRAINTS_SIZE 72 276 GrowableArray<JVMFlagConstraint*>* JVMFlagConstraintList::_constraints = NULL; 277 JVMFlagConstraint::ConstraintType JVMFlagConstraintList::_validating_type = JVMFlagConstraint::AtParse; 278 279 // Check the ranges of all flags that have them or print them out and exit if requested 280 void JVMFlagConstraintList::init(void) { 281 _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true); 282 283 emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 284 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 285 EMIT_CONSTRAINT_PRODUCT_FLAG, 286 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 287 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 288 EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG, 289 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 290 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 291 EMIT_CONSTRAINT_MANAGEABLE_FLAG, 292 EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 293 EMIT_CONSTRAINT_LP64_PRODUCT_FLAG, 294 IGNORE_RANGE, 295 EMIT_CONSTRAINT_CHECK, 296 IGNORE_WRITEABLE)); 297 298 EMIT_CONSTRAINTS_FOR_GLOBALS_EXT 299 300 emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 301 EMIT_CONSTRAINT_PRODUCT_FLAG, 302 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 303 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 304 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 305 IGNORE_RANGE, 306 EMIT_CONSTRAINT_CHECK, 307 IGNORE_WRITEABLE)); 308 309 310 #ifdef COMPILER1 311 emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 312 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 313 EMIT_CONSTRAINT_PRODUCT_FLAG, 314 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 315 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 316 EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG, 317 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 318 IGNORE_RANGE, 319 EMIT_CONSTRAINT_CHECK, 320 IGNORE_WRITEABLE)); 321 #endif // COMPILER1 322 323 #ifdef COMPILER2 324 emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 325 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 326 EMIT_CONSTRAINT_PRODUCT_FLAG, 327 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 328 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 329 EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG, 330 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 331 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 332 IGNORE_RANGE, 333 EMIT_CONSTRAINT_CHECK, 334 IGNORE_WRITEABLE)); 335 #endif // COMPILER2 336 337 #if INCLUDE_ALL_GCS 338 emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 339 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 340 EMIT_CONSTRAINT_PRODUCT_FLAG, 341 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 342 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 343 EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG, 344 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 345 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 346 EMIT_CONSTRAINT_MANAGEABLE_FLAG, 347 EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 348 IGNORE_RANGE, 349 EMIT_CONSTRAINT_CHECK, 350 IGNORE_WRITEABLE)); 351 #endif // INCLUDE_ALL_GCS 352 } 353 354 JVMFlagConstraint* JVMFlagConstraintList::find(const char* name) { 355 JVMFlagConstraint* found = NULL; 356 for (int i=0; i<length(); i++) { 357 JVMFlagConstraint* constraint = at(i); 358 if (strcmp(constraint->name(), name) == 0) { 359 found = constraint; 360 break; 361 } 362 } 363 return found; 364 } 365 366 // Find constraints by name and return only if found constraint's type is equal or lower than current validating type. 367 JVMFlagConstraint* JVMFlagConstraintList::find_if_needs_check(const char* name) { 368 JVMFlagConstraint* found = NULL; 369 JVMFlagConstraint* constraint = find(name); 370 if (constraint && (constraint->type() <= _validating_type)) { 371 found = constraint; 372 } 373 return found; 374 } 375 376 // Check constraints for specific constraint type. 377 bool JVMFlagConstraintList::check_constraints(JVMFlagConstraint::ConstraintType type) { 378 guarantee(type > _validating_type, "Constraint check is out of order."); 379 _validating_type = type; 380 381 bool status = true; 382 for (int i=0; i<length(); i++) { 383 JVMFlagConstraint* constraint = at(i); 384 if (type != constraint->type()) continue; 385 if (constraint->apply(true) != JVMFlag::SUCCESS) status = false; 386 } 387 return status; 388 }