commandLineFlagConstraintList.cpp revision 9149:a8a8604f890f
1220496Smarkm/* 2220496Smarkm * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3220496Smarkm * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4220496Smarkm * 5220496Smarkm * This code is free software; you can redistribute it and/or modify it 6220496Smarkm * under the terms of the GNU General Public License version 2 only, as 7220496Smarkm * published by the Free Software Foundation. 8220496Smarkm * 9220496Smarkm * This code is distributed in the hope that it will be useful, but WITHOUT 10220496Smarkm * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11220496Smarkm * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12220496Smarkm * version 2 for more details (a copy is included in the LICENSE file that 13220496Smarkm * accompanied this code). 14220496Smarkm * 15220496Smarkm * You should have received a copy of the GNU General Public License version 16220496Smarkm * 2 along with this work; if not, write to the Free Software Foundation, 17220496Smarkm * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18220496Smarkm * 19220496Smarkm * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20220496Smarkm * or visit www.oracle.com if you need additional information or have any 21220496Smarkm * questions. 22220496Smarkm * 23220496Smarkm */ 24220496Smarkm 25220496Smarkm#include "precompiled.hpp" 26220496Smarkm#include "classfile/stringTable.hpp" 27220496Smarkm#include "classfile/symbolTable.hpp" 28220496Smarkm#include "gc/shared/referenceProcessor.hpp" 29220496Smarkm#include "runtime/arguments.hpp" 30220496Smarkm#include "runtime/commandLineFlagConstraintList.hpp" 31220496Smarkm#include "runtime/commandLineFlagConstraintsCompiler.hpp" 32220496Smarkm#include "runtime/commandLineFlagConstraintsGC.hpp" 33220496Smarkm#include "runtime/commandLineFlagConstraintsRuntime.hpp" 34220496Smarkm#include "runtime/os.hpp" 35220496Smarkm#include "utilities/macros.hpp" 36220496Smarkm#if INCLUDE_JVMCI 37220496Smarkm#include "jvmci/commandLineFlagConstraintsJVMCI.hpp" 38220496Smarkm#endif 39220496Smarkm 40220496Smarkmclass CommandLineFlagConstraint_bool : public CommandLineFlagConstraint { 41220496Smarkm CommandLineFlagConstraintFunc_bool _constraint; 42220496Smarkm 43220496Smarkmpublic: 44220496Smarkm // the "name" argument must be a string literal 45220496Smarkm CommandLineFlagConstraint_bool(const char* name, 46220496Smarkm CommandLineFlagConstraintFunc_bool func, 47220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 48220496Smarkm _constraint=func; 49220496Smarkm } 50220496Smarkm 51220496Smarkm Flag::Error apply_bool(bool value, bool verbose) { 52220496Smarkm return _constraint(value, verbose); 53220496Smarkm } 54220496Smarkm}; 55220496Smarkm 56220496Smarkmclass CommandLineFlagConstraint_int : public CommandLineFlagConstraint { 57220496Smarkm CommandLineFlagConstraintFunc_int _constraint; 58220496Smarkm 59220496Smarkmpublic: 60220496Smarkm // the "name" argument must be a string literal 61220496Smarkm CommandLineFlagConstraint_int(const char* name, 62220496Smarkm CommandLineFlagConstraintFunc_int func, 63220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 64220496Smarkm _constraint=func; 65220496Smarkm } 66220496Smarkm 67220496Smarkm Flag::Error apply_int(int value, bool verbose) { 68220496Smarkm return _constraint(value, verbose); 69220496Smarkm } 70220496Smarkm}; 71220496Smarkm 72220496Smarkmclass CommandLineFlagConstraint_intx : public CommandLineFlagConstraint { 73220496Smarkm CommandLineFlagConstraintFunc_intx _constraint; 74220496Smarkm 75220496Smarkmpublic: 76220496Smarkm // the "name" argument must be a string literal 77220496Smarkm CommandLineFlagConstraint_intx(const char* name, 78220496Smarkm CommandLineFlagConstraintFunc_intx func, 79220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 80220496Smarkm _constraint=func; 81220496Smarkm } 82220496Smarkm 83220496Smarkm Flag::Error apply_intx(intx value, bool verbose) { 84220496Smarkm return _constraint(value, verbose); 85220496Smarkm } 86220496Smarkm}; 87220496Smarkm 88220496Smarkmclass CommandLineFlagConstraint_uint : public CommandLineFlagConstraint { 89220496Smarkm CommandLineFlagConstraintFunc_uint _constraint; 90220496Smarkm 91220496Smarkmpublic: 92220496Smarkm // the "name" argument must be a string literal 93220496Smarkm CommandLineFlagConstraint_uint(const char* name, 94220496Smarkm CommandLineFlagConstraintFunc_uint func, 95220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 96220496Smarkm _constraint=func; 97220496Smarkm } 98220496Smarkm 99220496Smarkm Flag::Error apply_uint(uint value, bool verbose) { 100220496Smarkm return _constraint(value, verbose); 101220496Smarkm } 102220496Smarkm}; 103220496Smarkm 104220496Smarkmclass CommandLineFlagConstraint_uintx : public CommandLineFlagConstraint { 105220496Smarkm CommandLineFlagConstraintFunc_uintx _constraint; 106220496Smarkm 107220496Smarkmpublic: 108220496Smarkm // the "name" argument must be a string literal 109220496Smarkm CommandLineFlagConstraint_uintx(const char* name, 110220496Smarkm CommandLineFlagConstraintFunc_uintx func, 111220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 112220496Smarkm _constraint=func; 113220496Smarkm } 114220496Smarkm 115220496Smarkm Flag::Error apply_uintx(uintx value, bool verbose) { 116220496Smarkm return _constraint(value, verbose); 117220496Smarkm } 118220496Smarkm}; 119220496Smarkm 120220496Smarkmclass CommandLineFlagConstraint_uint64_t : public CommandLineFlagConstraint { 121220496Smarkm CommandLineFlagConstraintFunc_uint64_t _constraint; 122220496Smarkm 123220496Smarkmpublic: 124220496Smarkm // the "name" argument must be a string literal 125220496Smarkm CommandLineFlagConstraint_uint64_t(const char* name, 126220496Smarkm CommandLineFlagConstraintFunc_uint64_t func, 127220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 128220496Smarkm _constraint=func; 129220496Smarkm } 130220496Smarkm 131220496Smarkm Flag::Error apply_uint64_t(uint64_t value, bool verbose) { 132220496Smarkm return _constraint(value, verbose); 133220496Smarkm } 134220496Smarkm}; 135220496Smarkm 136220496Smarkmclass CommandLineFlagConstraint_size_t : public CommandLineFlagConstraint { 137220496Smarkm CommandLineFlagConstraintFunc_size_t _constraint; 138220496Smarkm 139220496Smarkmpublic: 140220496Smarkm // the "name" argument must be a string literal 141220496Smarkm CommandLineFlagConstraint_size_t(const char* name, 142220496Smarkm CommandLineFlagConstraintFunc_size_t func, 143220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 144220496Smarkm _constraint=func; 145220496Smarkm } 146220496Smarkm 147220496Smarkm Flag::Error apply_size_t(size_t value, bool verbose) { 148220496Smarkm return _constraint(value, verbose); 149220496Smarkm } 150220496Smarkm}; 151220496Smarkm 152220496Smarkmclass CommandLineFlagConstraint_double : public CommandLineFlagConstraint { 153220496Smarkm CommandLineFlagConstraintFunc_double _constraint; 154220496Smarkm 155220496Smarkmpublic: 156220496Smarkm // the "name" argument must be a string literal 157220496Smarkm CommandLineFlagConstraint_double(const char* name, 158220496Smarkm CommandLineFlagConstraintFunc_double func, 159220496Smarkm ConstraintType type) : CommandLineFlagConstraint(name, type) { 160220496Smarkm _constraint=func; 161220496Smarkm } 162220496Smarkm 163220496Smarkm Flag::Error apply_double(double value, bool verbose) { 164220496Smarkm return _constraint(value, verbose); 165220496Smarkm } 166220496Smarkm}; 167220496Smarkm 168220496Smarkm// No constraint emitting 169220496Smarkmvoid emit_constraint_no(...) { /* NOP */ } 170220496Smarkm 171220496Smarkm// No constraint emitting if function argument is NOT provided 172220496Smarkmvoid emit_constraint_bool(const char* /*name*/) { /* NOP */ } 173220496Smarkmvoid emit_constraint_ccstr(const char* /*name*/) { /* NOP */ } 174220496Smarkmvoid emit_constraint_ccstrlist(const char* /*name*/) { /* NOP */ } 175220496Smarkmvoid emit_constraint_int(const char* /*name*/) { /* NOP */ } 176220496Smarkmvoid emit_constraint_intx(const char* /*name*/) { /* NOP */ } 177220496Smarkmvoid emit_constraint_uint(const char* /*name*/) { /* NOP */ } 178220496Smarkmvoid emit_constraint_uintx(const char* /*name*/) { /* NOP */ } 179220496Smarkmvoid emit_constraint_uint64_t(const char* /*name*/) { /* NOP */ } 180220496Smarkmvoid emit_constraint_size_t(const char* /*name*/) { /* NOP */ } 181220496Smarkmvoid emit_constraint_double(const char* /*name*/) { /* NOP */ } 182220496Smarkm 183220496Smarkm// CommandLineFlagConstraint emitting code functions if function argument is provided 184220496Smarkmvoid emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func, CommandLineFlagConstraint::ConstraintType type) { 185220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func, type)); 186220496Smarkm} 187220496Smarkmvoid emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func, CommandLineFlagConstraint::ConstraintType type) { 188220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func, type)); 189220496Smarkm} 190220496Smarkmvoid emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func, CommandLineFlagConstraint::ConstraintType type) { 191220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func, type)); 192220496Smarkm} 193220496Smarkmvoid emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func, CommandLineFlagConstraint::ConstraintType type) { 194220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func, type)); 195220496Smarkm} 196220496Smarkmvoid emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func, CommandLineFlagConstraint::ConstraintType type) { 197220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func, type)); 198220496Smarkm} 199220496Smarkmvoid emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func, CommandLineFlagConstraint::ConstraintType type) { 200220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func, type)); 201220496Smarkm} 202220496Smarkmvoid emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func, CommandLineFlagConstraint::ConstraintType type) { 203220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func, type)); 204220496Smarkm} 205220496Smarkmvoid emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func, CommandLineFlagConstraint::ConstraintType type) { 206220496Smarkm CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func, type)); 207220496Smarkm} 208220496Smarkm 209220496Smarkm// Generate code to call emit_constraint_xxx function 210220496Smarkm#define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 211220496Smarkm#define EMIT_CONSTRAINT_COMMERCIAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 212220496Smarkm#define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 213220496Smarkm#define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 214220496Smarkm#define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 215220496Smarkm#define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 216220496Smarkm#define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc) ); emit_constraint_##type(#name 217220496Smarkm#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 218220496Smarkm#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) ); emit_constraint_##type(#name 219220496Smarkm#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 220220496Smarkm#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 221220496Smarkm 222220496Smarkm// Generate func argument to pass into emit_constraint_xxx functions 223220496Smarkm#define EMIT_CONSTRAINT_CHECK(func, type) , func, CommandLineFlagConstraint::type 224220496Smarkm 225220496Smarkm// the "name" argument must be a string literal 226220496Smarkm#define INITIAL_CONSTRAINTS_SIZE 40 227220496SmarkmGrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL; 228220496SmarkmCommandLineFlagConstraint::ConstraintType CommandLineFlagConstraintList::_validating_type = CommandLineFlagConstraint::AtParse; 229220496Smarkm 230220496Smarkm// Check the ranges of all flags that have them or print them out and exit if requested 231220496Smarkmvoid CommandLineFlagConstraintList::init(void) { 232220496Smarkm _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true); 233220496Smarkm 234220496Smarkm emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 235220496Smarkm EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 236220496Smarkm EMIT_CONSTRAINT_PRODUCT_FLAG, 237220496Smarkm EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 238220496Smarkm EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 239220496Smarkm EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 240220496Smarkm EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 241220496Smarkm EMIT_CONSTRAINT_MANAGEABLE_FLAG, 242220496Smarkm EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 243220496Smarkm EMIT_CONSTRAINT_LP64_PRODUCT_FLAG, 244220496Smarkm IGNORE_RANGE, 245220496Smarkm EMIT_CONSTRAINT_CHECK)); 246220496Smarkm 247220496Smarkm EMIT_CONSTRAINTS_FOR_GLOBALS_EXT 248220496Smarkm 249220496Smarkm emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 250220496Smarkm EMIT_CONSTRAINT_PRODUCT_FLAG, 251220496Smarkm EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 252220496Smarkm EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 253220496Smarkm EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 254220496Smarkm IGNORE_RANGE, 255220496Smarkm EMIT_CONSTRAINT_CHECK)); 256220496Smarkm 257220496Smarkm#if INCLUDE_JVMCI 258220496Smarkm emit_constraint_no(NULL JVMCI_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 259220496Smarkm EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 260220496Smarkm EMIT_CONSTRAINT_PRODUCT_FLAG, 261220496Smarkm EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 262220496Smarkm EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 263220496Smarkm EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 264220496Smarkm EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 265220496Smarkm IGNORE_RANGE, 266220496Smarkm EMIT_CONSTRAINT_CHECK)); 267220496Smarkm#endif // INCLUDE_JVMCI 268220496Smarkm 269220496Smarkm#ifdef COMPILER1 270220496Smarkm emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 271220496Smarkm EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 272220496Smarkm EMIT_CONSTRAINT_PRODUCT_FLAG, 273220496Smarkm EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 274220496Smarkm EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 275220496Smarkm EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 276220496Smarkm IGNORE_RANGE, 277220496Smarkm EMIT_CONSTRAINT_CHECK)); 278220496Smarkm#endif // COMPILER1 279220496Smarkm 280220496Smarkm#ifdef COMPILER2 281220496Smarkm emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 282220496Smarkm EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 283220496Smarkm EMIT_CONSTRAINT_PRODUCT_FLAG, 284220496Smarkm EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 285220496Smarkm EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 286220496Smarkm EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 287220496Smarkm EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 288220496Smarkm IGNORE_RANGE, 289220496Smarkm EMIT_CONSTRAINT_CHECK)); 290220496Smarkm#endif // COMPILER2 291220496Smarkm 292220496Smarkm#if INCLUDE_ALL_GCS 293220496Smarkm emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 294220496Smarkm EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 295220496Smarkm EMIT_CONSTRAINT_PRODUCT_FLAG, 296220496Smarkm EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 297220496Smarkm EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 298220496Smarkm EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 299220496Smarkm EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 300220496Smarkm EMIT_CONSTRAINT_MANAGEABLE_FLAG, 301220496Smarkm EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 302220496Smarkm IGNORE_RANGE, 303220496Smarkm EMIT_CONSTRAINT_CHECK)); 304220496Smarkm#endif // INCLUDE_ALL_GCS 305220496Smarkm} 306220496Smarkm 307220496Smarkm// Find constraints by name and return only if found constraint's type is equal or lower than current validating type. 308220496SmarkmCommandLineFlagConstraint* CommandLineFlagConstraintList::find_if_needs_check(const char* name) { 309220496Smarkm CommandLineFlagConstraint* found = NULL; 310220496Smarkm for (int i=0; i<length(); i++) { 311220496Smarkm CommandLineFlagConstraint* constraint = at(i); 312220496Smarkm if ((strcmp(constraint->name(), name) == 0) && 313220496Smarkm (constraint->type() <= _validating_type)) { 314220496Smarkm found = constraint; 315220496Smarkm break; 316220496Smarkm } 317220496Smarkm } 318220496Smarkm return found; 319220496Smarkm} 320220496Smarkm 321// Check constraints for specific constraint type. 322bool CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::ConstraintType type) { 323 guarantee(type > _validating_type, "Constraint check is out of order."); 324 _validating_type = type; 325 326 bool status = true; 327 for (int i=0; i<length(); i++) { 328 CommandLineFlagConstraint* constraint = at(i); 329 if (type != constraint->type()) continue; 330 const char* name = constraint->name(); 331 Flag* flag = Flag::find_flag(name, strlen(name), true, true); 332 // We must check for NULL here as lp64_product flags on 32 bit architecture 333 // can generate constraint check (despite that they are declared as constants), 334 // but they will not be returned by Flag::find_flag() 335 if (flag != NULL) { 336 if (flag->is_bool()) { 337 bool value = flag->get_bool(); 338 if (constraint->apply_bool(value, true) != Flag::SUCCESS) status = false; 339 } else if (flag->is_int()) { 340 int value = flag->get_int(); 341 if (constraint->apply_int(value, true) != Flag::SUCCESS) status = false; 342 } else if (flag->is_uint()) { 343 uint value = flag->get_uint(); 344 if (constraint->apply_uint(value, true) != Flag::SUCCESS) status = false; 345 } else if (flag->is_intx()) { 346 intx value = flag->get_intx(); 347 if (constraint->apply_intx(value, true) != Flag::SUCCESS) status = false; 348 } else if (flag->is_uintx()) { 349 uintx value = flag->get_uintx(); 350 if (constraint->apply_uintx(value, true) != Flag::SUCCESS) status = false; 351 } else if (flag->is_uint64_t()) { 352 uint64_t value = flag->get_uint64_t(); 353 if (constraint->apply_uint64_t(value, true) != Flag::SUCCESS) status = false; 354 } else if (flag->is_size_t()) { 355 size_t value = flag->get_size_t(); 356 if (constraint->apply_size_t(value, true) != Flag::SUCCESS) status = false; 357 } else if (flag->is_double()) { 358 double value = flag->get_double(); 359 if (constraint->apply_double(value, true) != Flag::SUCCESS) status = false; 360 } 361 } 362 } 363 return status; 364} 365