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