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