commandLineFlagRangeList.cpp revision 9679:9689c3d3e2f8
1284990Scy/* 2284990Scy * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3284990Scy * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4284990Scy * 5284990Scy * This code is free software; you can redistribute it and/or modify it 6284990Scy * under the terms of the GNU General Public License version 2 only, as 7284990Scy * published by the Free Software Foundation. 8284990Scy * 9284990Scy * This code is distributed in the hope that it will be useful, but WITHOUT 10284990Scy * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11284990Scy * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12284990Scy * version 2 for more details (a copy is included in the LICENSE file that 13284990Scy * accompanied this code). 14284990Scy * 15284990Scy * You should have received a copy of the GNU General Public License version 16284990Scy * 2 along with this work; if not, write to the Free Software Foundation, 17284990Scy * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18284990Scy * 19284990Scy * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20284990Scy * or visit www.oracle.com if you need additional information or have any 21284990Scy * questions. 22284990Scy * 23284990Scy */ 24284990Scy 25284990Scy#include "precompiled.hpp" 26284990Scy#include "classfile/stringTable.hpp" 27284990Scy#include "classfile/symbolTable.hpp" 28284990Scy#include "gc/shared/referenceProcessor.hpp" 29284990Scy#include "runtime/arguments.hpp" 30284990Scy#include "runtime/commandLineFlagRangeList.hpp" 31284990Scy#include "runtime/os.hpp" 32284990Scy#include "runtime/task.hpp" 33284990Scy#include "utilities/defaultStream.hpp" 34284990Scy#include "utilities/macros.hpp" 35284990Scy 36284990Scyvoid CommandLineError::print(bool verbose, const char* msg, ...) { 37284990Scy if (verbose) { 38284990Scy va_list listPointer; 39284990Scy va_start(listPointer, msg); 40284990Scy jio_vfprintf(defaultStream::error_stream(), msg, listPointer); 41284990Scy va_end(listPointer); 42284990Scy } 43284990Scy} 44284990Scy 45284990Scyclass CommandLineFlagRange_int : public CommandLineFlagRange { 46284990Scy int _min; 47284990Scy int _max; 48284990Scy 49284990Scypublic: 50284990Scy // the "name" argument must be a string literal 51284990Scy CommandLineFlagRange_int(const char* name, int min, int max) : CommandLineFlagRange(name) { 52284990Scy _min=min, _max=max; 53284990Scy } 54284990Scy 55284990Scy Flag::Error check_int(int value, bool verbose = true) { 56284990Scy if ((value < _min) || (value > _max)) { 57284990Scy CommandLineError::print(verbose, 58284990Scy "int %s=%d is outside the allowed range " 59284990Scy "[ %d ... %d ]\n", 60284990Scy name(), value, _min, _max); 61284990Scy return Flag::OUT_OF_BOUNDS; 62284990Scy } else { 63284990Scy return Flag::SUCCESS; 64284990Scy } 65284990Scy } 66284990Scy 67284990Scy void print(outputStream* st) { 68284990Scy st->print("[ %-25d ... %25d ]", _min, _max); 69284990Scy } 70284990Scy}; 71284990Scy 72284990Scyclass CommandLineFlagRange_intx : public CommandLineFlagRange { 73284990Scy intx _min; 74284990Scy intx _max; 75284990Scy 76284990Scypublic: 77284990Scy // the "name" argument must be a string literal 78284990Scy CommandLineFlagRange_intx(const char* name, intx min, intx max) : CommandLineFlagRange(name) { 79284990Scy _min=min, _max=max; 80284990Scy } 81284990Scy 82284990Scy Flag::Error check_intx(intx value, bool verbose = true) { 83284990Scy if ((value < _min) || (value > _max)) { 84284990Scy CommandLineError::print(verbose, 85284990Scy "intx %s=" INTX_FORMAT " is outside the allowed range " 86284990Scy "[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n", 87284990Scy name(), value, _min, _max); 88284990Scy return Flag::OUT_OF_BOUNDS; 89284990Scy } else { 90284990Scy return Flag::SUCCESS; 91284990Scy } 92284990Scy } 93284990Scy 94284990Scy void print(outputStream* st) { 95284990Scy st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max); 96284990Scy } 97284990Scy}; 98284990Scy 99284990Scyclass CommandLineFlagRange_uint : public CommandLineFlagRange { 100284990Scy uint _min; 101284990Scy uint _max; 102284990Scy 103284990Scypublic: 104284990Scy // the "name" argument must be a string literal 105284990Scy CommandLineFlagRange_uint(const char* name, uint min, uint max) : CommandLineFlagRange(name) { 106284990Scy _min=min, _max=max; 107284990Scy } 108284990Scy 109284990Scy Flag::Error check_uint(uint value, bool verbose = true) { 110284990Scy if ((value < _min) || (value > _max)) { 111284990Scy CommandLineError::print(verbose, 112284990Scy "uint %s=%u is outside the allowed range " 113284990Scy "[ %u ... %u ]\n", 114284990Scy name(), value, _min, _max); 115284990Scy return Flag::OUT_OF_BOUNDS; 116284990Scy } else { 117284990Scy return Flag::SUCCESS; 118284990Scy } 119284990Scy } 120284990Scy 121284990Scy void print(outputStream* st) { 122284990Scy st->print("[ %-25u ... %25u ]", _min, _max); 123284990Scy } 124284990Scy}; 125284990Scy 126284990Scyclass CommandLineFlagRange_uintx : public CommandLineFlagRange { 127284990Scy uintx _min; 128284990Scy uintx _max; 129284990Scy 130284990Scypublic: 131284990Scy // the "name" argument must be a string literal 132284990Scy CommandLineFlagRange_uintx(const char* name, uintx min, uintx max) : CommandLineFlagRange(name) { 133284990Scy _min=min, _max=max; 134284990Scy } 135284990Scy 136284990Scy Flag::Error check_uintx(uintx value, bool verbose = true) { 137284990Scy if ((value < _min) || (value > _max)) { 138284990Scy CommandLineError::print(verbose, 139284990Scy "uintx %s=" UINTX_FORMAT " is outside the allowed range " 140284990Scy "[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n", 141284990Scy name(), value, _min, _max); 142284990Scy return Flag::OUT_OF_BOUNDS; 143284990Scy } else { 144284990Scy return Flag::SUCCESS; 145284990Scy } 146284990Scy } 147284990Scy 148284990Scy void print(outputStream* st) { 149284990Scy st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max); 150284990Scy } 151284990Scy}; 152284990Scy 153284990Scyclass CommandLineFlagRange_uint64_t : public CommandLineFlagRange { 154284990Scy uint64_t _min; 155284990Scy uint64_t _max; 156284990Scy 157284990Scypublic: 158284990Scy // the "name" argument must be a string literal 159284990Scy CommandLineFlagRange_uint64_t(const char* name, uint64_t min, uint64_t max) : CommandLineFlagRange(name) { 160284990Scy _min=min, _max=max; 161284990Scy } 162284990Scy 163284990Scy Flag::Error check_uint64_t(uint64_t value, bool verbose = true) { 164284990Scy if ((value < _min) || (value > _max)) { 165284990Scy CommandLineError::print(verbose, 166284990Scy "uint64_t %s=" UINT64_FORMAT " is outside the allowed range " 167284990Scy "[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n", 168284990Scy name(), value, _min, _max); 169284990Scy return Flag::OUT_OF_BOUNDS; 170284990Scy } else { 171284990Scy return Flag::SUCCESS; 172284990Scy } 173284990Scy } 174284990Scy 175284990Scy void print(outputStream* st) { 176284990Scy st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max); 177284990Scy } 178284990Scy}; 179284990Scy 180284990Scyclass CommandLineFlagRange_size_t : public CommandLineFlagRange { 181284990Scy size_t _min; 182284990Scy size_t _max; 183284990Scy 184284990Scypublic: 185284990Scy // the "name" argument must be a string literal 186284990Scy CommandLineFlagRange_size_t(const char* name, size_t min, size_t max) : CommandLineFlagRange(name) { 187284990Scy _min=min, _max=max; 188284990Scy } 189284990Scy 190284990Scy Flag::Error check_size_t(size_t value, bool verbose = true) { 191284990Scy if ((value < _min) || (value > _max)) { 192284990Scy CommandLineError::print(verbose, 193284990Scy "size_t %s=" SIZE_FORMAT " is outside the allowed range " 194284990Scy "[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n", 195284990Scy name(), value, _min, _max); 196284990Scy return Flag::OUT_OF_BOUNDS; 197284990Scy } else { 198284990Scy return Flag::SUCCESS; 199284990Scy } 200284990Scy } 201284990Scy 202284990Scy void print(outputStream* st) { 203284990Scy st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max); 204284990Scy } 205284990Scy}; 206284990Scy 207284990Scyclass CommandLineFlagRange_double : public CommandLineFlagRange { 208284990Scy double _min; 209284990Scy double _max; 210284990Scy 211284990Scypublic: 212284990Scy // the "name" argument must be a string literal 213284990Scy CommandLineFlagRange_double(const char* name, double min, double max) : CommandLineFlagRange(name) { 214284990Scy _min=min, _max=max; 215284990Scy } 216284990Scy 217284990Scy Flag::Error check_double(double value, bool verbose = true) { 218284990Scy if ((value < _min) || (value > _max)) { 219284990Scy CommandLineError::print(verbose, 220 "double %s=%f is outside the allowed range " 221 "[ %f ... %f ]\n", 222 name(), value, _min, _max); 223 return Flag::OUT_OF_BOUNDS; 224 } else { 225 return Flag::SUCCESS; 226 } 227 } 228 229 void print(outputStream* st) { 230 st->print("[ %-25.3f ... %25.3f ]", _min, _max); 231 } 232}; 233 234// No constraint emitting 235void emit_range_no(...) { /* NOP */ } 236 237// No constraint emitting if function argument is NOT provided 238void emit_range_bool(const char* /*name*/) { /* NOP */ } 239void emit_range_ccstr(const char* /*name*/) { /* NOP */ } 240void emit_range_ccstrlist(const char* /*name*/) { /* NOP */ } 241void emit_range_int(const char* /*name*/) { /* NOP */ } 242void emit_range_intx(const char* /*name*/) { /* NOP */ } 243void emit_range_uint(const char* /*name*/) { /* NOP */ } 244void emit_range_uintx(const char* /*name*/) { /* NOP */ } 245void emit_range_uint64_t(const char* /*name*/) { /* NOP */ } 246void emit_range_size_t(const char* /*name*/) { /* NOP */ } 247void emit_range_double(const char* /*name*/) { /* NOP */ } 248 249// CommandLineFlagRange emitting code functions if range arguments are provided 250void emit_range_intx(const char* name, intx min, intx max) { 251 CommandLineFlagRangeList::add(new CommandLineFlagRange_intx(name, min, max)); 252} 253void emit_range_uint(const char* name, uint min, uint max) { 254 CommandLineFlagRangeList::add(new CommandLineFlagRange_uint(name, min, max)); 255} 256void emit_range_uintx(const char* name, uintx min, uintx max) { 257 CommandLineFlagRangeList::add(new CommandLineFlagRange_uintx(name, min, max)); 258} 259void emit_range_uint64_t(const char* name, uint64_t min, uint64_t max) { 260 CommandLineFlagRangeList::add(new CommandLineFlagRange_uint64_t(name, min, max)); 261} 262void emit_range_size_t(const char* name, size_t min, size_t max) { 263 CommandLineFlagRangeList::add(new CommandLineFlagRange_size_t(name, min, max)); 264} 265void emit_range_double(const char* name, double min, double max) { 266 CommandLineFlagRangeList::add(new CommandLineFlagRange_double(name, min, max)); 267} 268 269// Generate code to call emit_range_xxx function 270#define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name 271#define EMIT_RANGE_COMMERCIAL_FLAG(type, name, value, doc) ); emit_range_##type(#name 272#define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc) ); emit_range_##type(#name 273#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name 274#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc) ); emit_range_##type(#name 275#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc) ); emit_range_##type(#name 276#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc) ); emit_range_##type(#name 277#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc) ); emit_range_##type(#name 278#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc) ); emit_range_##type(#name 279#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name 280#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name 281 282// Generate func argument to pass into emit_range_xxx functions 283#define EMIT_RANGE_CHECK(a, b) , a, b 284 285#define INITIAL_RANGES_SIZE 379 286GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL; 287 288// Check the ranges of all flags that have them 289void CommandLineFlagRangeList::init(void) { 290 291 _ranges = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true); 292 293 emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 294 EMIT_RANGE_PD_DEVELOPER_FLAG, 295 EMIT_RANGE_PRODUCT_FLAG, 296 EMIT_RANGE_PD_PRODUCT_FLAG, 297 EMIT_RANGE_DIAGNOSTIC_FLAG, 298 EMIT_RANGE_EXPERIMENTAL_FLAG, 299 EMIT_RANGE_NOTPRODUCT_FLAG, 300 EMIT_RANGE_MANAGEABLE_FLAG, 301 EMIT_RANGE_PRODUCT_RW_FLAG, 302 EMIT_RANGE_LP64_PRODUCT_FLAG, 303 EMIT_RANGE_CHECK, 304 IGNORE_CONSTRAINT) ); 305 306 EMIT_RANGES_FOR_GLOBALS_EXT 307 308 emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 309 EMIT_RANGE_PRODUCT_FLAG, 310 EMIT_RANGE_DIAGNOSTIC_FLAG, 311 EMIT_RANGE_EXPERIMENTAL_FLAG, 312 EMIT_RANGE_NOTPRODUCT_FLAG, 313 EMIT_RANGE_CHECK, 314 IGNORE_CONSTRAINT)); 315 316#if INCLUDE_JVMCI 317 emit_range_no(NULL JVMCI_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 318 EMIT_RANGE_PD_DEVELOPER_FLAG, 319 EMIT_RANGE_PRODUCT_FLAG, 320 EMIT_RANGE_PD_PRODUCT_FLAG, 321 EMIT_RANGE_DIAGNOSTIC_FLAG, 322 EMIT_RANGE_EXPERIMENTAL_FLAG, 323 EMIT_RANGE_NOTPRODUCT_FLAG, 324 EMIT_RANGE_CHECK, 325 IGNORE_CONSTRAINT)); 326#endif // INCLUDE_JVMCI 327 328#ifdef COMPILER1 329 emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 330 EMIT_RANGE_PD_DEVELOPER_FLAG, 331 EMIT_RANGE_PRODUCT_FLAG, 332 EMIT_RANGE_PD_PRODUCT_FLAG, 333 EMIT_RANGE_DIAGNOSTIC_FLAG, 334 EMIT_RANGE_NOTPRODUCT_FLAG, 335 EMIT_RANGE_CHECK, 336 IGNORE_CONSTRAINT)); 337#endif // COMPILER1 338 339#ifdef COMPILER2 340 emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 341 EMIT_RANGE_PD_DEVELOPER_FLAG, 342 EMIT_RANGE_PRODUCT_FLAG, 343 EMIT_RANGE_PD_PRODUCT_FLAG, 344 EMIT_RANGE_DIAGNOSTIC_FLAG, 345 EMIT_RANGE_EXPERIMENTAL_FLAG, 346 EMIT_RANGE_NOTPRODUCT_FLAG, 347 EMIT_RANGE_CHECK, 348 IGNORE_CONSTRAINT)); 349#endif // COMPILER2 350 351#if INCLUDE_ALL_GCS 352 emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 353 EMIT_RANGE_PD_DEVELOPER_FLAG, 354 EMIT_RANGE_PRODUCT_FLAG, 355 EMIT_RANGE_PD_PRODUCT_FLAG, 356 EMIT_RANGE_DIAGNOSTIC_FLAG, 357 EMIT_RANGE_EXPERIMENTAL_FLAG, 358 EMIT_RANGE_NOTPRODUCT_FLAG, 359 EMIT_RANGE_MANAGEABLE_FLAG, 360 EMIT_RANGE_PRODUCT_RW_FLAG, 361 EMIT_RANGE_CHECK, 362 IGNORE_CONSTRAINT)); 363#endif // INCLUDE_ALL_GCS 364} 365 366CommandLineFlagRange* CommandLineFlagRangeList::find(const char* name) { 367 CommandLineFlagRange* found = NULL; 368 for (int i=0; i<length(); i++) { 369 CommandLineFlagRange* range = at(i); 370 if (strcmp(range->name(), name) == 0) { 371 found = range; 372 break; 373 } 374 } 375 return found; 376} 377 378void CommandLineFlagRangeList::print(const char* name, outputStream* st, bool unspecified) { 379 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 380 if (range != NULL) { 381 range->print(st); 382 } else if (unspecified == true) { 383 st->print("[ ... ]"); 384 } 385} 386 387bool CommandLineFlagRangeList::check_ranges() { 388 // Check ranges. 389 bool status = true; 390 for (int i=0; i<length(); i++) { 391 CommandLineFlagRange* range = at(i); 392 const char* name = range->name(); 393 Flag* flag = Flag::find_flag(name, strlen(name), true, true); 394 // We must check for NULL here as lp64_product flags on 32 bit architecture 395 // can generate range check (despite that they are declared as constants), 396 // but they will not be returned by Flag::find_flag() 397 if (flag != NULL) { 398 if (flag->is_int()) { 399 int value = flag->get_int(); 400 if (range->check_int(value, true) != Flag::SUCCESS) status = false; 401 } else if (flag->is_uint()) { 402 uint value = flag->get_uint(); 403 if (range->check_uint(value, true) != Flag::SUCCESS) status = false; 404 } else if (flag->is_intx()) { 405 intx value = flag->get_intx(); 406 if (range->check_intx(value, true) != Flag::SUCCESS) status = false; 407 } else if (flag->is_uintx()) { 408 uintx value = flag->get_uintx(); 409 if (range->check_uintx(value, true) != Flag::SUCCESS) status = false; 410 } else if (flag->is_uint64_t()) { 411 uint64_t value = flag->get_uint64_t(); 412 if (range->check_uint64_t(value, true) != Flag::SUCCESS) status = false; 413 } else if (flag->is_size_t()) { 414 size_t value = flag->get_size_t(); 415 if (range->check_size_t(value, true) != Flag::SUCCESS) status = false; 416 } else if (flag->is_double()) { 417 double value = flag->get_double(); 418 if (range->check_double(value, true) != Flag::SUCCESS) status = false; 419 } 420 } 421 } 422 return status; 423} 424