1 /* 2 * Copyright (c) 2015, 2016, 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/commandLineFlagConstraintList.hpp" 31 #include "runtime/commandLineFlagRangeList.hpp" 32 #include "runtime/os.hpp" 33 #include "runtime/task.hpp" 34 #include "utilities/defaultStream.hpp" 35 #include "utilities/macros.hpp" 36 37 void CommandLineError::print(bool verbose, const char* msg, ...) { 38 if (verbose) { 39 va_list listPointer; 40 va_start(listPointer, msg); 41 jio_vfprintf(defaultStream::error_stream(), msg, listPointer); 42 va_end(listPointer); 43 } 44 } 45 46 class CommandLineFlagRange_int : public CommandLineFlagRange { 47 int _min; 48 int _max; 49 const int* _ptr; 50 51 public: 52 // the "name" argument must be a string literal 53 CommandLineFlagRange_int(const char* name, const int* ptr, int min, int max) 54 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 55 56 Flag::Error check(bool verbose = true) { 57 return check_int(*_ptr, verbose); 58 } 59 60 Flag::Error check_int(int value, bool verbose = true) { 61 if ((value < _min) || (value > _max)) { 62 CommandLineError::print(verbose, 63 "int %s=%d is outside the allowed range " 64 "[ %d ... %d ]\n", 65 name(), value, _min, _max); 66 return Flag::OUT_OF_BOUNDS; 67 } else { 68 return Flag::SUCCESS; 69 } 70 } 71 72 void print(outputStream* st) { 73 st->print("[ %-25d ... %25d ]", _min, _max); 74 } 75 }; 76 77 class CommandLineFlagRange_intx : public CommandLineFlagRange { 78 intx _min; 79 intx _max; 80 const intx* _ptr; 81 public: 82 // the "name" argument must be a string literal 83 CommandLineFlagRange_intx(const char* name, const intx* ptr, intx min, intx max) 84 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 85 86 Flag::Error check(bool verbose = true) { 87 return check_intx(*_ptr, verbose); 88 } 89 90 Flag::Error check_intx(intx value, bool verbose = true) { 91 if ((value < _min) || (value > _max)) { 92 CommandLineError::print(verbose, 93 "intx %s=" INTX_FORMAT " is outside the allowed range " 94 "[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n", 95 name(), value, _min, _max); 96 return Flag::OUT_OF_BOUNDS; 97 } else { 98 return Flag::SUCCESS; 99 } 100 } 101 102 void print(outputStream* st) { 103 st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max); 104 } 105 }; 106 107 class CommandLineFlagRange_uint : public CommandLineFlagRange { 108 uint _min; 109 uint _max; 110 const uint* _ptr; 111 112 public: 113 // the "name" argument must be a string literal 114 CommandLineFlagRange_uint(const char* name, const uint* ptr, uint min, uint max) 115 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 116 117 Flag::Error check(bool verbose = true) { 118 return check_uint(*_ptr, verbose); 119 } 120 121 Flag::Error check_uint(uint value, bool verbose = true) { 122 if ((value < _min) || (value > _max)) { 123 CommandLineError::print(verbose, 124 "uint %s=%u is outside the allowed range " 125 "[ %u ... %u ]\n", 126 name(), value, _min, _max); 127 return Flag::OUT_OF_BOUNDS; 128 } else { 129 return Flag::SUCCESS; 130 } 131 } 132 133 void print(outputStream* st) { 134 st->print("[ %-25u ... %25u ]", _min, _max); 135 } 136 }; 137 138 class CommandLineFlagRange_uintx : public CommandLineFlagRange { 139 uintx _min; 140 uintx _max; 141 const uintx* _ptr; 142 143 public: 144 // the "name" argument must be a string literal 145 CommandLineFlagRange_uintx(const char* name, const uintx* ptr, uintx min, uintx max) 146 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 147 148 Flag::Error check(bool verbose = true) { 149 return check_uintx(*_ptr, verbose); 150 } 151 152 Flag::Error check_uintx(uintx value, bool verbose = true) { 153 if ((value < _min) || (value > _max)) { 154 CommandLineError::print(verbose, 155 "uintx %s=" UINTX_FORMAT " is outside the allowed range " 156 "[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n", 157 name(), value, _min, _max); 158 return Flag::OUT_OF_BOUNDS; 159 } else { 160 return Flag::SUCCESS; 161 } 162 } 163 164 void print(outputStream* st) { 165 st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max); 166 } 167 }; 168 169 class CommandLineFlagRange_uint64_t : public CommandLineFlagRange { 170 uint64_t _min; 171 uint64_t _max; 172 const uint64_t* _ptr; 173 174 public: 175 // the "name" argument must be a string literal 176 CommandLineFlagRange_uint64_t(const char* name, const uint64_t* ptr, uint64_t min, uint64_t max) 177 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 178 179 Flag::Error check(bool verbose = true) { 180 return check_uint64_t(*_ptr, verbose); 181 } 182 183 Flag::Error check_uint64_t(uint64_t value, bool verbose = true) { 184 if ((value < _min) || (value > _max)) { 185 CommandLineError::print(verbose, 186 "uint64_t %s=" UINT64_FORMAT " is outside the allowed range " 187 "[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n", 188 name(), value, _min, _max); 189 return Flag::OUT_OF_BOUNDS; 190 } else { 191 return Flag::SUCCESS; 192 } 193 } 194 195 void print(outputStream* st) { 196 st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max); 197 } 198 }; 199 200 class CommandLineFlagRange_size_t : public CommandLineFlagRange { 201 size_t _min; 202 size_t _max; 203 const size_t* _ptr; 204 205 public: 206 // the "name" argument must be a string literal 207 CommandLineFlagRange_size_t(const char* name, const size_t* ptr, size_t min, size_t max) 208 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 209 210 Flag::Error check(bool verbose = true) { 211 return check_size_t(*_ptr, verbose); 212 } 213 214 Flag::Error check_size_t(size_t value, bool verbose = true) { 215 if ((value < _min) || (value > _max)) { 216 CommandLineError::print(verbose, 217 "size_t %s=" SIZE_FORMAT " is outside the allowed range " 218 "[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n", 219 name(), value, _min, _max); 220 return Flag::OUT_OF_BOUNDS; 221 } else { 222 return Flag::SUCCESS; 223 } 224 } 225 226 void print(outputStream* st) { 227 st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max); 228 } 229 }; 230 231 class CommandLineFlagRange_double : public CommandLineFlagRange { 232 double _min; 233 double _max; 234 const double* _ptr; 235 236 public: 237 // the "name" argument must be a string literal 238 CommandLineFlagRange_double(const char* name, const double* ptr, double min, double max) 239 : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {} 240 241 Flag::Error check(bool verbose = true) { 242 return check_double(*_ptr, verbose); 243 } 244 245 Flag::Error check_double(double value, bool verbose = true) { 246 if ((value < _min) || (value > _max)) { 247 CommandLineError::print(verbose, 248 "double %s=%f is outside the allowed range " 249 "[ %f ... %f ]\n", 250 name(), value, _min, _max); 251 return Flag::OUT_OF_BOUNDS; 252 } else { 253 return Flag::SUCCESS; 254 } 255 } 256 257 void print(outputStream* st) { 258 st->print("[ %-25.3f ... %25.3f ]", _min, _max); 259 } 260 }; 261 262 // No constraint emitting 263 void emit_range_no(...) { /* NOP */ } 264 265 // No constraint emitting if function argument is NOT provided 266 void emit_range_bool(const char* /*name*/, const bool* /*value*/) { /* NOP */ } 267 void emit_range_ccstr(const char* /*name*/, const ccstr* /*value*/) { /* NOP */ } 268 void emit_range_ccstrlist(const char* /*name*/, const ccstrlist* /*value*/) { /* NOP */ } 269 void emit_range_int(const char* /*name*/, const int* /*value*/) { /* NOP */ } 270 void emit_range_intx(const char* /*name*/, const intx* /*value*/) { /* NOP */ } 271 void emit_range_uint(const char* /*name*/, const uint* /*value*/) { /* NOP */ } 272 void emit_range_uintx(const char* /*name*/, const uintx* /*value*/) { /* NOP */ } 273 void emit_range_uint64_t(const char* /*name*/, const uint64_t* /*value*/) { /* NOP */ } 274 void emit_range_size_t(const char* /*name*/, const size_t* /*value*/) { /* NOP */ } 275 void emit_range_double(const char* /*name*/, const double* /*value*/) { /* NOP */ } 276 277 // CommandLineFlagRange emitting code functions if range arguments are provided 278 void emit_range_int(const char* name, const int* ptr, int min, int max) { 279 CommandLineFlagRangeList::add(new CommandLineFlagRange_int(name, ptr, min, max)); 280 } 281 void emit_range_intx(const char* name, const intx* ptr, intx min, intx max) { 282 CommandLineFlagRangeList::add(new CommandLineFlagRange_intx(name, ptr, min, max)); 283 } 284 void emit_range_uint(const char* name, const uint* ptr, uint min, uint max) { 285 CommandLineFlagRangeList::add(new CommandLineFlagRange_uint(name, ptr, min, max)); 286 } 287 void emit_range_uintx(const char* name, const uintx* ptr, uintx min, uintx max) { 288 CommandLineFlagRangeList::add(new CommandLineFlagRange_uintx(name, ptr, min, max)); 289 } 290 void emit_range_uint64_t(const char* name, const uint64_t* ptr, uint64_t min, uint64_t max) { 291 CommandLineFlagRangeList::add(new CommandLineFlagRange_uint64_t(name, ptr, min, max)); 292 } 293 void emit_range_size_t(const char* name, const size_t* ptr, size_t min, size_t max) { 294 CommandLineFlagRangeList::add(new CommandLineFlagRange_size_t(name, ptr, min, max)); 295 } 296 void emit_range_double(const char* name, const double* ptr, double min, double max) { 297 CommandLineFlagRangeList::add(new CommandLineFlagRange_double(name, ptr, min, max)); 298 } 299 300 // Generate code to call emit_range_xxx function 301 #define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 302 #define EMIT_RANGE_COMMERCIAL_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 303 #define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 304 #define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 305 #define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 306 #define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 307 #define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc) ); emit_range_##type(#name,&name 308 #define EMIT_RANGE_PD_DIAGNOSTIC_FLAG(type, name, doc) ); emit_range_##type(#name,&name 309 #ifndef PRODUCT 310 #define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 311 #define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc) ); emit_range_##type(#name,&name 312 #define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 313 #else 314 #define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc) ); emit_range_no(#name,&name 315 #define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc) ); emit_range_no(#name,&name 316 #define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_range_no(#name,&name 317 #endif 318 #ifdef _LP64 319 #define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name 320 #else 321 #define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_no(#name,&name 322 #endif 323 324 // Generate func argument to pass into emit_range_xxx functions 325 #define EMIT_RANGE_CHECK(a, b) , a, b 326 327 #define INITIAL_RANGES_SIZE 379 328 GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL; 329 330 // Check the ranges of all flags that have them 331 void CommandLineFlagRangeList::init(void) { 332 333 _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true); 334 335 emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 336 EMIT_RANGE_PD_DEVELOPER_FLAG, 337 EMIT_RANGE_PRODUCT_FLAG, 338 EMIT_RANGE_PD_PRODUCT_FLAG, 339 EMIT_RANGE_DIAGNOSTIC_FLAG, 340 EMIT_RANGE_PD_DIAGNOSTIC_FLAG, 341 EMIT_RANGE_EXPERIMENTAL_FLAG, 342 EMIT_RANGE_NOTPRODUCT_FLAG, 343 EMIT_RANGE_MANAGEABLE_FLAG, 344 EMIT_RANGE_PRODUCT_RW_FLAG, 345 EMIT_RANGE_LP64_PRODUCT_FLAG, 346 EMIT_RANGE_CHECK, 347 IGNORE_CONSTRAINT, 348 IGNORE_WRITEABLE)); 349 350 EMIT_RANGES_FOR_GLOBALS_EXT 351 352 emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 353 EMIT_RANGE_PRODUCT_FLAG, 354 EMIT_RANGE_DIAGNOSTIC_FLAG, 355 EMIT_RANGE_EXPERIMENTAL_FLAG, 356 EMIT_RANGE_NOTPRODUCT_FLAG, 357 EMIT_RANGE_CHECK, 358 IGNORE_CONSTRAINT, 359 IGNORE_WRITEABLE)); 360 361 #if INCLUDE_JVMCI 362 emit_range_no(NULL JVMCI_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 363 EMIT_RANGE_PD_DEVELOPER_FLAG, 364 EMIT_RANGE_PRODUCT_FLAG, 365 EMIT_RANGE_PD_PRODUCT_FLAG, 366 EMIT_RANGE_DIAGNOSTIC_FLAG, 367 EMIT_RANGE_PD_DIAGNOSTIC_FLAG, 368 EMIT_RANGE_EXPERIMENTAL_FLAG, 369 EMIT_RANGE_NOTPRODUCT_FLAG, 370 EMIT_RANGE_CHECK, 371 IGNORE_CONSTRAINT, 372 IGNORE_WRITEABLE)); 373 #endif // INCLUDE_JVMCI 374 375 #ifdef COMPILER1 376 emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 377 EMIT_RANGE_PD_DEVELOPER_FLAG, 378 EMIT_RANGE_PRODUCT_FLAG, 379 EMIT_RANGE_PD_PRODUCT_FLAG, 380 EMIT_RANGE_DIAGNOSTIC_FLAG, 381 EMIT_RANGE_PD_DIAGNOSTIC_FLAG, 382 EMIT_RANGE_NOTPRODUCT_FLAG, 383 EMIT_RANGE_CHECK, 384 IGNORE_CONSTRAINT, 385 IGNORE_WRITEABLE)); 386 #endif // COMPILER1 387 388 #ifdef COMPILER2 389 emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 390 EMIT_RANGE_PD_DEVELOPER_FLAG, 391 EMIT_RANGE_PRODUCT_FLAG, 392 EMIT_RANGE_PD_PRODUCT_FLAG, 393 EMIT_RANGE_DIAGNOSTIC_FLAG, 394 EMIT_RANGE_PD_DIAGNOSTIC_FLAG, 395 EMIT_RANGE_EXPERIMENTAL_FLAG, 396 EMIT_RANGE_NOTPRODUCT_FLAG, 397 EMIT_RANGE_CHECK, 398 IGNORE_CONSTRAINT, 399 IGNORE_WRITEABLE)); 400 #endif // COMPILER2 401 402 #if INCLUDE_ALL_GCS 403 emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 404 EMIT_RANGE_PD_DEVELOPER_FLAG, 405 EMIT_RANGE_PRODUCT_FLAG, 406 EMIT_RANGE_PD_PRODUCT_FLAG, 407 EMIT_RANGE_DIAGNOSTIC_FLAG, 408 EMIT_RANGE_PD_DIAGNOSTIC_FLAG, 409 EMIT_RANGE_EXPERIMENTAL_FLAG, 410 EMIT_RANGE_NOTPRODUCT_FLAG, 411 EMIT_RANGE_MANAGEABLE_FLAG, 412 EMIT_RANGE_PRODUCT_RW_FLAG, 413 EMIT_RANGE_CHECK, 414 IGNORE_CONSTRAINT, 415 IGNORE_WRITEABLE)); 416 #endif // INCLUDE_ALL_GCS 417 } 418 419 CommandLineFlagRange* CommandLineFlagRangeList::find(const char* name) { 420 CommandLineFlagRange* found = NULL; 421 for (int i=0; i<length(); i++) { 422 CommandLineFlagRange* range = at(i); 423 if (strcmp(range->name(), name) == 0) { 424 found = range; 425 break; 426 } 427 } 428 return found; 429 } 430 431 void CommandLineFlagRangeList::print(outputStream* st, const char* name, RangeStrFunc default_range_str_func) { 432 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 433 if (range != NULL) { 434 range->print(st); 435 } else { 436 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); 437 if (constraint != NULL) { 438 assert(default_range_str_func!=NULL, "default_range_str_func must be provided"); 439 st->print("%s", default_range_str_func()); 440 } else { 441 st->print("[ ... ]"); 442 } 443 } 444 } 445 446 bool CommandLineFlagRangeList::check_ranges() { 447 // Check ranges. 448 bool status = true; 449 for (int i=0; i<length(); i++) { 450 CommandLineFlagRange* range = at(i); 451 if (range->check(true) != Flag::SUCCESS) status = false; 452 } 453 return status; 454 }