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