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