1 /* 2 * Copyright (c) 1997, 2018, 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 is_unlocker_ext(); 345 } 346 347 bool JVMFlag::is_unlocked() const { 348 if (is_diagnostic()) { 349 return UnlockDiagnosticVMOptions; 350 } 351 if (is_experimental()) { 352 return UnlockExperimentalVMOptions; 353 } 354 return is_unlocked_ext(); 355 } 356 357 void JVMFlag::clear_diagnostic() { 358 assert(is_diagnostic(), "sanity"); 359 _flags = Flags(_flags & ~KIND_DIAGNOSTIC); 360 assert(!is_diagnostic(), "sanity"); 361 } 362 363 // Get custom message for this locked flag, or NULL if 364 // none is available. Returns message type produced. 365 JVMFlag::MsgType JVMFlag::get_locked_message(char* buf, int buflen) const { 366 buf[0] = '\0'; 367 if (is_diagnostic() && !is_unlocked()) { 368 jio_snprintf(buf, buflen, 369 "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n" 370 "Error: The unlock option must precede '%s'.\n", 371 _name, _name); 372 return JVMFlag::DIAGNOSTIC_FLAG_BUT_LOCKED; 373 } 374 if (is_experimental() && !is_unlocked()) { 375 jio_snprintf(buf, buflen, 376 "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n" 377 "Error: The unlock option must precede '%s'.\n", 378 _name, _name); 379 return JVMFlag::EXPERIMENTAL_FLAG_BUT_LOCKED; 380 } 381 if (is_develop() && is_product_build()) { 382 jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n", 383 _name); 384 return JVMFlag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD; 385 } 386 if (is_notproduct() && is_product_build()) { 387 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n", 388 _name); 389 return JVMFlag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD; 390 } 391 return get_locked_message_ext(buf, buflen); 392 } 393 394 bool JVMFlag::is_writeable() const { 395 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext(); 396 } 397 398 // All flags except "manageable" are assumed to be internal flags. 399 // Long term, we need to define a mechanism to specify which flags 400 // are external/stable and change this function accordingly. 401 bool JVMFlag::is_external() const { 402 return is_manageable() || is_external_ext(); 403 } 404 405 // Helper function for JVMFlag::print_on(). 406 // Fills current line up to requested position. 407 // Should the current position already be past the requested position, 408 // one separator blank is enforced. 409 void fill_to_pos(outputStream* st, unsigned int req_pos) { 410 if ((unsigned int)st->position() < req_pos) { 411 st->fill_to(req_pos); // need to fill with blanks to reach req_pos 412 } else { 413 st->print(" "); // enforce blank separation. Previous field too long. 414 } 415 } 416 417 void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) { 418 // Don't print notproduct and develop flags in a product build. 419 if (is_constant_in_binary()) { 420 return; 421 } 422 423 if (!printRanges) { 424 // The command line options -XX:+PrintFlags* cause this function to be called 425 // for each existing flag to print information pertinent to this flag. The data 426 // is displayed in columnar form, with the following layout: 427 // col1 - data type, right-justified 428 // col2 - name, left-justified 429 // col3 - ' =' double-char, leading space to align with possible '+=' 430 // col4 - value left-justified 431 // col5 - kind right-justified 432 // col6 - origin left-justified 433 // col7 - comments left-justified 434 // 435 // The column widths are fixed. They are defined such that, for most cases, 436 // an eye-pleasing tabular output is created. 437 // 438 // Sample output: 439 // bool CMSScavengeBeforeRemark = false {product} {default} 440 // uintx CMSScheduleRemarkEdenPenetration = 50 {product} {default} 441 // size_t CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} {default} 442 // uintx CMSScheduleRemarkSamplingRatio = 5 {product} {default} 443 // double CMSSmallCoalSurplusPercent = 1.050000 {product} {default} 444 // ccstr CompileCommandFile = MyFile.cmd {product} {command line} 445 // ccstrlist CompileOnly = Method1 446 // CompileOnly += Method2 {product} {command line} 447 // | | | | | | | 448 // | | | | | | +-- col7 449 // | | | | | +-- col6 450 // | | | | +-- col5 451 // | | | +-- col4 452 // | | +-- col3 453 // | +-- col2 454 // +-- col1 455 456 const unsigned int col_spacing = 1; 457 const unsigned int col1_pos = 0; 458 const unsigned int col1_width = 9; 459 const unsigned int col2_pos = col1_pos + col1_width + col_spacing; 460 const unsigned int col2_width = 39; 461 const unsigned int col3_pos = col2_pos + col2_width + col_spacing; 462 const unsigned int col3_width = 2; 463 const unsigned int col4_pos = col3_pos + col3_width + col_spacing; 464 const unsigned int col4_width = 30; 465 const unsigned int col5_pos = col4_pos + col4_width + col_spacing; 466 const unsigned int col5_width = 20; 467 const unsigned int col6_pos = col5_pos + col5_width + col_spacing; 468 const unsigned int col6_width = 15; 469 const unsigned int col7_pos = col6_pos + col6_width + col_spacing; 470 const unsigned int col7_width = 1; 471 472 st->fill_to(col1_pos); 473 st->print("%*s", col1_width, _type); // right-justified, therefore width is required. 474 475 fill_to_pos(st, col2_pos); 476 st->print("%s", _name); 477 478 fill_to_pos(st, col3_pos); 479 st->print(" ="); // use " =" for proper alignment with multiline ccstr output. 480 481 fill_to_pos(st, col4_pos); 482 if (is_bool()) { 483 st->print("%s", get_bool() ? "true" : "false"); 484 } else if (is_int()) { 485 st->print("%d", get_int()); 486 } else if (is_uint()) { 487 st->print("%u", get_uint()); 488 } else if (is_intx()) { 489 st->print(INTX_FORMAT, get_intx()); 490 } else if (is_uintx()) { 491 st->print(UINTX_FORMAT, get_uintx()); 492 } else if (is_uint64_t()) { 493 st->print(UINT64_FORMAT, get_uint64_t()); 494 } else if (is_size_t()) { 495 st->print(SIZE_FORMAT, get_size_t()); 496 } else if (is_double()) { 497 st->print("%f", get_double()); 498 } else if (is_ccstr()) { 499 // Honor <newline> characters in ccstr: print multiple lines. 500 const char* cp = get_ccstr(); 501 if (cp != NULL) { 502 const char* eol; 503 while ((eol = strchr(cp, '\n')) != NULL) { 504 size_t llen = pointer_delta(eol, cp, sizeof(char)); 505 st->print("%.*s", (int)llen, cp); 506 st->cr(); 507 cp = eol+1; 508 fill_to_pos(st, col2_pos); 509 st->print("%s", _name); 510 fill_to_pos(st, col3_pos); 511 st->print("+="); 512 fill_to_pos(st, col4_pos); 513 } 514 st->print("%s", cp); 515 } 516 } else { 517 st->print("unhandled type %s", _type); 518 st->cr(); 519 return; 520 } 521 522 fill_to_pos(st, col5_pos); 523 print_kind(st, col5_width); 524 525 fill_to_pos(st, col6_pos); 526 print_origin(st, col6_width); 527 528 #ifndef PRODUCT 529 if (withComments) { 530 fill_to_pos(st, col7_pos); 531 st->print("%s", _doc); 532 } 533 #endif 534 st->cr(); 535 } else if (!is_bool() && !is_ccstr()) { 536 // The command line options -XX:+PrintFlags* cause this function to be called 537 // for each existing flag to print information pertinent to this flag. The data 538 // is displayed in columnar form, with the following layout: 539 // col1 - data type, right-justified 540 // col2 - name, left-justified 541 // col4 - range [ min ... max] 542 // col5 - kind right-justified 543 // col6 - origin left-justified 544 // col7 - comments left-justified 545 // 546 // The column widths are fixed. They are defined such that, for most cases, 547 // an eye-pleasing tabular output is created. 548 // 549 // Sample output: 550 // intx MinPassesBeforeFlush [ 0 ... 9223372036854775807 ] {diagnostic} {default} 551 // uintx MinRAMFraction [ 1 ... 18446744073709551615 ] {product} {default} 552 // double MinRAMPercentage [ 0.000 ... 100.000 ] {product} {default} 553 // uintx MinSurvivorRatio [ 3 ... 18446744073709551615 ] {product} {default} 554 // size_t MinTLABSize [ 1 ... 9223372036854775807 ] {product} {default} 555 // intx MonitorBound [ 0 ... 2147483647 ] {product} {default} 556 // | | | | | | 557 // | | | | | +-- col7 558 // | | | | +-- col6 559 // | | | +-- col5 560 // | | +-- col4 561 // | +-- col2 562 // +-- col1 563 564 const unsigned int col_spacing = 1; 565 const unsigned int col1_pos = 0; 566 const unsigned int col1_width = 9; 567 const unsigned int col2_pos = col1_pos + col1_width + col_spacing; 568 const unsigned int col2_width = 49; 569 const unsigned int col3_pos = col2_pos + col2_width + col_spacing; 570 const unsigned int col3_width = 0; 571 const unsigned int col4_pos = col3_pos + col3_width + col_spacing; 572 const unsigned int col4_width = 60; 573 const unsigned int col5_pos = col4_pos + col4_width + col_spacing; 574 const unsigned int col5_width = 35; 575 const unsigned int col6_pos = col5_pos + col5_width + col_spacing; 576 const unsigned int col6_width = 15; 577 const unsigned int col7_pos = col6_pos + col6_width + col_spacing; 578 const unsigned int col7_width = 1; 579 580 st->fill_to(col1_pos); 581 st->print("%*s", col1_width, _type); // right-justified, therefore width is required. 582 583 fill_to_pos(st, col2_pos); 584 st->print("%s", _name); 585 586 fill_to_pos(st, col4_pos); 587 RangeStrFunc func = NULL; 588 if (is_int()) { 589 func = JVMFlag::get_int_default_range_str; 590 } else if (is_uint()) { 591 func = JVMFlag::get_uint_default_range_str; 592 } else if (is_intx()) { 593 func = JVMFlag::get_intx_default_range_str; 594 } else if (is_uintx()) { 595 func = JVMFlag::get_uintx_default_range_str; 596 } else if (is_uint64_t()) { 597 func = JVMFlag::get_uint64_t_default_range_str; 598 } else if (is_size_t()) { 599 func = JVMFlag::get_size_t_default_range_str; 600 } else if (is_double()) { 601 func = JVMFlag::get_double_default_range_str; 602 } else { 603 st->print("unhandled type %s", _type); 604 st->cr(); 605 return; 606 } 607 JVMFlagRangeList::print(st, _name, func); 608 609 fill_to_pos(st, col5_pos); 610 print_kind(st, col5_width); 611 612 fill_to_pos(st, col6_pos); 613 print_origin(st, col6_width); 614 615 #ifndef PRODUCT 616 if (withComments) { 617 fill_to_pos(st, col7_pos); 618 st->print("%s", _doc); 619 } 620 #endif 621 st->cr(); 622 } 623 } 624 625 void JVMFlag::print_kind(outputStream* st, unsigned int width) { 626 struct Data { 627 int flag; 628 const char* name; 629 }; 630 631 Data data[] = { 632 { KIND_JVMCI, "JVMCI" }, 633 { KIND_C1, "C1" }, 634 { KIND_C2, "C2" }, 635 { KIND_ARCH, "ARCH" }, 636 { KIND_PLATFORM_DEPENDENT, "pd" }, 637 { KIND_PRODUCT, "product" }, 638 { KIND_MANAGEABLE, "manageable" }, 639 { KIND_DIAGNOSTIC, "diagnostic" }, 640 { KIND_EXPERIMENTAL, "experimental" }, 641 { KIND_NOT_PRODUCT, "notproduct" }, 642 { KIND_DEVELOP, "develop" }, 643 { KIND_LP64_PRODUCT, "lp64_product" }, 644 { KIND_READ_WRITE, "rw" }, 645 { -1, "" } 646 }; 647 648 if ((_flags & KIND_MASK) != 0) { 649 bool is_first = true; 650 const size_t buffer_size = 64; 651 size_t buffer_used = 0; 652 char kind[buffer_size]; 653 654 jio_snprintf(kind, buffer_size, "{"); 655 buffer_used++; 656 for (int i = 0; data[i].flag != -1; i++) { 657 Data d = data[i]; 658 if ((_flags & d.flag) != 0) { 659 if (is_first) { 660 is_first = false; 661 } else { 662 assert(buffer_used + 1 < buffer_size, "Too small buffer"); 663 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, " "); 664 buffer_used++; 665 } 666 size_t length = strlen(d.name); 667 assert(buffer_used + length < buffer_size, "Too small buffer"); 668 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "%s", d.name); 669 buffer_used += length; 670 } 671 } 672 assert(buffer_used + 2 <= buffer_size, "Too small buffer"); 673 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}"); 674 st->print("%*s", width, kind); 675 } 676 } 677 678 void JVMFlag::print_origin(outputStream* st, unsigned int width) { 679 int origin = _flags & VALUE_ORIGIN_MASK; 680 st->print("{"); 681 switch(origin) { 682 case DEFAULT: 683 st->print("default"); break; 684 case COMMAND_LINE: 685 st->print("command line"); break; 686 case ENVIRON_VAR: 687 st->print("environment"); break; 688 case CONFIG_FILE: 689 st->print("config file"); break; 690 case MANAGEMENT: 691 st->print("management"); break; 692 case ERGONOMIC: 693 if (_flags & ORIG_COMMAND_LINE) { 694 st->print("command line, "); 695 } 696 st->print("ergonomic"); break; 697 case ATTACH_ON_DEMAND: 698 st->print("attach"); break; 699 case INTERNAL: 700 st->print("internal"); break; 701 } 702 st->print("}"); 703 } 704 705 void JVMFlag::print_as_flag(outputStream* st) { 706 if (is_bool()) { 707 st->print("-XX:%s%s", get_bool() ? "+" : "-", _name); 708 } else if (is_int()) { 709 st->print("-XX:%s=%d", _name, get_int()); 710 } else if (is_uint()) { 711 st->print("-XX:%s=%u", _name, get_uint()); 712 } else if (is_intx()) { 713 st->print("-XX:%s=" INTX_FORMAT, _name, get_intx()); 714 } else if (is_uintx()) { 715 st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx()); 716 } else if (is_uint64_t()) { 717 st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t()); 718 } else if (is_size_t()) { 719 st->print("-XX:%s=" SIZE_FORMAT, _name, get_size_t()); 720 } else if (is_double()) { 721 st->print("-XX:%s=%f", _name, get_double()); 722 } else if (is_ccstr()) { 723 st->print("-XX:%s=", _name); 724 const char* cp = get_ccstr(); 725 if (cp != NULL) { 726 // Need to turn embedded '\n's back into separate arguments 727 // Not so efficient to print one character at a time, 728 // but the choice is to do the transformation to a buffer 729 // and print that. And this need not be efficient. 730 for (; *cp != '\0'; cp += 1) { 731 switch (*cp) { 732 default: 733 st->print("%c", *cp); 734 break; 735 case '\n': 736 st->print(" -XX:%s=", _name); 737 break; 738 } 739 } 740 } 741 } else { 742 ShouldNotReachHere(); 743 } 744 } 745 746 const char* JVMFlag::flag_error_str(JVMFlag::Error error) { 747 switch (error) { 748 case JVMFlag::MISSING_NAME: return "MISSING_NAME"; 749 case JVMFlag::MISSING_VALUE: return "MISSING_VALUE"; 750 case JVMFlag::NON_WRITABLE: return "NON_WRITABLE"; 751 case JVMFlag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS"; 752 case JVMFlag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT"; 753 case JVMFlag::INVALID_FLAG: return "INVALID_FLAG"; 754 case JVMFlag::ERR_OTHER: return "ERR_OTHER"; 755 case JVMFlag::SUCCESS: return "SUCCESS"; 756 default: ShouldNotReachHere(); return "NULL"; 757 } 758 } 759 760 // 4991491 do not "optimize out" the was_set false values: omitting them 761 // tickles a Microsoft compiler bug causing flagTable to be malformed 762 763 #define RUNTIME_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_PRODUCT) }, 764 #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) }, 765 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_DIAGNOSTIC) }, 766 #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) }, 767 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_EXPERIMENTAL) }, 768 #define RUNTIME_MANAGEABLE_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_MANAGEABLE) }, 769 #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) }, 770 #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) }, 771 #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) }, 772 #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) }, 773 774 #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) }, 775 #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) }, 776 #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) }, 777 #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) }, 778 #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) }, 779 #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) }, 780 #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) }, 781 #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) }, 782 783 #ifdef _LP64 784 #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) }, 785 #else 786 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 787 #endif // _LP64 788 789 #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) }, 790 #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) }, 791 #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) }, 792 #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) }, 793 #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) }, 794 #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) }, 795 #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) }, 796 797 #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) }, 798 #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) }, 799 #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) }, 800 #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) }, 801 #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) }, 802 #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) }, 803 #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) }, 804 #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) }, 805 806 #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) }, 807 #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) }, 808 #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) }, 809 #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) }, 810 #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) }, 811 812 static JVMFlag flagTable[] = { 813 VM_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 814 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 815 RUNTIME_PRODUCT_FLAG_STRUCT, \ 816 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 817 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 818 RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \ 819 RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \ 820 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 821 RUNTIME_MANAGEABLE_FLAG_STRUCT, \ 822 RUNTIME_PRODUCT_RW_FLAG_STRUCT, \ 823 RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \ 824 IGNORE_RANGE, \ 825 IGNORE_CONSTRAINT, \ 826 IGNORE_WRITEABLE) 827 828 RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 829 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 830 RUNTIME_PRODUCT_FLAG_STRUCT, \ 831 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 832 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 833 RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \ 834 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 835 IGNORE_RANGE, \ 836 IGNORE_CONSTRAINT, \ 837 IGNORE_WRITEABLE) 838 #if INCLUDE_JVMCI 839 JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \ 840 JVMCI_PD_DEVELOP_FLAG_STRUCT, \ 841 JVMCI_PRODUCT_FLAG_STRUCT, \ 842 JVMCI_PD_PRODUCT_FLAG_STRUCT, \ 843 JVMCI_DIAGNOSTIC_FLAG_STRUCT, \ 844 JVMCI_PD_DIAGNOSTIC_FLAG_STRUCT, \ 845 JVMCI_EXPERIMENTAL_FLAG_STRUCT, \ 846 JVMCI_NOTPRODUCT_FLAG_STRUCT, \ 847 IGNORE_RANGE, \ 848 IGNORE_CONSTRAINT, \ 849 IGNORE_WRITEABLE) 850 #endif // INCLUDE_JVMCI 851 #ifdef COMPILER1 852 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \ 853 C1_PD_DEVELOP_FLAG_STRUCT, \ 854 C1_PRODUCT_FLAG_STRUCT, \ 855 C1_PD_PRODUCT_FLAG_STRUCT, \ 856 C1_DIAGNOSTIC_FLAG_STRUCT, \ 857 C1_PD_DIAGNOSTIC_FLAG_STRUCT, \ 858 C1_NOTPRODUCT_FLAG_STRUCT, \ 859 IGNORE_RANGE, \ 860 IGNORE_CONSTRAINT, \ 861 IGNORE_WRITEABLE) 862 #endif // COMPILER1 863 #ifdef COMPILER2 864 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \ 865 C2_PD_DEVELOP_FLAG_STRUCT, \ 866 C2_PRODUCT_FLAG_STRUCT, \ 867 C2_PD_PRODUCT_FLAG_STRUCT, \ 868 C2_DIAGNOSTIC_FLAG_STRUCT, \ 869 C2_PD_DIAGNOSTIC_FLAG_STRUCT, \ 870 C2_EXPERIMENTAL_FLAG_STRUCT, \ 871 C2_NOTPRODUCT_FLAG_STRUCT, \ 872 IGNORE_RANGE, \ 873 IGNORE_CONSTRAINT, \ 874 IGNORE_WRITEABLE) 875 #endif // COMPILER2 876 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \ 877 ARCH_PRODUCT_FLAG_STRUCT, \ 878 ARCH_DIAGNOSTIC_FLAG_STRUCT, \ 879 ARCH_EXPERIMENTAL_FLAG_STRUCT, \ 880 ARCH_NOTPRODUCT_FLAG_STRUCT, \ 881 IGNORE_RANGE, \ 882 IGNORE_CONSTRAINT, \ 883 IGNORE_WRITEABLE) 884 FLAGTABLE_EXT 885 {0, NULL, NULL} 886 }; 887 888 JVMFlag* JVMFlag::flags = flagTable; 889 size_t JVMFlag::numFlags = (sizeof(flagTable) / sizeof(JVMFlag)); 890 891 inline bool str_equal(const char* s, size_t s_len, const char* q, size_t q_len) { 892 if (s_len != q_len) return false; 893 return memcmp(s, q, q_len) == 0; 894 } 895 896 // Search the flag table for a named flag 897 JVMFlag* JVMFlag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) { 898 for (JVMFlag* current = &flagTable[0]; current->_name != NULL; current++) { 899 if (str_equal(current->_name, current->get_name_length(), name, length)) { 900 // Found a matching entry. 901 // Don't report notproduct and develop flags in product builds. 902 if (current->is_constant_in_binary()) { 903 return (return_flag ? current : NULL); 904 } 905 // Report locked flags only if allowed. 906 if (!(current->is_unlocked() || current->is_unlocker())) { 907 if (!allow_locked) { 908 // disable use of locked flags, e.g. diagnostic, experimental, 909 // etc. until they are explicitly unlocked 910 return NULL; 911 } 912 } 913 return current; 914 } 915 } 916 // JVMFlag name is not in the flag table 917 return NULL; 918 } 919 920 // Get or compute the flag name length 921 size_t JVMFlag::get_name_length() { 922 if (_name_len == 0) { 923 _name_len = strlen(_name); 924 } 925 return _name_len; 926 } 927 928 JVMFlag* JVMFlag::fuzzy_match(const char* name, size_t length, bool allow_locked) { 929 float VMOptionsFuzzyMatchSimilarity = 0.7f; 930 JVMFlag* match = NULL; 931 float score; 932 float max_score = -1; 933 934 for (JVMFlag* current = &flagTable[0]; current->_name != NULL; current++) { 935 score = StringUtils::similarity(current->_name, strlen(current->_name), name, length); 936 if (score > max_score) { 937 max_score = score; 938 match = current; 939 } 940 } 941 942 if (!(match->is_unlocked() || match->is_unlocker())) { 943 if (!allow_locked) { 944 return NULL; 945 } 946 } 947 948 if (max_score < VMOptionsFuzzyMatchSimilarity) { 949 return NULL; 950 } 951 952 return match; 953 } 954 955 // Returns the address of the index'th element 956 static JVMFlag* address_of_flag(JVMFlagsWithType flag) { 957 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 958 return &JVMFlag::flags[flag]; 959 } 960 961 bool JVMFlagEx::is_default(JVMFlags flag) { 962 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 963 JVMFlag* f = &JVMFlag::flags[flag]; 964 return f->is_default(); 965 } 966 967 bool JVMFlagEx::is_ergo(JVMFlags flag) { 968 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 969 JVMFlag* f = &JVMFlag::flags[flag]; 970 return f->is_ergonomic(); 971 } 972 973 bool JVMFlagEx::is_cmdline(JVMFlags flag) { 974 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 975 JVMFlag* f = &JVMFlag::flags[flag]; 976 return f->is_command_line(); 977 } 978 979 bool JVMFlag::wasSetOnCmdline(const char* name, bool* value) { 980 JVMFlag* result = JVMFlag::find_flag((char*)name, strlen(name)); 981 if (result == NULL) return false; 982 *value = result->is_command_line(); 983 return true; 984 } 985 986 void JVMFlagEx::setOnCmdLine(JVMFlagsWithType flag) { 987 JVMFlag* faddr = address_of_flag(flag); 988 assert(faddr != NULL, "Unknown flag"); 989 faddr->set_command_line(); 990 } 991 992 template<class E, class T> 993 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const JVMFlag::Flags origin) { 994 E e; 995 e.set_name(name); 996 e.set_oldValue(old_value); 997 e.set_newValue(new_value); 998 e.set_origin(origin); 999 e.commit(); 1000 } 1001 1002 static JVMFlag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose) { 1003 JVMFlag::Error status = JVMFlag::SUCCESS; 1004 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1005 if (constraint != NULL) { 1006 status = constraint->apply_bool(new_value, verbose); 1007 } 1008 return status; 1009 } 1010 1011 JVMFlag::Error JVMFlag::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) { 1012 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1013 if (result == NULL) return JVMFlag::INVALID_FLAG; 1014 if (!result->is_bool()) return JVMFlag::WRONG_FORMAT; 1015 *value = result->get_bool(); 1016 return JVMFlag::SUCCESS; 1017 } 1018 1019 JVMFlag::Error JVMFlag::boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin) { 1020 const char* name; 1021 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1022 if (!flag->is_bool()) return JVMFlag::WRONG_FORMAT; 1023 name = flag->_name; 1024 JVMFlag::Error check = apply_constraint_and_check_range_bool(name, *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>(name, 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 JVMFlag::boolAtPut(const char* name, size_t len, bool* value, JVMFlag::Flags origin) { 1035 JVMFlag* result = JVMFlag::find_flag(name, len); 1036 return boolAtPut(result, value, origin); 1037 } 1038 1039 JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsWithType flag, bool value, JVMFlag::Flags origin) { 1040 JVMFlag* faddr = address_of_flag(flag); 1041 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); 1042 return JVMFlag::boolAtPut(faddr, &value, origin); 1043 } 1044 1045 static JVMFlag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose) { 1046 JVMFlag::Error status = JVMFlag::SUCCESS; 1047 JVMFlagRange* range = JVMFlagRangeList::find(name); 1048 if (range != NULL) { 1049 status = range->check_int(new_value, verbose); 1050 } 1051 if (status == JVMFlag::SUCCESS) { 1052 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1053 if (constraint != NULL) { 1054 status = constraint->apply_int(new_value, verbose); 1055 } 1056 } 1057 return status; 1058 } 1059 1060 JVMFlag::Error JVMFlag::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) { 1061 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1062 if (result == NULL) return JVMFlag::INVALID_FLAG; 1063 if (!result->is_int()) return JVMFlag::WRONG_FORMAT; 1064 *value = result->get_int(); 1065 return JVMFlag::SUCCESS; 1066 } 1067 1068 JVMFlag::Error JVMFlag::intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin) { 1069 const char* name; 1070 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1071 if (!flag->is_int()) return JVMFlag::WRONG_FORMAT; 1072 name = flag->_name; 1073 JVMFlag::Error check = apply_constraint_and_check_range_int(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1074 if (check != JVMFlag::SUCCESS) return check; 1075 int old_value = flag->get_int(); 1076 trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin); 1077 check = flag->set_int(*value); 1078 *value = old_value; 1079 flag->set_origin(origin); 1080 return check; 1081 } 1082 1083 JVMFlag::Error JVMFlag::intAtPut(const char* name, size_t len, int* value, JVMFlag::Flags origin) { 1084 JVMFlag* result = JVMFlag::find_flag(name, len); 1085 return intAtPut(result, value, origin); 1086 } 1087 1088 JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsWithType flag, int value, JVMFlag::Flags origin) { 1089 JVMFlag* faddr = address_of_flag(flag); 1090 guarantee(faddr != NULL && faddr->is_int(), "wrong flag type"); 1091 return JVMFlag::intAtPut(faddr, &value, origin); 1092 } 1093 1094 static JVMFlag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose) { 1095 JVMFlag::Error status = JVMFlag::SUCCESS; 1096 JVMFlagRange* range = JVMFlagRangeList::find(name); 1097 if (range != NULL) { 1098 status = range->check_uint(new_value, verbose); 1099 } 1100 if (status == JVMFlag::SUCCESS) { 1101 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1102 if (constraint != NULL) { 1103 status = constraint->apply_uint(new_value, verbose); 1104 } 1105 } 1106 return status; 1107 } 1108 1109 JVMFlag::Error JVMFlag::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) { 1110 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1111 if (result == NULL) return JVMFlag::INVALID_FLAG; 1112 if (!result->is_uint()) return JVMFlag::WRONG_FORMAT; 1113 *value = result->get_uint(); 1114 return JVMFlag::SUCCESS; 1115 } 1116 1117 JVMFlag::Error JVMFlag::uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin) { 1118 const char* name; 1119 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1120 if (!flag->is_uint()) return JVMFlag::WRONG_FORMAT; 1121 name = flag->_name; 1122 JVMFlag::Error check = apply_constraint_and_check_range_uint(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1123 if (check != JVMFlag::SUCCESS) return check; 1124 uint old_value = flag->get_uint(); 1125 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin); 1126 check = flag->set_uint(*value); 1127 *value = old_value; 1128 flag->set_origin(origin); 1129 return check; 1130 } 1131 1132 JVMFlag::Error JVMFlag::uintAtPut(const char* name, size_t len, uint* value, JVMFlag::Flags origin) { 1133 JVMFlag* result = JVMFlag::find_flag(name, len); 1134 return uintAtPut(result, value, origin); 1135 } 1136 1137 JVMFlag::Error JVMFlagEx::uintAtPut(JVMFlagsWithType flag, uint value, JVMFlag::Flags origin) { 1138 JVMFlag* faddr = address_of_flag(flag); 1139 guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type"); 1140 return JVMFlag::uintAtPut(faddr, &value, origin); 1141 } 1142 1143 JVMFlag::Error JVMFlag::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) { 1144 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1145 if (result == NULL) return JVMFlag::INVALID_FLAG; 1146 if (!result->is_intx()) return JVMFlag::WRONG_FORMAT; 1147 *value = result->get_intx(); 1148 return JVMFlag::SUCCESS; 1149 } 1150 1151 static JVMFlag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose) { 1152 JVMFlag::Error status = JVMFlag::SUCCESS; 1153 JVMFlagRange* range = JVMFlagRangeList::find(name); 1154 if (range != NULL) { 1155 status = range->check_intx(new_value, verbose); 1156 } 1157 if (status == JVMFlag::SUCCESS) { 1158 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1159 if (constraint != NULL) { 1160 status = constraint->apply_intx(new_value, verbose); 1161 } 1162 } 1163 return status; 1164 } 1165 1166 JVMFlag::Error JVMFlag::intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin) { 1167 const char* name; 1168 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1169 if (!flag->is_intx()) return JVMFlag::WRONG_FORMAT; 1170 name = flag->_name; 1171 JVMFlag::Error check = apply_constraint_and_check_range_intx(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1172 if (check != JVMFlag::SUCCESS) return check; 1173 intx old_value = flag->get_intx(); 1174 trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin); 1175 check = flag->set_intx(*value); 1176 *value = old_value; 1177 flag->set_origin(origin); 1178 return check; 1179 } 1180 1181 JVMFlag::Error JVMFlag::intxAtPut(const char* name, size_t len, intx* value, JVMFlag::Flags origin) { 1182 JVMFlag* result = JVMFlag::find_flag(name, len); 1183 return intxAtPut(result, value, origin); 1184 } 1185 1186 JVMFlag::Error JVMFlagEx::intxAtPut(JVMFlagsWithType flag, intx value, JVMFlag::Flags origin) { 1187 JVMFlag* faddr = address_of_flag(flag); 1188 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); 1189 return JVMFlag::intxAtPut(faddr, &value, origin); 1190 } 1191 1192 JVMFlag::Error JVMFlag::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) { 1193 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1194 if (result == NULL) return JVMFlag::INVALID_FLAG; 1195 if (!result->is_uintx()) return JVMFlag::WRONG_FORMAT; 1196 *value = result->get_uintx(); 1197 return JVMFlag::SUCCESS; 1198 } 1199 1200 static JVMFlag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose) { 1201 JVMFlag::Error status = JVMFlag::SUCCESS; 1202 JVMFlagRange* range = JVMFlagRangeList::find(name); 1203 if (range != NULL) { 1204 status = range->check_uintx(new_value, verbose); 1205 } 1206 if (status == JVMFlag::SUCCESS) { 1207 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1208 if (constraint != NULL) { 1209 status = constraint->apply_uintx(new_value, verbose); 1210 } 1211 } 1212 return status; 1213 } 1214 1215 JVMFlag::Error JVMFlag::uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin) { 1216 const char* name; 1217 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1218 if (!flag->is_uintx()) return JVMFlag::WRONG_FORMAT; 1219 name = flag->_name; 1220 JVMFlag::Error check = apply_constraint_and_check_range_uintx(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1221 if (check != JVMFlag::SUCCESS) return check; 1222 uintx old_value = flag->get_uintx(); 1223 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1224 check = flag->set_uintx(*value); 1225 *value = old_value; 1226 flag->set_origin(origin); 1227 return check; 1228 } 1229 1230 JVMFlag::Error JVMFlag::uintxAtPut(const char* name, size_t len, uintx* value, JVMFlag::Flags origin) { 1231 JVMFlag* result = JVMFlag::find_flag(name, len); 1232 return uintxAtPut(result, value, origin); 1233 } 1234 1235 JVMFlag::Error JVMFlagEx::uintxAtPut(JVMFlagsWithType flag, uintx value, JVMFlag::Flags origin) { 1236 JVMFlag* faddr = address_of_flag(flag); 1237 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); 1238 return JVMFlag::uintxAtPut(faddr, &value, origin); 1239 } 1240 1241 JVMFlag::Error JVMFlag::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) { 1242 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1243 if (result == NULL) return JVMFlag::INVALID_FLAG; 1244 if (!result->is_uint64_t()) return JVMFlag::WRONG_FORMAT; 1245 *value = result->get_uint64_t(); 1246 return JVMFlag::SUCCESS; 1247 } 1248 1249 static JVMFlag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose) { 1250 JVMFlag::Error status = JVMFlag::SUCCESS; 1251 JVMFlagRange* range = JVMFlagRangeList::find(name); 1252 if (range != NULL) { 1253 status = range->check_uint64_t(new_value, verbose); 1254 } 1255 if (status == JVMFlag::SUCCESS) { 1256 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1257 if (constraint != NULL) { 1258 status = constraint->apply_uint64_t(new_value, verbose); 1259 } 1260 } 1261 return status; 1262 } 1263 1264 JVMFlag::Error JVMFlag::uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin) { 1265 const char* name; 1266 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1267 if (!flag->is_uint64_t()) return JVMFlag::WRONG_FORMAT; 1268 name = flag->_name; 1269 JVMFlag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1270 if (check != JVMFlag::SUCCESS) return check; 1271 uint64_t old_value = flag->get_uint64_t(); 1272 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1273 check = flag->set_uint64_t(*value); 1274 *value = old_value; 1275 flag->set_origin(origin); 1276 return check; 1277 } 1278 1279 JVMFlag::Error JVMFlag::uint64_tAtPut(const char* name, size_t len, uint64_t* value, JVMFlag::Flags origin) { 1280 JVMFlag* result = JVMFlag::find_flag(name, len); 1281 return uint64_tAtPut(result, value, origin); 1282 } 1283 1284 JVMFlag::Error JVMFlagEx::uint64_tAtPut(JVMFlagsWithType flag, uint64_t value, JVMFlag::Flags origin) { 1285 JVMFlag* faddr = address_of_flag(flag); 1286 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); 1287 return JVMFlag::uint64_tAtPut(faddr, &value, origin); 1288 } 1289 1290 JVMFlag::Error JVMFlag::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) { 1291 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1292 if (result == NULL) return JVMFlag::INVALID_FLAG; 1293 if (!result->is_size_t()) return JVMFlag::WRONG_FORMAT; 1294 *value = result->get_size_t(); 1295 return JVMFlag::SUCCESS; 1296 } 1297 1298 static JVMFlag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose) { 1299 JVMFlag::Error status = JVMFlag::SUCCESS; 1300 JVMFlagRange* range = JVMFlagRangeList::find(name); 1301 if (range != NULL) { 1302 status = range->check_size_t(new_value, verbose); 1303 } 1304 if (status == JVMFlag::SUCCESS) { 1305 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1306 if (constraint != NULL) { 1307 status = constraint->apply_size_t(new_value, verbose); 1308 } 1309 } 1310 return status; 1311 } 1312 1313 1314 JVMFlag::Error JVMFlag::size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin) { 1315 const char* name; 1316 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1317 if (!flag->is_size_t()) return JVMFlag::WRONG_FORMAT; 1318 name = flag->_name; 1319 JVMFlag::Error check = apply_constraint_and_check_range_size_t(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1320 if (check != JVMFlag::SUCCESS) return check; 1321 size_t old_value = flag->get_size_t(); 1322 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1323 check = flag->set_size_t(*value); 1324 *value = old_value; 1325 flag->set_origin(origin); 1326 return check; 1327 } 1328 1329 JVMFlag::Error JVMFlag::size_tAtPut(const char* name, size_t len, size_t* value, JVMFlag::Flags origin) { 1330 JVMFlag* result = JVMFlag::find_flag(name, len); 1331 return size_tAtPut(result, value, origin); 1332 } 1333 1334 JVMFlag::Error JVMFlagEx::size_tAtPut(JVMFlagsWithType flag, size_t value, JVMFlag::Flags origin) { 1335 JVMFlag* faddr = address_of_flag(flag); 1336 guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type"); 1337 return JVMFlag::size_tAtPut(faddr, &value, origin); 1338 } 1339 1340 JVMFlag::Error JVMFlag::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) { 1341 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1342 if (result == NULL) return JVMFlag::INVALID_FLAG; 1343 if (!result->is_double()) return JVMFlag::WRONG_FORMAT; 1344 *value = result->get_double(); 1345 return JVMFlag::SUCCESS; 1346 } 1347 1348 static JVMFlag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose) { 1349 JVMFlag::Error status = JVMFlag::SUCCESS; 1350 JVMFlagRange* range = JVMFlagRangeList::find(name); 1351 if (range != NULL) { 1352 status = range->check_double(new_value, verbose); 1353 } 1354 if (status == JVMFlag::SUCCESS) { 1355 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1356 if (constraint != NULL) { 1357 status = constraint->apply_double(new_value, verbose); 1358 } 1359 } 1360 return status; 1361 } 1362 1363 JVMFlag::Error JVMFlag::doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin) { 1364 const char* name; 1365 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1366 if (!flag->is_double()) return JVMFlag::WRONG_FORMAT; 1367 name = flag->_name; 1368 JVMFlag::Error check = apply_constraint_and_check_range_double(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1369 if (check != JVMFlag::SUCCESS) return check; 1370 double old_value = flag->get_double(); 1371 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin); 1372 check = flag->set_double(*value); 1373 *value = old_value; 1374 flag->set_origin(origin); 1375 return check; 1376 } 1377 1378 JVMFlag::Error JVMFlag::doubleAtPut(const char* name, size_t len, double* value, JVMFlag::Flags origin) { 1379 JVMFlag* result = JVMFlag::find_flag(name, len); 1380 return doubleAtPut(result, value, origin); 1381 } 1382 1383 JVMFlag::Error JVMFlagEx::doubleAtPut(JVMFlagsWithType flag, double value, JVMFlag::Flags origin) { 1384 JVMFlag* faddr = address_of_flag(flag); 1385 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); 1386 return JVMFlag::doubleAtPut(faddr, &value, origin); 1387 } 1388 1389 JVMFlag::Error JVMFlag::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) { 1390 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1391 if (result == NULL) return JVMFlag::INVALID_FLAG; 1392 if (!result->is_ccstr()) return JVMFlag::WRONG_FORMAT; 1393 *value = result->get_ccstr(); 1394 return JVMFlag::SUCCESS; 1395 } 1396 1397 JVMFlag::Error JVMFlag::ccstrAtPut(const char* name, size_t len, ccstr* value, JVMFlag::Flags origin) { 1398 JVMFlag* result = JVMFlag::find_flag(name, len); 1399 if (result == NULL) return JVMFlag::INVALID_FLAG; 1400 if (!result->is_ccstr()) return JVMFlag::WRONG_FORMAT; 1401 ccstr old_value = result->get_ccstr(); 1402 trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin); 1403 char* new_value = NULL; 1404 if (*value != NULL) { 1405 new_value = os::strdup_check_oom(*value); 1406 } 1407 JVMFlag::Error check = result->set_ccstr(new_value); 1408 if (result->is_default() && old_value != NULL) { 1409 // Prior value is NOT heap allocated, but was a literal constant. 1410 old_value = os::strdup_check_oom(old_value); 1411 } 1412 *value = old_value; 1413 result->set_origin(origin); 1414 return check; 1415 } 1416 1417 JVMFlag::Error JVMFlagEx::ccstrAtPut(JVMFlagsWithType flag, ccstr value, JVMFlag::Flags origin) { 1418 JVMFlag* faddr = address_of_flag(flag); 1419 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); 1420 ccstr old_value = faddr->get_ccstr(); 1421 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin); 1422 char* new_value = os::strdup_check_oom(value); 1423 JVMFlag::Error check = faddr->set_ccstr(new_value); 1424 if (!faddr->is_default() && old_value != NULL) { 1425 // Prior value is heap allocated so free it. 1426 FREE_C_HEAP_ARRAY(char, old_value); 1427 } 1428 faddr->set_origin(origin); 1429 return check; 1430 } 1431 1432 extern "C" { 1433 static int compare_flags(const void* void_a, const void* void_b) { 1434 return strcmp((*((JVMFlag**) void_a))->_name, (*((JVMFlag**) void_b))->_name); 1435 } 1436 } 1437 1438 void JVMFlag::printSetFlags(outputStream* out) { 1439 // Print which flags were set on the command line 1440 // note: this method is called before the thread structure is in place 1441 // which means resource allocation cannot be used. 1442 1443 // The last entry is the null entry. 1444 const size_t length = JVMFlag::numFlags - 1; 1445 1446 // Sort 1447 JVMFlag** array = NEW_C_HEAP_ARRAY(JVMFlag*, length, mtArguments); 1448 for (size_t i = 0; i < length; i++) { 1449 array[i] = &flagTable[i]; 1450 } 1451 qsort(array, length, sizeof(JVMFlag*), compare_flags); 1452 1453 // Print 1454 for (size_t i = 0; i < length; i++) { 1455 if (array[i]->get_origin() /* naked field! */) { 1456 array[i]->print_as_flag(out); 1457 out->print(" "); 1458 } 1459 } 1460 out->cr(); 1461 FREE_C_HEAP_ARRAY(JVMFlag*, array); 1462 } 1463 1464 #ifndef PRODUCT 1465 1466 void JVMFlag::verify() { 1467 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); 1468 } 1469 1470 #endif // PRODUCT 1471 1472 void JVMFlag::printFlags(outputStream* out, bool withComments, bool printRanges, bool skipDefaults) { 1473 // Print the flags sorted by name 1474 // note: this method is called before the thread structure is in place 1475 // which means resource allocation cannot be used. 1476 1477 // The last entry is the null entry. 1478 const size_t length = JVMFlag::numFlags - 1; 1479 1480 // Sort 1481 JVMFlag** array = NEW_C_HEAP_ARRAY(JVMFlag*, length, mtArguments); 1482 for (size_t i = 0; i < length; i++) { 1483 array[i] = &flagTable[i]; 1484 } 1485 qsort(array, length, sizeof(JVMFlag*), compare_flags); 1486 1487 // Print 1488 if (!printRanges) { 1489 out->print_cr("[Global flags]"); 1490 } else { 1491 out->print_cr("[Global flags ranges]"); 1492 } 1493 1494 for (size_t i = 0; i < length; i++) { 1495 if (array[i]->is_unlocked() && !(skipDefaults && array[i]->is_default())) { 1496 array[i]->print_on(out, withComments, printRanges); 1497 } 1498 } 1499 FREE_C_HEAP_ARRAY(JVMFlag*, array); 1500 } 1501 1502 void JVMFlag::printError(bool verbose, const char* msg, ...) { 1503 if (verbose) { 1504 va_list listPointer; 1505 va_start(listPointer, msg); 1506 jio_vfprintf(defaultStream::error_stream(), msg, listPointer); 1507 va_end(listPointer); 1508 } 1509 } 1510