1 /* 2 * Copyright (c) 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 RUNTIME_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 RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 833 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 834 RUNTIME_PRODUCT_FLAG_STRUCT, \ 835 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 836 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 837 RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \ 838 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 839 IGNORE_RANGE, \ 840 IGNORE_CONSTRAINT, \ 841 IGNORE_WRITEABLE) 842 #if INCLUDE_ALL_GCS 843 G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ 844 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ 845 RUNTIME_PRODUCT_FLAG_STRUCT, \ 846 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ 847 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ 848 RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \ 849 RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \ 850 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ 851 RUNTIME_MANAGEABLE_FLAG_STRUCT, \ 852 RUNTIME_PRODUCT_RW_FLAG_STRUCT, \ 853 IGNORE_RANGE, \ 854 IGNORE_CONSTRAINT, \ 855 IGNORE_WRITEABLE) 856 #endif // INCLUDE_ALL_GCS 857 #if INCLUDE_JVMCI 858 JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \ 859 JVMCI_PD_DEVELOP_FLAG_STRUCT, \ 860 JVMCI_PRODUCT_FLAG_STRUCT, \ 861 JVMCI_PD_PRODUCT_FLAG_STRUCT, \ 862 JVMCI_DIAGNOSTIC_FLAG_STRUCT, \ 863 JVMCI_PD_DIAGNOSTIC_FLAG_STRUCT, \ 864 JVMCI_EXPERIMENTAL_FLAG_STRUCT, \ 865 JVMCI_NOTPRODUCT_FLAG_STRUCT, \ 866 IGNORE_RANGE, \ 867 IGNORE_CONSTRAINT, \ 868 IGNORE_WRITEABLE) 869 #endif // INCLUDE_JVMCI 870 #ifdef COMPILER1 871 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \ 872 C1_PD_DEVELOP_FLAG_STRUCT, \ 873 C1_PRODUCT_FLAG_STRUCT, \ 874 C1_PD_PRODUCT_FLAG_STRUCT, \ 875 C1_DIAGNOSTIC_FLAG_STRUCT, \ 876 C1_PD_DIAGNOSTIC_FLAG_STRUCT, \ 877 C1_NOTPRODUCT_FLAG_STRUCT, \ 878 IGNORE_RANGE, \ 879 IGNORE_CONSTRAINT, \ 880 IGNORE_WRITEABLE) 881 #endif // COMPILER1 882 #ifdef COMPILER2 883 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \ 884 C2_PD_DEVELOP_FLAG_STRUCT, \ 885 C2_PRODUCT_FLAG_STRUCT, \ 886 C2_PD_PRODUCT_FLAG_STRUCT, \ 887 C2_DIAGNOSTIC_FLAG_STRUCT, \ 888 C2_PD_DIAGNOSTIC_FLAG_STRUCT, \ 889 C2_EXPERIMENTAL_FLAG_STRUCT, \ 890 C2_NOTPRODUCT_FLAG_STRUCT, \ 891 IGNORE_RANGE, \ 892 IGNORE_CONSTRAINT, \ 893 IGNORE_WRITEABLE) 894 #endif // COMPILER2 895 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \ 896 ARCH_PRODUCT_FLAG_STRUCT, \ 897 ARCH_DIAGNOSTIC_FLAG_STRUCT, \ 898 ARCH_EXPERIMENTAL_FLAG_STRUCT, \ 899 ARCH_NOTPRODUCT_FLAG_STRUCT, \ 900 IGNORE_RANGE, \ 901 IGNORE_CONSTRAINT, \ 902 IGNORE_WRITEABLE) 903 FLAGTABLE_EXT 904 {0, NULL, NULL} 905 }; 906 907 JVMFlag* JVMFlag::flags = flagTable; 908 size_t JVMFlag::numFlags = (sizeof(flagTable) / sizeof(JVMFlag)); 909 910 inline bool str_equal(const char* s, size_t s_len, const char* q, size_t q_len) { 911 if (s_len != q_len) return false; 912 return memcmp(s, q, q_len) == 0; 913 } 914 915 // Search the flag table for a named flag 916 JVMFlag* JVMFlag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) { 917 for (JVMFlag* current = &flagTable[0]; current->_name != NULL; current++) { 918 if (str_equal(current->_name, current->get_name_length(), name, length)) { 919 // Found a matching entry. 920 // Don't report notproduct and develop flags in product builds. 921 if (current->is_constant_in_binary()) { 922 return (return_flag ? current : NULL); 923 } 924 // Report locked flags only if allowed. 925 if (!(current->is_unlocked() || current->is_unlocker())) { 926 if (!allow_locked) { 927 // disable use of locked flags, e.g. diagnostic, experimental, 928 // commercial... until they are explicitly unlocked 929 return NULL; 930 } 931 } 932 return current; 933 } 934 } 935 // JVMFlag name is not in the flag table 936 return NULL; 937 } 938 939 // Get or compute the flag name length 940 size_t JVMFlag::get_name_length() { 941 if (_name_len == 0) { 942 _name_len = strlen(_name); 943 } 944 return _name_len; 945 } 946 947 JVMFlag* JVMFlag::fuzzy_match(const char* name, size_t length, bool allow_locked) { 948 float VMOptionsFuzzyMatchSimilarity = 0.7f; 949 JVMFlag* match = NULL; 950 float score; 951 float max_score = -1; 952 953 for (JVMFlag* current = &flagTable[0]; current->_name != NULL; current++) { 954 score = StringUtils::similarity(current->_name, strlen(current->_name), name, length); 955 if (score > max_score) { 956 max_score = score; 957 match = current; 958 } 959 } 960 961 if (!(match->is_unlocked() || match->is_unlocker())) { 962 if (!allow_locked) { 963 return NULL; 964 } 965 } 966 967 if (max_score < VMOptionsFuzzyMatchSimilarity) { 968 return NULL; 969 } 970 971 return match; 972 } 973 974 // Returns the address of the index'th element 975 static JVMFlag* address_of_flag(JVMFlagsWithType flag) { 976 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 977 return &JVMFlag::flags[flag]; 978 } 979 980 bool JVMFlagEx::is_default(JVMFlags flag) { 981 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 982 JVMFlag* f = &JVMFlag::flags[flag]; 983 return f->is_default(); 984 } 985 986 bool JVMFlagEx::is_ergo(JVMFlags flag) { 987 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 988 JVMFlag* f = &JVMFlag::flags[flag]; 989 return f->is_ergonomic(); 990 } 991 992 bool JVMFlagEx::is_cmdline(JVMFlags flag) { 993 assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); 994 JVMFlag* f = &JVMFlag::flags[flag]; 995 return f->is_command_line(); 996 } 997 998 bool JVMFlag::wasSetOnCmdline(const char* name, bool* value) { 999 JVMFlag* result = JVMFlag::find_flag((char*)name, strlen(name)); 1000 if (result == NULL) return false; 1001 *value = result->is_command_line(); 1002 return true; 1003 } 1004 1005 void JVMFlagEx::setOnCmdLine(JVMFlagsWithType flag) { 1006 JVMFlag* faddr = address_of_flag(flag); 1007 assert(faddr != NULL, "Unknown flag"); 1008 faddr->set_command_line(); 1009 } 1010 1011 template<class E, class T> 1012 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const JVMFlag::Flags origin) { 1013 E e; 1014 e.set_name(name); 1015 e.set_oldValue(old_value); 1016 e.set_newValue(new_value); 1017 e.set_origin(origin); 1018 e.commit(); 1019 } 1020 1021 static JVMFlag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose) { 1022 JVMFlag::Error status = JVMFlag::SUCCESS; 1023 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1024 if (constraint != NULL) { 1025 status = constraint->apply_bool(new_value, verbose); 1026 } 1027 return status; 1028 } 1029 1030 JVMFlag::Error JVMFlag::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) { 1031 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1032 if (result == NULL) return JVMFlag::INVALID_FLAG; 1033 if (!result->is_bool()) return JVMFlag::WRONG_FORMAT; 1034 *value = result->get_bool(); 1035 return JVMFlag::SUCCESS; 1036 } 1037 1038 JVMFlag::Error JVMFlag::boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin) { 1039 const char* name; 1040 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1041 if (!flag->is_bool()) return JVMFlag::WRONG_FORMAT; 1042 name = flag->_name; 1043 JVMFlag::Error check = apply_constraint_and_check_range_bool(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1044 if (check != JVMFlag::SUCCESS) return check; 1045 bool old_value = flag->get_bool(); 1046 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin); 1047 check = flag->set_bool(*value); 1048 *value = old_value; 1049 flag->set_origin(origin); 1050 return check; 1051 } 1052 1053 JVMFlag::Error JVMFlag::boolAtPut(const char* name, size_t len, bool* value, JVMFlag::Flags origin) { 1054 JVMFlag* result = JVMFlag::find_flag(name, len); 1055 return boolAtPut(result, value, origin); 1056 } 1057 1058 JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsWithType flag, bool value, JVMFlag::Flags origin) { 1059 JVMFlag* faddr = address_of_flag(flag); 1060 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); 1061 return JVMFlag::boolAtPut(faddr, &value, origin); 1062 } 1063 1064 static JVMFlag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose) { 1065 JVMFlag::Error status = JVMFlag::SUCCESS; 1066 JVMFlagRange* range = JVMFlagRangeList::find(name); 1067 if (range != NULL) { 1068 status = range->check_int(new_value, verbose); 1069 } 1070 if (status == JVMFlag::SUCCESS) { 1071 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1072 if (constraint != NULL) { 1073 status = constraint->apply_int(new_value, verbose); 1074 } 1075 } 1076 return status; 1077 } 1078 1079 JVMFlag::Error JVMFlag::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) { 1080 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1081 if (result == NULL) return JVMFlag::INVALID_FLAG; 1082 if (!result->is_int()) return JVMFlag::WRONG_FORMAT; 1083 *value = result->get_int(); 1084 return JVMFlag::SUCCESS; 1085 } 1086 1087 JVMFlag::Error JVMFlag::intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin) { 1088 const char* name; 1089 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1090 if (!flag->is_int()) return JVMFlag::WRONG_FORMAT; 1091 name = flag->_name; 1092 JVMFlag::Error check = apply_constraint_and_check_range_int(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1093 if (check != JVMFlag::SUCCESS) return check; 1094 int old_value = flag->get_int(); 1095 trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin); 1096 check = flag->set_int(*value); 1097 *value = old_value; 1098 flag->set_origin(origin); 1099 return check; 1100 } 1101 1102 JVMFlag::Error JVMFlag::intAtPut(const char* name, size_t len, int* value, JVMFlag::Flags origin) { 1103 JVMFlag* result = JVMFlag::find_flag(name, len); 1104 return intAtPut(result, value, origin); 1105 } 1106 1107 JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsWithType flag, int value, JVMFlag::Flags origin) { 1108 JVMFlag* faddr = address_of_flag(flag); 1109 guarantee(faddr != NULL && faddr->is_int(), "wrong flag type"); 1110 return JVMFlag::intAtPut(faddr, &value, origin); 1111 } 1112 1113 static JVMFlag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose) { 1114 JVMFlag::Error status = JVMFlag::SUCCESS; 1115 JVMFlagRange* range = JVMFlagRangeList::find(name); 1116 if (range != NULL) { 1117 status = range->check_uint(new_value, verbose); 1118 } 1119 if (status == JVMFlag::SUCCESS) { 1120 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1121 if (constraint != NULL) { 1122 status = constraint->apply_uint(new_value, verbose); 1123 } 1124 } 1125 return status; 1126 } 1127 1128 JVMFlag::Error JVMFlag::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) { 1129 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1130 if (result == NULL) return JVMFlag::INVALID_FLAG; 1131 if (!result->is_uint()) return JVMFlag::WRONG_FORMAT; 1132 *value = result->get_uint(); 1133 return JVMFlag::SUCCESS; 1134 } 1135 1136 JVMFlag::Error JVMFlag::uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin) { 1137 const char* name; 1138 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1139 if (!flag->is_uint()) return JVMFlag::WRONG_FORMAT; 1140 name = flag->_name; 1141 JVMFlag::Error check = apply_constraint_and_check_range_uint(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1142 if (check != JVMFlag::SUCCESS) return check; 1143 uint old_value = flag->get_uint(); 1144 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin); 1145 check = flag->set_uint(*value); 1146 *value = old_value; 1147 flag->set_origin(origin); 1148 return check; 1149 } 1150 1151 JVMFlag::Error JVMFlag::uintAtPut(const char* name, size_t len, uint* value, JVMFlag::Flags origin) { 1152 JVMFlag* result = JVMFlag::find_flag(name, len); 1153 return uintAtPut(result, value, origin); 1154 } 1155 1156 JVMFlag::Error JVMFlagEx::uintAtPut(JVMFlagsWithType flag, uint value, JVMFlag::Flags origin) { 1157 JVMFlag* faddr = address_of_flag(flag); 1158 guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type"); 1159 return JVMFlag::uintAtPut(faddr, &value, origin); 1160 } 1161 1162 JVMFlag::Error JVMFlag::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) { 1163 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1164 if (result == NULL) return JVMFlag::INVALID_FLAG; 1165 if (!result->is_intx()) return JVMFlag::WRONG_FORMAT; 1166 *value = result->get_intx(); 1167 return JVMFlag::SUCCESS; 1168 } 1169 1170 static JVMFlag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose) { 1171 JVMFlag::Error status = JVMFlag::SUCCESS; 1172 JVMFlagRange* range = JVMFlagRangeList::find(name); 1173 if (range != NULL) { 1174 status = range->check_intx(new_value, verbose); 1175 } 1176 if (status == JVMFlag::SUCCESS) { 1177 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1178 if (constraint != NULL) { 1179 status = constraint->apply_intx(new_value, verbose); 1180 } 1181 } 1182 return status; 1183 } 1184 1185 JVMFlag::Error JVMFlag::intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin) { 1186 const char* name; 1187 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1188 if (!flag->is_intx()) return JVMFlag::WRONG_FORMAT; 1189 name = flag->_name; 1190 JVMFlag::Error check = apply_constraint_and_check_range_intx(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1191 if (check != JVMFlag::SUCCESS) return check; 1192 intx old_value = flag->get_intx(); 1193 trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin); 1194 check = flag->set_intx(*value); 1195 *value = old_value; 1196 flag->set_origin(origin); 1197 return check; 1198 } 1199 1200 JVMFlag::Error JVMFlag::intxAtPut(const char* name, size_t len, intx* value, JVMFlag::Flags origin) { 1201 JVMFlag* result = JVMFlag::find_flag(name, len); 1202 return intxAtPut(result, value, origin); 1203 } 1204 1205 JVMFlag::Error JVMFlagEx::intxAtPut(JVMFlagsWithType flag, intx value, JVMFlag::Flags origin) { 1206 JVMFlag* faddr = address_of_flag(flag); 1207 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); 1208 return JVMFlag::intxAtPut(faddr, &value, origin); 1209 } 1210 1211 JVMFlag::Error JVMFlag::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) { 1212 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1213 if (result == NULL) return JVMFlag::INVALID_FLAG; 1214 if (!result->is_uintx()) return JVMFlag::WRONG_FORMAT; 1215 *value = result->get_uintx(); 1216 return JVMFlag::SUCCESS; 1217 } 1218 1219 static JVMFlag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose) { 1220 JVMFlag::Error status = JVMFlag::SUCCESS; 1221 JVMFlagRange* range = JVMFlagRangeList::find(name); 1222 if (range != NULL) { 1223 status = range->check_uintx(new_value, verbose); 1224 } 1225 if (status == JVMFlag::SUCCESS) { 1226 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1227 if (constraint != NULL) { 1228 status = constraint->apply_uintx(new_value, verbose); 1229 } 1230 } 1231 return status; 1232 } 1233 1234 JVMFlag::Error JVMFlag::uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin) { 1235 const char* name; 1236 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1237 if (!flag->is_uintx()) return JVMFlag::WRONG_FORMAT; 1238 name = flag->_name; 1239 JVMFlag::Error check = apply_constraint_and_check_range_uintx(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1240 if (check != JVMFlag::SUCCESS) return check; 1241 uintx old_value = flag->get_uintx(); 1242 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1243 check = flag->set_uintx(*value); 1244 *value = old_value; 1245 flag->set_origin(origin); 1246 return check; 1247 } 1248 1249 JVMFlag::Error JVMFlag::uintxAtPut(const char* name, size_t len, uintx* value, JVMFlag::Flags origin) { 1250 JVMFlag* result = JVMFlag::find_flag(name, len); 1251 return uintxAtPut(result, value, origin); 1252 } 1253 1254 JVMFlag::Error JVMFlagEx::uintxAtPut(JVMFlagsWithType flag, uintx value, JVMFlag::Flags origin) { 1255 JVMFlag* faddr = address_of_flag(flag); 1256 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); 1257 return JVMFlag::uintxAtPut(faddr, &value, origin); 1258 } 1259 1260 JVMFlag::Error JVMFlag::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) { 1261 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1262 if (result == NULL) return JVMFlag::INVALID_FLAG; 1263 if (!result->is_uint64_t()) return JVMFlag::WRONG_FORMAT; 1264 *value = result->get_uint64_t(); 1265 return JVMFlag::SUCCESS; 1266 } 1267 1268 static JVMFlag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose) { 1269 JVMFlag::Error status = JVMFlag::SUCCESS; 1270 JVMFlagRange* range = JVMFlagRangeList::find(name); 1271 if (range != NULL) { 1272 status = range->check_uint64_t(new_value, verbose); 1273 } 1274 if (status == JVMFlag::SUCCESS) { 1275 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1276 if (constraint != NULL) { 1277 status = constraint->apply_uint64_t(new_value, verbose); 1278 } 1279 } 1280 return status; 1281 } 1282 1283 JVMFlag::Error JVMFlag::uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin) { 1284 const char* name; 1285 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1286 if (!flag->is_uint64_t()) return JVMFlag::WRONG_FORMAT; 1287 name = flag->_name; 1288 JVMFlag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1289 if (check != JVMFlag::SUCCESS) return check; 1290 uint64_t old_value = flag->get_uint64_t(); 1291 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1292 check = flag->set_uint64_t(*value); 1293 *value = old_value; 1294 flag->set_origin(origin); 1295 return check; 1296 } 1297 1298 JVMFlag::Error JVMFlag::uint64_tAtPut(const char* name, size_t len, uint64_t* value, JVMFlag::Flags origin) { 1299 JVMFlag* result = JVMFlag::find_flag(name, len); 1300 return uint64_tAtPut(result, value, origin); 1301 } 1302 1303 JVMFlag::Error JVMFlagEx::uint64_tAtPut(JVMFlagsWithType flag, uint64_t value, JVMFlag::Flags origin) { 1304 JVMFlag* faddr = address_of_flag(flag); 1305 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); 1306 return JVMFlag::uint64_tAtPut(faddr, &value, origin); 1307 } 1308 1309 JVMFlag::Error JVMFlag::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) { 1310 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1311 if (result == NULL) return JVMFlag::INVALID_FLAG; 1312 if (!result->is_size_t()) return JVMFlag::WRONG_FORMAT; 1313 *value = result->get_size_t(); 1314 return JVMFlag::SUCCESS; 1315 } 1316 1317 static JVMFlag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose) { 1318 JVMFlag::Error status = JVMFlag::SUCCESS; 1319 JVMFlagRange* range = JVMFlagRangeList::find(name); 1320 if (range != NULL) { 1321 status = range->check_size_t(new_value, verbose); 1322 } 1323 if (status == JVMFlag::SUCCESS) { 1324 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1325 if (constraint != NULL) { 1326 status = constraint->apply_size_t(new_value, verbose); 1327 } 1328 } 1329 return status; 1330 } 1331 1332 1333 JVMFlag::Error JVMFlag::size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin) { 1334 const char* name; 1335 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1336 if (!flag->is_size_t()) return JVMFlag::WRONG_FORMAT; 1337 name = flag->_name; 1338 JVMFlag::Error check = apply_constraint_and_check_range_size_t(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1339 if (check != JVMFlag::SUCCESS) return check; 1340 size_t old_value = flag->get_size_t(); 1341 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); 1342 check = flag->set_size_t(*value); 1343 *value = old_value; 1344 flag->set_origin(origin); 1345 return check; 1346 } 1347 1348 JVMFlag::Error JVMFlag::size_tAtPut(const char* name, size_t len, size_t* value, JVMFlag::Flags origin) { 1349 JVMFlag* result = JVMFlag::find_flag(name, len); 1350 return size_tAtPut(result, value, origin); 1351 } 1352 1353 JVMFlag::Error JVMFlagEx::size_tAtPut(JVMFlagsWithType flag, size_t value, JVMFlag::Flags origin) { 1354 JVMFlag* faddr = address_of_flag(flag); 1355 guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type"); 1356 return JVMFlag::size_tAtPut(faddr, &value, origin); 1357 } 1358 1359 JVMFlag::Error JVMFlag::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) { 1360 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1361 if (result == NULL) return JVMFlag::INVALID_FLAG; 1362 if (!result->is_double()) return JVMFlag::WRONG_FORMAT; 1363 *value = result->get_double(); 1364 return JVMFlag::SUCCESS; 1365 } 1366 1367 static JVMFlag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose) { 1368 JVMFlag::Error status = JVMFlag::SUCCESS; 1369 JVMFlagRange* range = JVMFlagRangeList::find(name); 1370 if (range != NULL) { 1371 status = range->check_double(new_value, verbose); 1372 } 1373 if (status == JVMFlag::SUCCESS) { 1374 JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name); 1375 if (constraint != NULL) { 1376 status = constraint->apply_double(new_value, verbose); 1377 } 1378 } 1379 return status; 1380 } 1381 1382 JVMFlag::Error JVMFlag::doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin) { 1383 const char* name; 1384 if (flag == NULL) return JVMFlag::INVALID_FLAG; 1385 if (!flag->is_double()) return JVMFlag::WRONG_FORMAT; 1386 name = flag->_name; 1387 JVMFlag::Error check = apply_constraint_and_check_range_double(name, *value, !JVMFlagConstraintList::validated_after_ergo()); 1388 if (check != JVMFlag::SUCCESS) return check; 1389 double old_value = flag->get_double(); 1390 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin); 1391 check = flag->set_double(*value); 1392 *value = old_value; 1393 flag->set_origin(origin); 1394 return check; 1395 } 1396 1397 JVMFlag::Error JVMFlag::doubleAtPut(const char* name, size_t len, double* value, JVMFlag::Flags origin) { 1398 JVMFlag* result = JVMFlag::find_flag(name, len); 1399 return doubleAtPut(result, value, origin); 1400 } 1401 1402 JVMFlag::Error JVMFlagEx::doubleAtPut(JVMFlagsWithType flag, double value, JVMFlag::Flags origin) { 1403 JVMFlag* faddr = address_of_flag(flag); 1404 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); 1405 return JVMFlag::doubleAtPut(faddr, &value, origin); 1406 } 1407 1408 JVMFlag::Error JVMFlag::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) { 1409 JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag); 1410 if (result == NULL) return JVMFlag::INVALID_FLAG; 1411 if (!result->is_ccstr()) return JVMFlag::WRONG_FORMAT; 1412 *value = result->get_ccstr(); 1413 return JVMFlag::SUCCESS; 1414 } 1415 1416 JVMFlag::Error JVMFlag::ccstrAtPut(const char* name, size_t len, ccstr* value, JVMFlag::Flags origin) { 1417 JVMFlag* result = JVMFlag::find_flag(name, len); 1418 if (result == NULL) return JVMFlag::INVALID_FLAG; 1419 if (!result->is_ccstr()) return JVMFlag::WRONG_FORMAT; 1420 ccstr old_value = result->get_ccstr(); 1421 trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin); 1422 char* new_value = NULL; 1423 if (*value != NULL) { 1424 new_value = os::strdup_check_oom(*value); 1425 } 1426 JVMFlag::Error check = result->set_ccstr(new_value); 1427 if (result->is_default() && old_value != NULL) { 1428 // Prior value is NOT heap allocated, but was a literal constant. 1429 old_value = os::strdup_check_oom(old_value); 1430 } 1431 *value = old_value; 1432 result->set_origin(origin); 1433 return check; 1434 } 1435 1436 JVMFlag::Error JVMFlagEx::ccstrAtPut(JVMFlagsWithType flag, ccstr value, JVMFlag::Flags origin) { 1437 JVMFlag* faddr = address_of_flag(flag); 1438 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); 1439 ccstr old_value = faddr->get_ccstr(); 1440 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin); 1441 char* new_value = os::strdup_check_oom(value); 1442 JVMFlag::Error check = faddr->set_ccstr(new_value); 1443 if (!faddr->is_default() && old_value != NULL) { 1444 // Prior value is heap allocated so free it. 1445 FREE_C_HEAP_ARRAY(char, old_value); 1446 } 1447 faddr->set_origin(origin); 1448 return check; 1449 } 1450 1451 extern "C" { 1452 static int compare_flags(const void* void_a, const void* void_b) { 1453 return strcmp((*((JVMFlag**) void_a))->_name, (*((JVMFlag**) void_b))->_name); 1454 } 1455 } 1456 1457 void JVMFlag::printSetFlags(outputStream* out) { 1458 // Print which flags were set on the command line 1459 // note: this method is called before the thread structure is in place 1460 // which means resource allocation cannot be used. 1461 1462 // The last entry is the null entry. 1463 const size_t length = JVMFlag::numFlags - 1; 1464 1465 // Sort 1466 JVMFlag** array = NEW_C_HEAP_ARRAY(JVMFlag*, length, mtArguments); 1467 for (size_t i = 0; i < length; i++) { 1468 array[i] = &flagTable[i]; 1469 } 1470 qsort(array, length, sizeof(JVMFlag*), compare_flags); 1471 1472 // Print 1473 for (size_t i = 0; i < length; i++) { 1474 if (array[i]->get_origin() /* naked field! */) { 1475 array[i]->print_as_flag(out); 1476 out->print(" "); 1477 } 1478 } 1479 out->cr(); 1480 FREE_C_HEAP_ARRAY(JVMFlag*, array); 1481 } 1482 1483 #ifndef PRODUCT 1484 1485 void JVMFlag::verify() { 1486 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); 1487 } 1488 1489 #endif // PRODUCT 1490 1491 void JVMFlag::printFlags(outputStream* out, bool withComments, bool printRanges) { 1492 // Print the flags sorted by name 1493 // note: this method is called before the thread structure is in place 1494 // which means resource allocation cannot be used. 1495 1496 // The last entry is the null entry. 1497 const size_t length = JVMFlag::numFlags - 1; 1498 1499 // Sort 1500 JVMFlag** array = NEW_C_HEAP_ARRAY(JVMFlag*, length, mtArguments); 1501 for (size_t i = 0; i < length; i++) { 1502 array[i] = &flagTable[i]; 1503 } 1504 qsort(array, length, sizeof(JVMFlag*), compare_flags); 1505 1506 // Print 1507 if (!printRanges) { 1508 out->print_cr("[Global flags]"); 1509 } else { 1510 out->print_cr("[Global flags ranges]"); 1511 } 1512 1513 for (size_t i = 0; i < length; i++) { 1514 if (array[i]->is_unlocked()) { 1515 array[i]->print_on(out, withComments, printRanges); 1516 } 1517 } 1518 FREE_C_HEAP_ARRAY(JVMFlag*, array); 1519 }