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