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