1 /* 2 * Copyright (c) 1997, 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 "memory/allocation.inline.hpp" 27 #include "oops/oop.inline.hpp" 28 #include "runtime/arguments.hpp" 29 #include "runtime/globals.hpp" 30 #include "runtime/globals_extension.hpp" 31 #include "runtime/commandLineFlagConstraintList.hpp" 32 #include "runtime/commandLineFlagRangeList.hpp" 33 #include "runtime/os.hpp" 34 #include "runtime/sharedRuntime.hpp" 35 #include "trace/tracing.hpp" 36 #include "utilities/macros.hpp" 37 #include "utilities/ostream.hpp" 38 #if INCLUDE_ALL_GCS 39 #include "gc/g1/g1_globals.hpp" 40 #endif // INCLUDE_ALL_GCS 41 #ifdef COMPILER1 42 #include "c1/c1_globals.hpp" 43 #endif 44 #if INCLUDE_JVMCI 45 #include "jvmci/jvmci_globals.hpp" 46 #endif 47 #ifdef COMPILER2 48 #include "opto/c2_globals.hpp" 49 #endif 50 #ifdef SHARK 51 #include "shark/shark_globals.hpp" 52 #endif 53 54 RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \ 55 MATERIALIZE_PD_DEVELOPER_FLAG, \ 56 MATERIALIZE_PRODUCT_FLAG, \ 57 MATERIALIZE_PD_PRODUCT_FLAG, \ 58 MATERIALIZE_DIAGNOSTIC_FLAG, \ 59 MATERIALIZE_EXPERIMENTAL_FLAG, \ 60 MATERIALIZE_NOTPRODUCT_FLAG, \ 61 MATERIALIZE_MANAGEABLE_FLAG, \ 62 MATERIALIZE_PRODUCT_RW_FLAG, \ 63 MATERIALIZE_LP64_PRODUCT_FLAG, \ 64 IGNORE_RANGE, \ 65 IGNORE_CONSTRAINT) 66 67 RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \ 68 MATERIALIZE_PD_DEVELOPER_FLAG, \ 69 MATERIALIZE_PRODUCT_FLAG, \ 70 MATERIALIZE_PD_PRODUCT_FLAG, \ 71 MATERIALIZE_DIAGNOSTIC_FLAG, \ 72 MATERIALIZE_NOTPRODUCT_FLAG, \ 73 IGNORE_RANGE, \ 74 IGNORE_CONSTRAINT) 75 76 ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \ 77 MATERIALIZE_PRODUCT_FLAG, \ 78 MATERIALIZE_DIAGNOSTIC_FLAG, \ 79 MATERIALIZE_EXPERIMENTAL_FLAG, \ 80 MATERIALIZE_NOTPRODUCT_FLAG, \ 81 IGNORE_RANGE, \ 82 IGNORE_CONSTRAINT) 83 84 MATERIALIZE_FLAGS_EXT 85 86 #define DEFAULT_RANGE_STR_CHUNK_SIZE 64 87 static char* create_range_str(const char *fmt, ...) { 88 static size_t string_length = DEFAULT_RANGE_STR_CHUNK_SIZE; 89 static char* range_string = NEW_C_HEAP_ARRAY(char, string_length, mtLogging); 90 91 int size_needed = 0; 92 do { 93 va_list args; 94 va_start(args, fmt); 95 size_needed = jio_vsnprintf(range_string, string_length, fmt, args); 96 va_end(args); 97 98 if (size_needed < 0) { 99 string_length += DEFAULT_RANGE_STR_CHUNK_SIZE; 100 range_string = REALLOC_C_HEAP_ARRAY(char, range_string, string_length, mtLogging); 101 guarantee(range_string != NULL, "create_range_str string should not be NULL"); 102 } 103 } while (size_needed < 0); 104 105 return range_string; 106 } 107 108 const char* Flag::get_int_default_range_str() { 109 return create_range_str("[ " INT32_FORMAT_W(-25) " ... " INT32_FORMAT_W(25) " ]", INT_MIN, INT_MAX); 110 } 111 112 const char* Flag::get_uint_default_range_str() { 113 return create_range_str("[ " UINT32_FORMAT_W(-25) " ... " UINT32_FORMAT_W(25) " ]", 0, UINT_MAX); 114 } 115 116 const char* Flag::get_intx_default_range_str() { 117 return create_range_str("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", min_intx, max_intx); 118 } 119 120 const char* Flag::get_uintx_default_range_str() { 121 return create_range_str("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", 0, max_uintx); 122 } 123 124 const char* Flag::get_uint64_t_default_range_str() { 125 return create_range_str("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", 0, uint64_t(max_juint)); 126 } 127 128 const char* Flag::get_size_t_default_range_str() { 129 return create_range_str("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", 0, SIZE_MAX); 130 } 131 132 const char* Flag::get_double_default_range_str() { 133 return create_range_str("[ %-25.3f ... %25.3f ]", DBL_MIN, DBL_MAX); 134 } 135 136 static bool is_product_build() { 137 #ifdef PRODUCT 138 return true; 139 #else 140 return false; 141 #endif 142 } 143 144 void Flag::check_writable() { 145 if (is_constant_in_binary()) { 146 fatal("flag is constant: %s", _name); 147 } 148 } 149 150 bool Flag::is_bool() const { 151 return strcmp(_type, "bool") == 0; 152 } 153 154 bool Flag::get_bool() const { 155 return *((bool*) _addr); 156 } 157 158 void Flag::set_bool(bool value) { 159 check_writable(); 160 *((bool*) _addr) = value; 161 } 162 163 bool Flag::is_int() const { 164 return strcmp(_type, "int") == 0; 165 } 166 167 int Flag::get_int() const { 168 return *((int*) _addr); 169 } 170 171 void Flag::set_int(int value) { 172 check_writable(); 173 *((int*) _addr) = value; 174 } 175 176 bool Flag::is_uint() const { 177 return strcmp(_type, "uint") == 0; 178 } 179 180 uint Flag::get_uint() const { 181 return *((uint*) _addr); 182 } 183 184 void Flag::set_uint(uint value) { 185 check_writable(); 186 *((uint*) _addr) = value; 187 } 188 189 bool Flag::is_intx() const { 190 return strcmp(_type, "intx") == 0; 191 } 192 193 intx Flag::get_intx() const { 194 return *((intx*) _addr); 195 } 196 197 void Flag::set_intx(intx value) { 198 check_writable(); 199 *((intx*) _addr) = value; 200 } 201 202 bool Flag::is_uintx() const { 203 return strcmp(_type, "uintx") == 0; 204 } 205 206 uintx Flag::get_uintx() const { 207 return *((uintx*) _addr); 208 } 209 210 void Flag::set_uintx(uintx value) { 211 check_writable(); 212 *((uintx*) _addr) = value; 213 } 214 215 bool Flag::is_uint64_t() const { 216 return strcmp(_type, "uint64_t") == 0; 217 } 218 219 uint64_t Flag::get_uint64_t() const { 220 return *((uint64_t*) _addr); 221 } 222 223 void Flag::set_uint64_t(uint64_t value) { 224 check_writable(); 225 *((uint64_t*) _addr) = value; 226 } 227 228 bool Flag::is_size_t() const { 229 return strcmp(_type, "size_t") == 0; 230 } 231 232 size_t Flag::get_size_t() const { 233 return *((size_t*) _addr); 234 } 235 236 void Flag::set_size_t(size_t value) { 237 check_writable(); 238 *((size_t*) _addr) = value; 239 } 240 241 bool Flag::is_double() const { 242 return strcmp(_type, "double") == 0; 243 } 244 245 double Flag::get_double() const { 246 return *((double*) _addr); 247 } 248 249 void Flag::set_double(double value) { 250 check_writable(); 251 *((double*) _addr) = value; 252 } 253 254 bool Flag::is_ccstr() const { 255 return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0; 256 } 257 258 bool Flag::ccstr_accumulates() const { 259 return strcmp(_type, "ccstrlist") == 0; 260 } 261 262 ccstr Flag::get_ccstr() const { 263 return *((ccstr*) _addr); 264 } 265 266 void Flag::set_ccstr(ccstr value) { 267 check_writable(); 268 *((ccstr*) _addr) = value; 269 } 270 271 272 Flag::Flags Flag::get_origin() { 273 return Flags(_flags & VALUE_ORIGIN_MASK); 274 } 275 276 void Flag::set_origin(Flags origin) { 277 assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity"); 278 _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin); 279 } 280 281 bool Flag::is_default() { 282 return (get_origin() == DEFAULT); 283 } 284 285 bool Flag::is_ergonomic() { 286 return (get_origin() == ERGONOMIC); 287 } 288 289 bool Flag::is_command_line() { 290 return (get_origin() == COMMAND_LINE); 291 } 292 293 bool Flag::is_product() const { 294 return (_flags & KIND_PRODUCT) != 0; 295 } 296 297 bool Flag::is_manageable() const { 298 return (_flags & KIND_MANAGEABLE) != 0; 299 } 300 301 bool Flag::is_diagnostic() const { 302 return (_flags & KIND_DIAGNOSTIC) != 0; 303 } 304 305 bool Flag::is_experimental() const { 306 return (_flags & KIND_EXPERIMENTAL) != 0; 307 } 308 309 bool Flag::is_notproduct() const { 310 return (_flags & KIND_NOT_PRODUCT) != 0; 311 } 312 313 bool Flag::is_develop() const { 314 return (_flags & KIND_DEVELOP) != 0; 315 } 316 317 bool Flag::is_read_write() const { 318 return (_flags & KIND_READ_WRITE) != 0; 319 } 320 321 bool Flag::is_commercial() const { 322 return (_flags & KIND_COMMERCIAL) != 0; 323 } 324 325 /** 326 * Returns if this flag is a constant in the binary. Right now this is 327 * true for notproduct and develop flags in product builds. 328 */ 329 bool Flag::is_constant_in_binary() const { 330 #ifdef PRODUCT 331 return is_notproduct() || is_develop(); 332 #else 333 return false; 334 #endif 335 } 336 337 bool Flag::is_unlocker() const { 338 return strcmp(_name, "UnlockDiagnosticVMOptions") == 0 || 339 strcmp(_name, "UnlockExperimentalVMOptions") == 0 || 340 is_unlocker_ext(); 341 } 342 343 bool Flag::is_unlocked() const { 344 if (is_diagnostic()) { 345 return UnlockDiagnosticVMOptions; 346 } 347 if (is_experimental()) { 348 return UnlockExperimentalVMOptions; 349 } 350 return is_unlocked_ext(); 351 } 352 353 void Flag::unlock_diagnostic() { 354 assert(is_diagnostic(), "sanity"); 355 _flags = Flags(_flags & ~KIND_DIAGNOSTIC); 356 } 357 358 // Get custom message for this locked flag, or NULL if 359 // none is available. Returns message type produced. 360 Flag::MsgType Flag::get_locked_message(char* buf, int buflen) const { 361 buf[0] = '\0'; 362 if (is_diagnostic() && !is_unlocked()) { 363 jio_snprintf(buf, buflen, 364 "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n" 365 "Error: The unlock option must precede '%s'.\n", 366 _name, _name); 367 return Flag::DIAGNOSTIC_FLAG_BUT_LOCKED; 368 } 369 if (is_experimental() && !is_unlocked()) { 370 jio_snprintf(buf, buflen, 371 "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n" 372 "Error: The unlock option must precede '%s'.\n", 373 _name, _name); 374 return Flag::EXPERIMENTAL_FLAG_BUT_LOCKED; 375 } 376 if (is_develop() && is_product_build()) { 377 jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n", 378 _name); 379 return Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD; 380 } 381 if (is_notproduct() && is_product_build()) { 382 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n", 383 _name); 384 return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD; 385 } 386 get_locked_message_ext(buf, buflen); 387 return Flag::NONE; 388 } 389 390 bool Flag::is_writeable() const { 391 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext(); 392 } 393 394 // All flags except "manageable" are assumed to be internal flags. 395 // Long term, we need to define a mechanism to specify which flags 396 // are external/stable and change this function accordingly. 397 bool Flag::is_external() const { 398 return is_manageable() || is_external_ext(); 399 } 400 401 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) { 402 // Don't print notproduct and develop flags in a product build. 403 if (is_constant_in_binary()) { 404 return; 405 } 406 407 if (!printRanges) { 408 409 st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' ')); 410 411 if (is_bool()) { 412 st->print("%-16s", get_bool() ? "true" : "false"); 413 } else if (is_int()) { 414 st->print("%-16d", get_int()); 415 } else if (is_uint()) { 416 st->print("%-16u", get_uint()); 417 } else if (is_intx()) { 418 st->print(INTX_FORMAT_W(-16), get_intx()); 419 } else if (is_uintx()) { 420 st->print(UINTX_FORMAT_W(-16), get_uintx()); 421 } else if (is_uint64_t()) { 422 st->print(UINT64_FORMAT_W(-16), get_uint64_t()); 423 } else if (is_size_t()) { 424 st->print(SIZE_FORMAT_W(-16), get_size_t()); 425 } else if (is_double()) { 426 st->print("%-16f", get_double()); 427 } else if (is_ccstr()) { 428 const char* cp = get_ccstr(); 429 if (cp != NULL) { 430 const char* eol; 431 while ((eol = strchr(cp, '\n')) != NULL) { 432 size_t llen = pointer_delta(eol, cp, sizeof(char)); 433 st->print("%.*s", (int)llen, cp); 434 st->cr(); 435 cp = eol+1; 436 st->print("%5s %-35s += ", "", _name); 437 } 438 st->print("%-16s", cp); 439 } 440 else st->print("%-16s", ""); 441 } 442 443 st->print("%-20s", " "); 444 print_kind(st); 445 446 #ifndef PRODUCT 447 if (withComments) { 448 st->print("%s", _doc); 449 } 450 #endif 451 452 st->cr(); 453 454 } else if (!is_bool() && !is_ccstr()) { 455 st->print("%9s %-50s ", _type, _name); 456 457 RangeStrFunc func = NULL; 458 if (is_int()) { 459 func = Flag::get_int_default_range_str; 460 } else if (is_uint()) { 461 func = Flag::get_uint_default_range_str; 462 } else if (is_intx()) { 463 func = Flag::get_intx_default_range_str; 464 } else if (is_uintx()) { 465 func = Flag::get_uintx_default_range_str; 466 } else if (is_uint64_t()) { 467 func = Flag::get_uint64_t_default_range_str; 468 } else if (is_size_t()) { 469 func = Flag::get_size_t_default_range_str; 470 } else if (is_double()) { 471 func = Flag::get_double_default_range_str; 472 } else { 473 ShouldNotReachHere(); 474 } 475 CommandLineFlagRangeList::print(st, _name, func); 476 477 st->print(" %-20s", " "); 478 print_kind(st); 479 480 #ifndef PRODUCT 481 if (withComments) { 482 st->print("%s", _doc); 483 } 484 #endif 485 486 st->cr(); 487 } 488 } 489 490 void Flag::print_kind(outputStream* st) { 491 struct Data { 492 int flag; 493 const char* name; 494 }; 495 496 Data data[] = { 497 { KIND_JVMCI, "JVMCI" }, 498 { KIND_C1, "C1" }, 499 { KIND_C2, "C2" }, 500 { KIND_ARCH, "ARCH" }, 501 { KIND_SHARK, "SHARK" }, 502 { KIND_PLATFORM_DEPENDENT, "pd" }, 503 { KIND_PRODUCT, "product" }, 504 { KIND_MANAGEABLE, "manageable" }, 505 { KIND_DIAGNOSTIC, "diagnostic" }, 506 { KIND_EXPERIMENTAL, "experimental" }, 507 { KIND_COMMERCIAL, "commercial" }, 508 { KIND_NOT_PRODUCT, "notproduct" }, 509 { KIND_DEVELOP, "develop" }, 510 { KIND_LP64_PRODUCT, "lp64_product" }, 511 { KIND_READ_WRITE, "rw" }, 512 { -1, "" } 513 }; 514 515 if ((_flags & KIND_MASK) != 0) { 516 st->print("{"); 517 bool is_first = true; 518 519 for (int i = 0; data[i].flag != -1; i++) { 520 Data d = data[i]; 521 if ((_flags & d.flag) != 0) { 522 if (is_first) { 523 is_first = false; 524 } else { 525 st->print(" "); 526 } 527 st->print("%s", d.name); 528 } 529 } 530 531 st->print("}"); 532 } 533 } 534 535 void Flag::print_as_flag(outputStream* st) { 536 if (is_bool()) { 537 st->print("-XX:%s%s", get_bool() ? "+" : "-", _name); 538 } else if (is_int()) { 539 st->print("-XX:%s=%d", _name, get_int()); 540 } else if (is_uint()) { 541 st->print("-XX:%s=%u", _name, get_uint()); 542 } else if (is_intx()) { 543 st->print("-XX:%s=" INTX_FORMAT, _name, get_intx()); 544 } else if (is_uintx()) { 545 st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx()); 546 } else if (is_uint64_t()) { 547 st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t()); 548 } else if (is_size_t()) { 549 st->print("-XX:%s=" SIZE_FORMAT, _name, get_size_t()); 550 } else if (is_double()) { 551 st->print("-XX:%s=%f", _name, get_double()); 552 } else if (is_ccstr()) { 553 st->print("-XX:%s=", _name); 554 const char* cp = get_ccstr(); 555 if (cp != NULL) { 556 // Need to turn embedded '\n's back into separate arguments 557 // Not so efficient to print one character at a time, 558 // but the choice is to do the transformation to a buffer 559 // and print that. And this need not be efficient. 560 for (; *cp != '\0'; cp += 1) { 561 switch (*cp) { 562 default: 563 st->print("%c", *cp); 564 break; 565 case '\n': 566 st->print(" -XX:%s=", _name); 567 break; 568 } 569 } 570 } 571 } else { 572 ShouldNotReachHere(); 573 } 574 } 575 576 const char* Flag::flag_error_str(Flag::Error error) { 577 switch (error) { 578 case Flag::MISSING_NAME: return "MISSING_NAME"; 579 case Flag::MISSING_VALUE: return "MISSING_VALUE"; 580 case Flag::NON_WRITABLE: return "NON_WRITABLE"; 581 case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS"; 582 case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT"; 583 case Flag::INVALID_FLAG: return "INVALID_FLAG"; 584 case Flag::ERR_OTHER: return "ERR_OTHER"; 585 case Flag::SUCCESS: return "SUCCESS"; 586 default: ShouldNotReachHere(); return "NULL"; 587 } 588 } 589 590 // 4991491 do not "optimize out" the was_set false values: omitting them 591 // tickles a Microsoft compiler bug causing flagTable to be malformed 592 593 #define RUNTIME_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) }, 594 #define RUNTIME_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, 595 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) }, 596 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) }, 597 #define RUNTIME_MANAGEABLE_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) }, 598 #define RUNTIME_PRODUCT_RW_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_READ_WRITE) }, 599 #define RUNTIME_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP) }, 600 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, 601 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_NOT_PRODUCT) }, 602 603 #define JVMCI_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_PRODUCT) }, 604 #define JVMCI_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, 605 #define JVMCI_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DIAGNOSTIC) }, 606 #define JVMCI_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_EXPERIMENTAL) }, 607 #define JVMCI_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DEVELOP) }, 608 #define JVMCI_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, 609 #define JVMCI_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_NOT_PRODUCT) }, 610 611 #ifdef _LP64 612 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_LP64_PRODUCT) }, 613 #else 614 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 615 #endif // _LP64 616 617 #define C1_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT) }, 618 #define C1_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, 619 #define C1_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DIAGNOSTIC) }, 620 #define C1_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP) }, 621 #define C1_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, 622 #define C1_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_NOT_PRODUCT) }, 623 624 #define C2_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT) }, 625 #define C2_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, 626 #define C2_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DIAGNOSTIC) }, 627 #define C2_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_EXPERIMENTAL) }, 628 #define C2_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP) }, 629 #define C2_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, 630 #define C2_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_NOT_PRODUCT) }, 631 632 #define ARCH_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_PRODUCT) }, 633 #define ARCH_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DIAGNOSTIC) }, 634 #define ARCH_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_EXPERIMENTAL) }, 635 #define ARCH_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DEVELOP) }, 636 #define ARCH_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_NOT_PRODUCT) }, 637 638 #define SHARK_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT) }, 639 #define SHARK_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, 640 #define SHARK_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DIAGNOSTIC) }, 641 #define SHARK_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP) }, 642 #define SHARK_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, 643 #define SHARK_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_NOT_PRODUCT) }, 644 645 static Flag flagTable[] = { 646 RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 647 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 648 RUNTIME_PRODUCT_FLAG_STRUCT, \ 649 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 650 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 651 RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \ 652 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 653 RUNTIME_MANAGEABLE_FLAG_STRUCT, \ 654 RUNTIME_PRODUCT_RW_FLAG_STRUCT, \ 655 RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \ 656 IGNORE_RANGE, \ 657 IGNORE_CONSTRAINT) 658 RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 659 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 660 RUNTIME_PRODUCT_FLAG_STRUCT, \ 661 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 662 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 663 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 664 IGNORE_RANGE, \ 665 IGNORE_CONSTRAINT) 666 #if INCLUDE_ALL_GCS 667 G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 668 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 669 RUNTIME_PRODUCT_FLAG_STRUCT, \ 670 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 671 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 672 RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \ 673 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 674 RUNTIME_MANAGEABLE_FLAG_STRUCT, \ 675 RUNTIME_PRODUCT_RW_FLAG_STRUCT, \ 676 IGNORE_RANGE, \ 677 IGNORE_CONSTRAINT) 678 #endif // INCLUDE_ALL_GCS 679 #if INCLUDE_JVMCI 680 JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \ 681 JVMCI_PD_DEVELOP_FLAG_STRUCT, \ 682 JVMCI_PRODUCT_FLAG_STRUCT, \ 683 JVMCI_PD_PRODUCT_FLAG_STRUCT, \ 684 JVMCI_DIAGNOSTIC_FLAG_STRUCT, \ 685 JVMCI_EXPERIMENTAL_FLAG_STRUCT, \ 686 JVMCI_NOTPRODUCT_FLAG_STRUCT, \ 687 IGNORE_RANGE, \ 688 IGNORE_CONSTRAINT) 689 #endif // INCLUDE_JVMCI 690 #ifdef COMPILER1 691 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \ 692 C1_PD_DEVELOP_FLAG_STRUCT, \ 693 C1_PRODUCT_FLAG_STRUCT, \ 694 C1_PD_PRODUCT_FLAG_STRUCT, \ 695 C1_DIAGNOSTIC_FLAG_STRUCT, \ 696 C1_NOTPRODUCT_FLAG_STRUCT, \ 697 IGNORE_RANGE, \ 698 IGNORE_CONSTRAINT) 699 #endif // COMPILER1 700 #ifdef COMPILER2 701 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \ 702 C2_PD_DEVELOP_FLAG_STRUCT, \ 703 C2_PRODUCT_FLAG_STRUCT, \ 704 C2_PD_PRODUCT_FLAG_STRUCT, \ 705 C2_DIAGNOSTIC_FLAG_STRUCT, \ 706 C2_EXPERIMENTAL_FLAG_STRUCT, \ 707 C2_NOTPRODUCT_FLAG_STRUCT, \ 708 IGNORE_RANGE, \ 709 IGNORE_CONSTRAINT) 710 #endif // COMPILER2 711 #ifdef SHARK 712 SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \ 713 SHARK_PD_DEVELOP_FLAG_STRUCT, \ 714 SHARK_PRODUCT_FLAG_STRUCT, \ 715 SHARK_PD_PRODUCT_FLAG_STRUCT, \ 716 SHARK_DIAGNOSTIC_FLAG_STRUCT, \ 717 SHARK_NOTPRODUCT_FLAG_STRUCT) 718 #endif // SHARK 719 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \ 720 ARCH_PRODUCT_FLAG_STRUCT, \ 721 ARCH_DIAGNOSTIC_FLAG_STRUCT, \ 722 ARCH_EXPERIMENTAL_FLAG_STRUCT, \ 723 ARCH_NOTPRODUCT_FLAG_STRUCT, \ 724 IGNORE_RANGE, \ 725 IGNORE_CONSTRAINT) 726 FLAGTABLE_EXT 727 {0, NULL, NULL} 728 }; 729 730 Flag* Flag::flags = flagTable; 731 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); 732 733 inline bool str_equal(const char* s, const char* q, size_t len) { 734 // s is null terminated, q is not! 735 if (strlen(s) != (unsigned int) len) return false; 736 return strncmp(s, q, len) == 0; 737 } 738 739 // Search the flag table for a named flag 740 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) { 741 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) { 742 if (str_equal(current->_name, name, length)) { 743 // Found a matching entry. 744 // Don't report notproduct and develop flags in product builds. 745 if (current->is_constant_in_binary()) { 746 return (return_flag ? current : NULL); 747 } 748 // Report locked flags only if allowed. 749 if (!(current->is_unlocked() || current->is_unlocker())) { 750 if (!allow_locked) { 751 // disable use of locked flags, e.g. diagnostic, experimental, 752 // commercial... until they are explicitly unlocked 753 return NULL; 754 } 755 } 756 return current; 757 } 758 } 759 // Flag name is not in the flag table 760 return NULL; 761 } 762 763 // Compute string similarity based on Dice's coefficient 764 static float str_similar(const char* str1, const char* str2, size_t len2) { 765 int len1 = (int) strlen(str1); 766 int total = len1 + (int) len2; 767 768 int hit = 0; 769 770 for (int i = 0; i < len1 -1; ++i) { 771 for (int j = 0; j < (int) len2 -1; ++j) { 772 if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) { 773 ++hit; 774 break; 775 } 776 } 777 } 778 779 return 2.0f * (float) hit / (float) total; 780 } 781 782 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { 783 float VMOptionsFuzzyMatchSimilarity = 0.7f; 784 Flag* match = NULL; 785 float score; 786 float max_score = -1; 787 788 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) { 789 score = str_similar(current->_name, name, length); 790 if (score > max_score) { 791 max_score = score; 792 match = current; 793 } 794 } 795 796 if (!(match->is_unlocked() || match->is_unlocker())) { 797 if (!allow_locked) { 798 return NULL; 799 } 800 } 801 802 if (max_score < VMOptionsFuzzyMatchSimilarity) { 803 return NULL; 804 } 805 806 return match; 807 } 808 809 // Returns the address of the index'th element 810 static Flag* address_of_flag(CommandLineFlagWithType flag) { 811 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 812 return &Flag::flags[flag]; 813 } 814 815 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { 816 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 817 Flag* f = &Flag::flags[flag]; 818 return f->is_default(); 819 } 820 821 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) { 822 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 823 Flag* f = &Flag::flags[flag]; 824 return f->is_ergonomic(); 825 } 826 827 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) { 828 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 829 Flag* f = &Flag::flags[flag]; 830 return f->is_command_line(); 831 } 832 833 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { 834 Flag* result = Flag::find_flag((char*)name, strlen(name)); 835 if (result == NULL) return false; 836 *value = result->is_command_line(); 837 return true; 838 } 839 840 template<class E, class T> 841 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) { 842 E e; 843 e.set_name(name); 844 e.set_old_value(old_value); 845 e.set_new_value(new_value); 846 e.set_origin(origin); 847 e.commit(); 848 } 849 850 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose) { 851 Flag::Error status = Flag::SUCCESS; 852 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 853 if (constraint != NULL) { 854 status = constraint->apply_bool(new_value, verbose); 855 } 856 return status; 857 } 858 859 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) { 860 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 861 if (result == NULL) return Flag::INVALID_FLAG; 862 if (!result->is_bool()) return Flag::WRONG_FORMAT; 863 *value = result->get_bool(); 864 return Flag::SUCCESS; 865 } 866 867 Flag::Error CommandLineFlags::boolAtPut(Flag* flag, bool* value, Flag::Flags origin) { 868 const char* name; 869 if (flag == NULL) return Flag::INVALID_FLAG; 870 if (!flag->is_bool()) return Flag::WRONG_FORMAT; 871 name = flag->_name; 872 Flag::Error check = apply_constraint_and_check_range_bool(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 873 if (check != Flag::SUCCESS) return check; 874 bool old_value = flag->get_bool(); 875 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin); 876 flag->set_bool(*value); 877 *value = old_value; 878 flag->set_origin(origin); 879 return Flag::SUCCESS; 880 } 881 882 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) { 883 Flag* result = Flag::find_flag(name, len); 884 return boolAtPut(result, value, origin); 885 } 886 887 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) { 888 Flag* faddr = address_of_flag(flag); 889 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); 890 return CommandLineFlags::boolAtPut(faddr, &value, origin); 891 } 892 893 static Flag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose) { 894 Flag::Error status = Flag::SUCCESS; 895 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 896 if (range != NULL) { 897 status = range->check_int(new_value, verbose); 898 } 899 if (status == Flag::SUCCESS) { 900 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 901 if (constraint != NULL) { 902 status = constraint->apply_int(new_value, verbose); 903 } 904 } 905 return status; 906 } 907 908 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) { 909 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 910 if (result == NULL) return Flag::INVALID_FLAG; 911 if (!result->is_int()) return Flag::WRONG_FORMAT; 912 *value = result->get_int(); 913 return Flag::SUCCESS; 914 } 915 916 Flag::Error CommandLineFlags::intAtPut(Flag* flag, int* value, Flag::Flags origin) { 917 const char* name; 918 if (flag == NULL) return Flag::INVALID_FLAG; 919 if (!flag->is_int()) return Flag::WRONG_FORMAT; 920 name = flag->_name; 921 Flag::Error check = apply_constraint_and_check_range_int(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 922 if (check != Flag::SUCCESS) return check; 923 int old_value = flag->get_int(); 924 trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin); 925 flag->set_int(*value); 926 *value = old_value; 927 flag->set_origin(origin); 928 return Flag::SUCCESS; 929 } 930 931 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) { 932 Flag* result = Flag::find_flag(name, len); 933 return intAtPut(result, value, origin); 934 } 935 936 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) { 937 Flag* faddr = address_of_flag(flag); 938 guarantee(faddr != NULL && faddr->is_int(), "wrong flag type"); 939 return CommandLineFlags::intAtPut(faddr, &value, origin); 940 } 941 942 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose) { 943 Flag::Error status = Flag::SUCCESS; 944 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 945 if (range != NULL) { 946 status = range->check_uint(new_value, verbose); 947 } 948 if (status == Flag::SUCCESS) { 949 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 950 if (constraint != NULL) { 951 status = constraint->apply_uint(new_value, verbose); 952 } 953 } 954 return status; 955 } 956 957 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) { 958 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 959 if (result == NULL) return Flag::INVALID_FLAG; 960 if (!result->is_uint()) return Flag::WRONG_FORMAT; 961 *value = result->get_uint(); 962 return Flag::SUCCESS; 963 } 964 965 Flag::Error CommandLineFlags::uintAtPut(Flag* flag, uint* value, Flag::Flags origin) { 966 const char* name; 967 if (flag == NULL) return Flag::INVALID_FLAG; 968 if (!flag->is_uint()) return Flag::WRONG_FORMAT; 969 name = flag->_name; 970 Flag::Error check = apply_constraint_and_check_range_uint(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 971 if (check != Flag::SUCCESS) return check; 972 uint old_value = flag->get_uint(); 973 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin); 974 flag->set_uint(*value); 975 *value = old_value; 976 flag->set_origin(origin); 977 return Flag::SUCCESS; 978 } 979 980 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) { 981 Flag* result = Flag::find_flag(name, len); 982 return uintAtPut(result, value, origin); 983 } 984 985 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) { 986 Flag* faddr = address_of_flag(flag); 987 guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type"); 988 return CommandLineFlags::uintAtPut(faddr, &value, origin); 989 } 990 991 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) { 992 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 993 if (result == NULL) return Flag::INVALID_FLAG; 994 if (!result->is_intx()) return Flag::WRONG_FORMAT; 995 *value = result->get_intx(); 996 return Flag::SUCCESS; 997 } 998 999 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose) { 1000 Flag::Error status = Flag::SUCCESS; 1001 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 1002 if (range != NULL) { 1003 status = range->check_intx(new_value, verbose); 1004 } 1005 if (status == Flag::SUCCESS) { 1006 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 1007 if (constraint != NULL) { 1008 status = constraint->apply_intx(new_value, verbose); 1009 } 1010 } 1011 return status; 1012 } 1013 1014 Flag::Error CommandLineFlags::intxAtPut(Flag* flag, intx* value, Flag::Flags origin) { 1015 const char* name; 1016 if (flag == NULL) return Flag::INVALID_FLAG; 1017 if (!flag->is_intx()) return Flag::WRONG_FORMAT; 1018 name = flag->_name; 1019 Flag::Error check = apply_constraint_and_check_range_intx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 1020 if (check != Flag::SUCCESS) return check; 1021 intx old_value = flag->get_intx(); 1022 trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin); 1023 flag->set_intx(*value); 1024 *value = old_value; 1025 flag->set_origin(origin); 1026 return Flag::SUCCESS; 1027 } 1028 1029 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) { 1030 Flag* result = Flag::find_flag(name, len); 1031 return intxAtPut(result, value, origin); 1032 } 1033 1034 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) { 1035 Flag* faddr = address_of_flag(flag); 1036 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); 1037 return CommandLineFlags::intxAtPut(faddr, &value, origin); 1038 } 1039 1040 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) { 1041 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 1042 if (result == NULL) return Flag::INVALID_FLAG; 1043 if (!result->is_uintx()) return Flag::WRONG_FORMAT; 1044 *value = result->get_uintx(); 1045 return Flag::SUCCESS; 1046 } 1047 1048 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose) { 1049 Flag::Error status = Flag::SUCCESS; 1050 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 1051 if (range != NULL) { 1052 status = range->check_uintx(new_value, verbose); 1053 } 1054 if (status == Flag::SUCCESS) { 1055 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 1056 if (constraint != NULL) { 1057 status = constraint->apply_uintx(new_value, verbose); 1058 } 1059 } 1060 return status; 1061 } 1062 1063 Flag::Error CommandLineFlags::uintxAtPut(Flag* flag, uintx* value, Flag::Flags origin) { 1064 const char* name; 1065 if (flag == NULL) return Flag::INVALID_FLAG; 1066 if (!flag->is_uintx()) return Flag::WRONG_FORMAT; 1067 name = flag->_name; 1068 Flag::Error check = apply_constraint_and_check_range_uintx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 1069 if (check != Flag::SUCCESS) return check; 1070 uintx old_value = flag->get_uintx(); 1071 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1072 flag->set_uintx(*value); 1073 *value = old_value; 1074 flag->set_origin(origin); 1075 return Flag::SUCCESS; 1076 } 1077 1078 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) { 1079 Flag* result = Flag::find_flag(name, len); 1080 return uintxAtPut(result, value, origin); 1081 } 1082 1083 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) { 1084 Flag* faddr = address_of_flag(flag); 1085 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); 1086 return CommandLineFlags::uintxAtPut(faddr, &value, origin); 1087 } 1088 1089 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) { 1090 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 1091 if (result == NULL) return Flag::INVALID_FLAG; 1092 if (!result->is_uint64_t()) return Flag::WRONG_FORMAT; 1093 *value = result->get_uint64_t(); 1094 return Flag::SUCCESS; 1095 } 1096 1097 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose) { 1098 Flag::Error status = Flag::SUCCESS; 1099 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 1100 if (range != NULL) { 1101 status = range->check_uint64_t(new_value, verbose); 1102 } 1103 if (status == Flag::SUCCESS) { 1104 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 1105 if (constraint != NULL) { 1106 status = constraint->apply_uint64_t(new_value, verbose); 1107 } 1108 } 1109 return status; 1110 } 1111 1112 Flag::Error CommandLineFlags::uint64_tAtPut(Flag* flag, uint64_t* value, Flag::Flags origin) { 1113 const char* name; 1114 if (flag == NULL) return Flag::INVALID_FLAG; 1115 if (!flag->is_uint64_t()) return Flag::WRONG_FORMAT; 1116 name = flag->_name; 1117 Flag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 1118 if (check != Flag::SUCCESS) return check; 1119 uint64_t old_value = flag->get_uint64_t(); 1120 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1121 flag->set_uint64_t(*value); 1122 *value = old_value; 1123 flag->set_origin(origin); 1124 return Flag::SUCCESS; 1125 } 1126 1127 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) { 1128 Flag* result = Flag::find_flag(name, len); 1129 return uint64_tAtPut(result, value, origin); 1130 } 1131 1132 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) { 1133 Flag* faddr = address_of_flag(flag); 1134 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); 1135 return CommandLineFlags::uint64_tAtPut(faddr, &value, origin); 1136 } 1137 1138 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) { 1139 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 1140 if (result == NULL) return Flag::INVALID_FLAG; 1141 if (!result->is_size_t()) return Flag::WRONG_FORMAT; 1142 *value = result->get_size_t(); 1143 return Flag::SUCCESS; 1144 } 1145 1146 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose) { 1147 Flag::Error status = Flag::SUCCESS; 1148 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 1149 if (range != NULL) { 1150 status = range->check_size_t(new_value, verbose); 1151 } 1152 if (status == Flag::SUCCESS) { 1153 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 1154 if (constraint != NULL) { 1155 status = constraint->apply_size_t(new_value, verbose); 1156 } 1157 } 1158 return status; 1159 } 1160 1161 1162 Flag::Error CommandLineFlags::size_tAtPut(Flag* flag, size_t* value, Flag::Flags origin) { 1163 const char* name; 1164 if (flag == NULL) return Flag::INVALID_FLAG; 1165 if (!flag->is_size_t()) return Flag::WRONG_FORMAT; 1166 name = flag->_name; 1167 Flag::Error check = apply_constraint_and_check_range_size_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 1168 if (check != Flag::SUCCESS) return check; 1169 size_t old_value = flag->get_size_t(); 1170 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1171 flag->set_size_t(*value); 1172 *value = old_value; 1173 flag->set_origin(origin); 1174 return Flag::SUCCESS; 1175 } 1176 1177 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) { 1178 Flag* result = Flag::find_flag(name, len); 1179 return size_tAtPut(result, value, origin); 1180 } 1181 1182 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) { 1183 Flag* faddr = address_of_flag(flag); 1184 guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type"); 1185 return CommandLineFlags::size_tAtPut(faddr, &value, origin); 1186 } 1187 1188 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) { 1189 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 1190 if (result == NULL) return Flag::INVALID_FLAG; 1191 if (!result->is_double()) return Flag::WRONG_FORMAT; 1192 *value = result->get_double(); 1193 return Flag::SUCCESS; 1194 } 1195 1196 static Flag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose) { 1197 Flag::Error status = Flag::SUCCESS; 1198 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); 1199 if (range != NULL) { 1200 status = range->check_double(new_value, verbose); 1201 } 1202 if (status == Flag::SUCCESS) { 1203 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); 1204 if (constraint != NULL) { 1205 status = constraint->apply_double(new_value, verbose); 1206 } 1207 } 1208 return status; 1209 } 1210 1211 Flag::Error CommandLineFlags::doubleAtPut(Flag* flag, double* value, Flag::Flags origin) { 1212 const char* name; 1213 if (flag == NULL) return Flag::INVALID_FLAG; 1214 if (!flag->is_double()) return Flag::WRONG_FORMAT; 1215 name = flag->_name; 1216 Flag::Error check = apply_constraint_and_check_range_double(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); 1217 if (check != Flag::SUCCESS) return check; 1218 double old_value = flag->get_double(); 1219 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin); 1220 flag->set_double(*value); 1221 *value = old_value; 1222 flag->set_origin(origin); 1223 return Flag::SUCCESS; 1224 } 1225 1226 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) { 1227 Flag* result = Flag::find_flag(name, len); 1228 return doubleAtPut(result, value, origin); 1229 } 1230 1231 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) { 1232 Flag* faddr = address_of_flag(flag); 1233 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); 1234 return CommandLineFlags::doubleAtPut(faddr, &value, origin); 1235 } 1236 1237 Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) { 1238 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); 1239 if (result == NULL) return Flag::INVALID_FLAG; 1240 if (!result->is_ccstr()) return Flag::WRONG_FORMAT; 1241 *value = result->get_ccstr(); 1242 return Flag::SUCCESS; 1243 } 1244 1245 Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) { 1246 Flag* result = Flag::find_flag(name, len); 1247 if (result == NULL) return Flag::INVALID_FLAG; 1248 if (!result->is_ccstr()) return Flag::WRONG_FORMAT; 1249 ccstr old_value = result->get_ccstr(); 1250 trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin); 1251 char* new_value = NULL; 1252 if (*value != NULL) { 1253 new_value = os::strdup_check_oom(*value); 1254 } 1255 result->set_ccstr(new_value); 1256 if (result->is_default() && old_value != NULL) { 1257 // Prior value is NOT heap allocated, but was a literal constant. 1258 old_value = os::strdup_check_oom(old_value); 1259 } 1260 *value = old_value; 1261 result->set_origin(origin); 1262 return Flag::SUCCESS; 1263 } 1264 1265 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) { 1266 Flag* faddr = address_of_flag(flag); 1267 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); 1268 ccstr old_value = faddr->get_ccstr(); 1269 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin); 1270 char* new_value = os::strdup_check_oom(value); 1271 faddr->set_ccstr(new_value); 1272 if (!faddr->is_default() && old_value != NULL) { 1273 // Prior value is heap allocated so free it. 1274 FREE_C_HEAP_ARRAY(char, old_value); 1275 } 1276 faddr->set_origin(origin); 1277 return Flag::SUCCESS; 1278 } 1279 1280 extern "C" { 1281 static int compare_flags(const void* void_a, const void* void_b) { 1282 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name); 1283 } 1284 } 1285 1286 void CommandLineFlags::printSetFlags(outputStream* out) { 1287 // Print which flags were set on the command line 1288 // note: this method is called before the thread structure is in place 1289 // which means resource allocation cannot be used. 1290 1291 // The last entry is the null entry. 1292 const size_t length = Flag::numFlags - 1; 1293 1294 // Sort 1295 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); 1296 for (size_t i = 0; i < length; i++) { 1297 array[i] = &flagTable[i]; 1298 } 1299 qsort(array, length, sizeof(Flag*), compare_flags); 1300 1301 // Print 1302 for (size_t i = 0; i < length; i++) { 1303 if (array[i]->get_origin() /* naked field! */) { 1304 array[i]->print_as_flag(out); 1305 out->print(" "); 1306 } 1307 } 1308 out->cr(); 1309 FREE_C_HEAP_ARRAY(Flag*, array); 1310 } 1311 1312 #ifndef PRODUCT 1313 1314 void CommandLineFlags::verify() { 1315 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); 1316 } 1317 1318 #endif // PRODUCT 1319 1320 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) { 1321 // Print the flags sorted by name 1322 // note: this method is called before the thread structure is in place 1323 // which means resource allocation cannot be used. 1324 1325 // The last entry is the null entry. 1326 const size_t length = Flag::numFlags - 1; 1327 1328 // Sort 1329 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); 1330 for (size_t i = 0; i < length; i++) { 1331 array[i] = &flagTable[i]; 1332 } 1333 qsort(array, length, sizeof(Flag*), compare_flags); 1334 1335 // Print 1336 if (!printRanges) { 1337 out->print_cr("[Global flags]"); 1338 } else { 1339 out->print_cr("[Global flags ranges]"); 1340 } 1341 1342 for (size_t i = 0; i < length; i++) { 1343 if (array[i]->is_unlocked()) { 1344 array[i]->print_on(out, withComments, printRanges); 1345 } 1346 } 1347 FREE_C_HEAP_ARRAY(Flag*, array); 1348 }