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