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