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