src/share/vm/runtime/globals.cpp

Wed, 03 Jul 2019 20:42:37 +0800

author
aoqi
date
Wed, 03 Jul 2019 20:42:37 +0800
changeset 9637
eef07cd490d4
parent 7535
7ae4e26cb1e0
child 9931
fd44df5e3bc3
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "memory/allocation.inline.hpp"
aoqi@0 27 #include "oops/oop.inline.hpp"
aoqi@0 28 #include "runtime/arguments.hpp"
aoqi@0 29 #include "runtime/globals.hpp"
aoqi@0 30 #include "runtime/globals_extension.hpp"
aoqi@0 31 #include "utilities/ostream.hpp"
aoqi@0 32 #include "utilities/macros.hpp"
aoqi@0 33 #include "utilities/top.hpp"
aoqi@0 34 #include "trace/tracing.hpp"
aoqi@0 35 #if INCLUDE_ALL_GCS
aoqi@0 36 #include "gc_implementation/g1/g1_globals.hpp"
aoqi@0 37 #endif // INCLUDE_ALL_GCS
aoqi@0 38 #ifdef COMPILER1
aoqi@0 39 #include "c1/c1_globals.hpp"
aoqi@0 40 #endif
aoqi@0 41 #ifdef COMPILER2
aoqi@0 42 #include "opto/c2_globals.hpp"
aoqi@0 43 #endif
aoqi@0 44 #ifdef SHARK
aoqi@0 45 #include "shark/shark_globals.hpp"
aoqi@0 46 #endif
aoqi@0 47
aoqi@0 48 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
aoqi@0 49
aoqi@0 50 RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
aoqi@0 51 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
aoqi@0 52 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
aoqi@0 53 MATERIALIZE_NOTPRODUCT_FLAG, \
aoqi@0 54 MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG, \
aoqi@0 55 MATERIALIZE_LP64_PRODUCT_FLAG)
aoqi@0 56
aoqi@0 57 RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
aoqi@0 58 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
aoqi@0 59 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
aoqi@0 60
aoqi@0 61 ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \
aoqi@0 62 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
aoqi@0 63 MATERIALIZE_NOTPRODUCT_FLAG)
aoqi@0 64
aoqi@0 65 MATERIALIZE_FLAGS_EXT
aoqi@0 66
aoqi@0 67
aoqi@0 68 static bool is_product_build() {
aoqi@0 69 #ifdef PRODUCT
aoqi@0 70 return true;
aoqi@0 71 #else
aoqi@0 72 return false;
aoqi@0 73 #endif
aoqi@0 74 }
aoqi@0 75
aoqi@0 76 void Flag::check_writable() {
aoqi@0 77 if (is_constant_in_binary()) {
aoqi@0 78 fatal(err_msg("flag is constant: %s", _name));
aoqi@0 79 }
aoqi@0 80 }
aoqi@0 81
aoqi@0 82 bool Flag::is_bool() const {
aoqi@0 83 return strcmp(_type, "bool") == 0;
aoqi@0 84 }
aoqi@0 85
aoqi@0 86 bool Flag::get_bool() const {
aoqi@0 87 return *((bool*) _addr);
aoqi@0 88 }
aoqi@0 89
aoqi@0 90 void Flag::set_bool(bool value) {
aoqi@0 91 check_writable();
aoqi@0 92 *((bool*) _addr) = value;
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 bool Flag::is_intx() const {
aoqi@0 96 return strcmp(_type, "intx") == 0;
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 intx Flag::get_intx() const {
aoqi@0 100 return *((intx*) _addr);
aoqi@0 101 }
aoqi@0 102
aoqi@0 103 void Flag::set_intx(intx value) {
aoqi@0 104 check_writable();
aoqi@0 105 *((intx*) _addr) = value;
aoqi@0 106 }
aoqi@0 107
aoqi@0 108 bool Flag::is_uintx() const {
aoqi@0 109 return strcmp(_type, "uintx") == 0;
aoqi@0 110 }
aoqi@0 111
aoqi@0 112 uintx Flag::get_uintx() const {
aoqi@0 113 return *((uintx*) _addr);
aoqi@0 114 }
aoqi@0 115
aoqi@0 116 void Flag::set_uintx(uintx value) {
aoqi@0 117 check_writable();
aoqi@0 118 *((uintx*) _addr) = value;
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 bool Flag::is_uint64_t() const {
aoqi@0 122 return strcmp(_type, "uint64_t") == 0;
aoqi@0 123 }
aoqi@0 124
aoqi@0 125 uint64_t Flag::get_uint64_t() const {
aoqi@0 126 return *((uint64_t*) _addr);
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 void Flag::set_uint64_t(uint64_t value) {
aoqi@0 130 check_writable();
aoqi@0 131 *((uint64_t*) _addr) = value;
aoqi@0 132 }
aoqi@0 133
aoqi@0 134 bool Flag::is_double() const {
aoqi@0 135 return strcmp(_type, "double") == 0;
aoqi@0 136 }
aoqi@0 137
aoqi@0 138 double Flag::get_double() const {
aoqi@0 139 return *((double*) _addr);
aoqi@0 140 }
aoqi@0 141
aoqi@0 142 void Flag::set_double(double value) {
aoqi@0 143 check_writable();
aoqi@0 144 *((double*) _addr) = value;
aoqi@0 145 }
aoqi@0 146
aoqi@0 147 bool Flag::is_ccstr() const {
aoqi@0 148 return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0;
aoqi@0 149 }
aoqi@0 150
aoqi@0 151 bool Flag::ccstr_accumulates() const {
aoqi@0 152 return strcmp(_type, "ccstrlist") == 0;
aoqi@0 153 }
aoqi@0 154
aoqi@0 155 ccstr Flag::get_ccstr() const {
aoqi@0 156 return *((ccstr*) _addr);
aoqi@0 157 }
aoqi@0 158
aoqi@0 159 void Flag::set_ccstr(ccstr value) {
aoqi@0 160 check_writable();
aoqi@0 161 *((ccstr*) _addr) = value;
aoqi@0 162 }
aoqi@0 163
aoqi@0 164
aoqi@0 165 Flag::Flags Flag::get_origin() {
aoqi@0 166 return Flags(_flags & VALUE_ORIGIN_MASK);
aoqi@0 167 }
aoqi@0 168
aoqi@0 169 void Flag::set_origin(Flags origin) {
aoqi@0 170 assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity");
aoqi@0 171 _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin);
aoqi@0 172 }
aoqi@0 173
aoqi@0 174 bool Flag::is_default() {
aoqi@0 175 return (get_origin() == DEFAULT);
aoqi@0 176 }
aoqi@0 177
aoqi@0 178 bool Flag::is_ergonomic() {
aoqi@0 179 return (get_origin() == ERGONOMIC);
aoqi@0 180 }
aoqi@0 181
aoqi@0 182 bool Flag::is_command_line() {
aoqi@0 183 return (get_origin() == COMMAND_LINE);
aoqi@0 184 }
aoqi@0 185
aoqi@0 186 bool Flag::is_product() const {
aoqi@0 187 return (_flags & KIND_PRODUCT) != 0;
aoqi@0 188 }
aoqi@0 189
aoqi@0 190 bool Flag::is_manageable() const {
aoqi@0 191 return (_flags & KIND_MANAGEABLE) != 0;
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 bool Flag::is_diagnostic() const {
aoqi@0 195 return (_flags & KIND_DIAGNOSTIC) != 0;
aoqi@0 196 }
aoqi@0 197
aoqi@0 198 bool Flag::is_experimental() const {
aoqi@0 199 return (_flags & KIND_EXPERIMENTAL) != 0;
aoqi@0 200 }
aoqi@0 201
aoqi@0 202 bool Flag::is_notproduct() const {
aoqi@0 203 return (_flags & KIND_NOT_PRODUCT) != 0;
aoqi@0 204 }
aoqi@0 205
aoqi@0 206 bool Flag::is_develop() const {
aoqi@0 207 return (_flags & KIND_DEVELOP) != 0;
aoqi@0 208 }
aoqi@0 209
aoqi@0 210 bool Flag::is_read_write() const {
aoqi@0 211 return (_flags & KIND_READ_WRITE) != 0;
aoqi@0 212 }
aoqi@0 213
aoqi@0 214 bool Flag::is_commercial() const {
aoqi@0 215 return (_flags & KIND_COMMERCIAL) != 0;
aoqi@0 216 }
aoqi@0 217
aoqi@0 218 /**
aoqi@0 219 * Returns if this flag is a constant in the binary. Right now this is
aoqi@0 220 * true for notproduct and develop flags in product builds.
aoqi@0 221 */
aoqi@0 222 bool Flag::is_constant_in_binary() const {
aoqi@0 223 #ifdef PRODUCT
aoqi@0 224 return is_notproduct() || is_develop();
aoqi@0 225 #else
aoqi@0 226 return false;
aoqi@0 227 #endif
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 bool Flag::is_unlocker() const {
aoqi@0 231 return strcmp(_name, "UnlockDiagnosticVMOptions") == 0 ||
aoqi@0 232 strcmp(_name, "UnlockExperimentalVMOptions") == 0 ||
aoqi@0 233 is_unlocker_ext();
aoqi@0 234 }
aoqi@0 235
aoqi@0 236 bool Flag::is_unlocked() const {
aoqi@0 237 if (is_diagnostic()) {
aoqi@0 238 return UnlockDiagnosticVMOptions;
aoqi@0 239 }
aoqi@0 240 if (is_experimental()) {
aoqi@0 241 return UnlockExperimentalVMOptions;
aoqi@0 242 }
aoqi@0 243 return is_unlocked_ext();
aoqi@0 244 }
aoqi@0 245
jiangli@7282 246 void Flag::unlock_diagnostic() {
jiangli@7282 247 assert(is_diagnostic(), "sanity");
jiangli@7282 248 _flags = Flags(_flags & ~KIND_DIAGNOSTIC);
jiangli@7282 249 }
jiangli@7282 250
aoqi@0 251 // Get custom message for this locked flag, or return NULL if
aoqi@0 252 // none is available.
aoqi@0 253 void Flag::get_locked_message(char* buf, int buflen) const {
aoqi@0 254 buf[0] = '\0';
aoqi@0 255 if (is_diagnostic() && !is_unlocked()) {
aoqi@0 256 jio_snprintf(buf, buflen, "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n",
aoqi@0 257 _name);
aoqi@0 258 return;
aoqi@0 259 }
aoqi@0 260 if (is_experimental() && !is_unlocked()) {
aoqi@0 261 jio_snprintf(buf, buflen, "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n",
aoqi@0 262 _name);
aoqi@0 263 return;
aoqi@0 264 }
aoqi@0 265 if (is_develop() && is_product_build()) {
aoqi@0 266 jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n",
aoqi@0 267 _name);
aoqi@0 268 return;
aoqi@0 269 }
aoqi@0 270 if (is_notproduct() && is_product_build()) {
aoqi@0 271 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
aoqi@0 272 _name);
aoqi@0 273 return;
aoqi@0 274 }
aoqi@0 275 get_locked_message_ext(buf, buflen);
aoqi@0 276 }
aoqi@0 277
aoqi@0 278 bool Flag::is_writeable() const {
aoqi@0 279 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
aoqi@0 280 }
aoqi@0 281
aoqi@0 282 // All flags except "manageable" are assumed to be internal flags.
aoqi@0 283 // Long term, we need to define a mechanism to specify which flags
aoqi@0 284 // are external/stable and change this function accordingly.
aoqi@0 285 bool Flag::is_external() const {
aoqi@0 286 return is_manageable() || is_external_ext();
aoqi@0 287 }
aoqi@0 288
aoqi@0 289
aoqi@0 290 // Length of format string (e.g. "%.1234s") for printing ccstr below
aoqi@0 291 #define FORMAT_BUFFER_LEN 16
aoqi@0 292
aoqi@0 293 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
aoqi@0 294 void Flag::print_on(outputStream* st, bool withComments) {
aoqi@0 295 // Don't print notproduct and develop flags in a product build.
aoqi@0 296 if (is_constant_in_binary()) {
aoqi@0 297 return;
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
aoqi@0 301
aoqi@0 302 if (is_bool()) {
aoqi@0 303 st->print("%-16s", get_bool() ? "true" : "false");
aoqi@0 304 }
aoqi@0 305 if (is_intx()) {
aoqi@0 306 st->print("%-16ld", get_intx());
aoqi@0 307 }
aoqi@0 308 if (is_uintx()) {
aoqi@0 309 st->print("%-16lu", get_uintx());
aoqi@0 310 }
aoqi@0 311 if (is_uint64_t()) {
aoqi@0 312 st->print("%-16lu", get_uint64_t());
aoqi@0 313 }
aoqi@0 314 if (is_double()) {
aoqi@0 315 st->print("%-16f", get_double());
aoqi@0 316 }
aoqi@0 317 if (is_ccstr()) {
aoqi@0 318 const char* cp = get_ccstr();
aoqi@0 319 if (cp != NULL) {
aoqi@0 320 const char* eol;
aoqi@0 321 while ((eol = strchr(cp, '\n')) != NULL) {
aoqi@0 322 char format_buffer[FORMAT_BUFFER_LEN];
aoqi@0 323 size_t llen = pointer_delta(eol, cp, sizeof(char));
aoqi@0 324 jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
aoqi@0 325 "%%." SIZE_FORMAT "s", llen);
aoqi@0 326 PRAGMA_DIAG_PUSH
aoqi@0 327 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
aoqi@0 328 st->print(format_buffer, cp);
aoqi@0 329 PRAGMA_DIAG_POP
aoqi@0 330 st->cr();
aoqi@0 331 cp = eol+1;
aoqi@0 332 st->print("%5s %-35s += ", "", _name);
aoqi@0 333 }
aoqi@0 334 st->print("%-16s", cp);
aoqi@0 335 }
aoqi@0 336 else st->print("%-16s", "");
aoqi@0 337 }
aoqi@0 338
aoqi@0 339 st->print("%-20s", " ");
aoqi@0 340 print_kind(st);
aoqi@0 341
aoqi@0 342 if (withComments) {
aoqi@0 343 #ifndef PRODUCT
aoqi@0 344 st->print("%s", _doc);
aoqi@0 345 #endif
aoqi@0 346 }
aoqi@0 347 st->cr();
aoqi@0 348 }
aoqi@0 349
aoqi@0 350 void Flag::print_kind(outputStream* st) {
aoqi@0 351 struct Data {
aoqi@0 352 int flag;
aoqi@0 353 const char* name;
aoqi@0 354 };
aoqi@0 355
aoqi@0 356 Data data[] = {
aoqi@0 357 { KIND_C1, "C1" },
aoqi@0 358 { KIND_C2, "C2" },
aoqi@0 359 { KIND_ARCH, "ARCH" },
aoqi@0 360 { KIND_SHARK, "SHARK" },
aoqi@0 361 { KIND_PLATFORM_DEPENDENT, "pd" },
aoqi@0 362 { KIND_PRODUCT, "product" },
aoqi@0 363 { KIND_MANAGEABLE, "manageable" },
aoqi@0 364 { KIND_DIAGNOSTIC, "diagnostic" },
aoqi@0 365 { KIND_EXPERIMENTAL, "experimental" },
aoqi@0 366 { KIND_COMMERCIAL, "commercial" },
aoqi@0 367 { KIND_NOT_PRODUCT, "notproduct" },
aoqi@0 368 { KIND_DEVELOP, "develop" },
aoqi@0 369 { KIND_LP64_PRODUCT, "lp64_product" },
aoqi@0 370 { KIND_READ_WRITE, "rw" },
aoqi@0 371 { -1, "" }
aoqi@0 372 };
aoqi@0 373
aoqi@0 374 if ((_flags & KIND_MASK) != 0) {
aoqi@0 375 st->print("{");
aoqi@0 376 bool is_first = true;
aoqi@0 377
aoqi@0 378 for (int i = 0; data[i].flag != -1; i++) {
aoqi@0 379 Data d = data[i];
aoqi@0 380 if ((_flags & d.flag) != 0) {
aoqi@0 381 if (is_first) {
aoqi@0 382 is_first = false;
aoqi@0 383 } else {
aoqi@0 384 st->print(" ");
aoqi@0 385 }
aoqi@0 386 st->print("%s", d.name);
aoqi@0 387 }
aoqi@0 388 }
aoqi@0 389
aoqi@0 390 st->print("}");
aoqi@0 391 }
aoqi@0 392 }
aoqi@0 393
aoqi@0 394 void Flag::print_as_flag(outputStream* st) {
aoqi@0 395 if (is_bool()) {
aoqi@0 396 st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
aoqi@0 397 } else if (is_intx()) {
aoqi@0 398 st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
aoqi@0 399 } else if (is_uintx()) {
aoqi@0 400 st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
aoqi@0 401 } else if (is_uint64_t()) {
aoqi@0 402 st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
aoqi@0 403 } else if (is_double()) {
aoqi@0 404 st->print("-XX:%s=%f", _name, get_double());
aoqi@0 405 } else if (is_ccstr()) {
aoqi@0 406 st->print("-XX:%s=", _name);
aoqi@0 407 const char* cp = get_ccstr();
aoqi@0 408 if (cp != NULL) {
aoqi@0 409 // Need to turn embedded '\n's back into separate arguments
aoqi@0 410 // Not so efficient to print one character at a time,
aoqi@0 411 // but the choice is to do the transformation to a buffer
aoqi@0 412 // and print that. And this need not be efficient.
aoqi@0 413 for (; *cp != '\0'; cp += 1) {
aoqi@0 414 switch (*cp) {
aoqi@0 415 default:
aoqi@0 416 st->print("%c", *cp);
aoqi@0 417 break;
aoqi@0 418 case '\n':
aoqi@0 419 st->print(" -XX:%s=", _name);
aoqi@0 420 break;
aoqi@0 421 }
aoqi@0 422 }
aoqi@0 423 }
aoqi@0 424 } else {
aoqi@0 425 ShouldNotReachHere();
aoqi@0 426 }
aoqi@0 427 }
aoqi@0 428
aoqi@0 429 // 4991491 do not "optimize out" the was_set false values: omitting them
aoqi@0 430 // tickles a Microsoft compiler bug causing flagTable to be malformed
aoqi@0 431
aoqi@0 432 #define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name)
aoqi@0 433
aoqi@0 434 #define RUNTIME_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) },
aoqi@0 435 #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) },
aoqi@0 436 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) },
aoqi@0 437 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) },
aoqi@0 438 #define RUNTIME_MANAGEABLE_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) },
aoqi@0 439 #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) },
aoqi@0 440 #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) },
aoqi@0 441 #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) },
aoqi@0 442 #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) },
aoqi@0 443
aoqi@0 444 #ifdef _LP64
aoqi@0 445 #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) },
aoqi@0 446 #else
aoqi@0 447 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
aoqi@0 448 #endif // _LP64
aoqi@0 449
aoqi@0 450 #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) },
aoqi@0 451 #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) },
aoqi@0 452 #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) },
aoqi@0 453 #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) },
aoqi@0 454 #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) },
aoqi@0 455 #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) },
aoqi@0 456
aoqi@0 457 #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) },
aoqi@0 458 #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) },
aoqi@0 459 #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) },
aoqi@0 460 #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) },
aoqi@0 461 #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) },
aoqi@0 462 #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) },
aoqi@0 463 #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) },
aoqi@0 464
aoqi@0 465 #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) },
aoqi@0 466 #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) },
aoqi@0 467 #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) },
aoqi@0 468 #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) },
aoqi@0 469 #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) },
aoqi@0 470
aoqi@0 471 #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) },
aoqi@0 472 #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) },
aoqi@0 473 #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) },
aoqi@0 474 #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) },
aoqi@0 475 #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) },
aoqi@0 476 #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) },
aoqi@0 477
aoqi@0 478 static Flag flagTable[] = {
aoqi@0 479 RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
aoqi@0 480 RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT)
aoqi@0 481 #if INCLUDE_ALL_GCS
aoqi@0 482 G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT)
aoqi@0 483 #endif // INCLUDE_ALL_GCS
aoqi@0 484 #ifdef COMPILER1
aoqi@0 485 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_DIAGNOSTIC_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
aoqi@0 486 #endif
aoqi@0 487 #ifdef COMPILER2
aoqi@0 488 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
aoqi@0 489 #endif
aoqi@0 490 #ifdef SHARK
aoqi@0 491 SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT)
aoqi@0 492 #endif
aoqi@0 493 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT)
aoqi@0 494 FLAGTABLE_EXT
aoqi@0 495 {0, NULL, NULL}
aoqi@0 496 };
aoqi@0 497
aoqi@0 498 Flag* Flag::flags = flagTable;
aoqi@0 499 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
aoqi@0 500
aoqi@0 501 inline bool str_equal(const char* s, const char* q, size_t len) {
aoqi@0 502 // s is null terminated, q is not!
aoqi@0 503 if (strlen(s) != (unsigned int) len) return false;
aoqi@0 504 return strncmp(s, q, len) == 0;
aoqi@0 505 }
aoqi@0 506
aoqi@0 507 // Search the flag table for a named flag
aoqi@0 508 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
aoqi@0 509 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
aoqi@0 510 if (str_equal(current->_name, name, length)) {
aoqi@0 511 // Found a matching entry.
aoqi@0 512 // Don't report notproduct and develop flags in product builds.
aoqi@0 513 if (current->is_constant_in_binary()) {
aoqi@0 514 return (return_flag == true ? current : NULL);
aoqi@0 515 }
aoqi@0 516 // Report locked flags only if allowed.
aoqi@0 517 if (!(current->is_unlocked() || current->is_unlocker())) {
aoqi@0 518 if (!allow_locked) {
aoqi@0 519 // disable use of locked flags, e.g. diagnostic, experimental,
aoqi@0 520 // commercial... until they are explicitly unlocked
aoqi@0 521 return NULL;
aoqi@0 522 }
aoqi@0 523 }
aoqi@0 524 return current;
aoqi@0 525 }
aoqi@0 526 }
aoqi@0 527 // Flag name is not in the flag table
aoqi@0 528 return NULL;
aoqi@0 529 }
aoqi@0 530
aoqi@0 531 // Compute string similarity based on Dice's coefficient
aoqi@0 532 static float str_similar(const char* str1, const char* str2, size_t len2) {
aoqi@0 533 int len1 = (int) strlen(str1);
aoqi@0 534 int total = len1 + (int) len2;
aoqi@0 535
aoqi@0 536 int hit = 0;
aoqi@0 537
aoqi@0 538 for (int i = 0; i < len1 -1; ++i) {
aoqi@0 539 for (int j = 0; j < (int) len2 -1; ++j) {
aoqi@0 540 if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
aoqi@0 541 ++hit;
aoqi@0 542 break;
aoqi@0 543 }
aoqi@0 544 }
aoqi@0 545 }
aoqi@0 546
aoqi@0 547 return 2.0f * (float) hit / (float) total;
aoqi@0 548 }
aoqi@0 549
aoqi@0 550 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
aoqi@0 551 float VMOptionsFuzzyMatchSimilarity = 0.7f;
aoqi@0 552 Flag* match = NULL;
aoqi@0 553 float score;
aoqi@0 554 float max_score = -1;
aoqi@0 555
aoqi@0 556 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
aoqi@0 557 score = str_similar(current->_name, name, length);
aoqi@0 558 if (score > max_score) {
aoqi@0 559 max_score = score;
aoqi@0 560 match = current;
aoqi@0 561 }
aoqi@0 562 }
aoqi@0 563
aoqi@0 564 if (!(match->is_unlocked() || match->is_unlocker())) {
aoqi@0 565 if (!allow_locked) {
aoqi@0 566 return NULL;
aoqi@0 567 }
aoqi@0 568 }
aoqi@0 569
aoqi@0 570 if (max_score < VMOptionsFuzzyMatchSimilarity) {
aoqi@0 571 return NULL;
aoqi@0 572 }
aoqi@0 573
aoqi@0 574 return match;
aoqi@0 575 }
aoqi@0 576
aoqi@0 577 // Returns the address of the index'th element
aoqi@0 578 static Flag* address_of_flag(CommandLineFlagWithType flag) {
aoqi@0 579 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 580 return &Flag::flags[flag];
aoqi@0 581 }
aoqi@0 582
aoqi@0 583 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
aoqi@0 584 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 585 Flag* f = &Flag::flags[flag];
aoqi@0 586 return f->is_default();
aoqi@0 587 }
aoqi@0 588
aoqi@0 589 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
aoqi@0 590 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 591 Flag* f = &Flag::flags[flag];
aoqi@0 592 return f->is_ergonomic();
aoqi@0 593 }
aoqi@0 594
aoqi@0 595 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
aoqi@0 596 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 597 Flag* f = &Flag::flags[flag];
aoqi@0 598 return f->is_command_line();
aoqi@0 599 }
aoqi@0 600
aoqi@0 601 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
aoqi@0 602 Flag* result = Flag::find_flag((char*)name, strlen(name));
aoqi@0 603 if (result == NULL) return false;
aoqi@0 604 *value = result->is_command_line();
aoqi@0 605 return true;
aoqi@0 606 }
aoqi@0 607
aoqi@0 608 template<class E, class T>
aoqi@0 609 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin)
aoqi@0 610 {
aoqi@0 611 E e;
aoqi@0 612 e.set_name(name);
aoqi@0 613 e.set_old_value(old_value);
aoqi@0 614 e.set_new_value(new_value);
aoqi@0 615 e.set_origin(origin);
aoqi@0 616 e.commit();
aoqi@0 617 }
aoqi@0 618
iignatyev@6963 619 bool CommandLineFlags::boolAt(const char* name, size_t len, bool* value) {
aoqi@0 620 Flag* result = Flag::find_flag(name, len);
aoqi@0 621 if (result == NULL) return false;
aoqi@0 622 if (!result->is_bool()) return false;
aoqi@0 623 *value = result->get_bool();
aoqi@0 624 return true;
aoqi@0 625 }
aoqi@0 626
iignatyev@6963 627 bool CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
aoqi@0 628 Flag* result = Flag::find_flag(name, len);
aoqi@0 629 if (result == NULL) return false;
aoqi@0 630 if (!result->is_bool()) return false;
aoqi@0 631 bool old_value = result->get_bool();
aoqi@0 632 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
aoqi@0 633 result->set_bool(*value);
aoqi@0 634 *value = old_value;
aoqi@0 635 result->set_origin(origin);
aoqi@0 636 return true;
aoqi@0 637 }
aoqi@0 638
aoqi@0 639 void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
aoqi@0 640 Flag* faddr = address_of_flag(flag);
aoqi@0 641 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
aoqi@0 642 trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
aoqi@0 643 faddr->set_bool(value);
aoqi@0 644 faddr->set_origin(origin);
aoqi@0 645 }
aoqi@0 646
iignatyev@6963 647 bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value) {
aoqi@0 648 Flag* result = Flag::find_flag(name, len);
aoqi@0 649 if (result == NULL) return false;
aoqi@0 650 if (!result->is_intx()) return false;
aoqi@0 651 *value = result->get_intx();
aoqi@0 652 return true;
aoqi@0 653 }
aoqi@0 654
iignatyev@6963 655 bool CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
aoqi@0 656 Flag* result = Flag::find_flag(name, len);
aoqi@0 657 if (result == NULL) return false;
aoqi@0 658 if (!result->is_intx()) return false;
aoqi@0 659 intx old_value = result->get_intx();
aoqi@0 660 trace_flag_changed<EventLongFlagChanged, s8>(name, old_value, *value, origin);
aoqi@0 661 result->set_intx(*value);
aoqi@0 662 *value = old_value;
aoqi@0 663 result->set_origin(origin);
aoqi@0 664 return true;
aoqi@0 665 }
aoqi@0 666
aoqi@0 667 void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
aoqi@0 668 Flag* faddr = address_of_flag(flag);
aoqi@0 669 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
aoqi@0 670 trace_flag_changed<EventLongFlagChanged, s8>(faddr->_name, faddr->get_intx(), value, origin);
aoqi@0 671 faddr->set_intx(value);
aoqi@0 672 faddr->set_origin(origin);
aoqi@0 673 }
aoqi@0 674
iignatyev@6963 675 bool CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value) {
aoqi@0 676 Flag* result = Flag::find_flag(name, len);
aoqi@0 677 if (result == NULL) return false;
aoqi@0 678 if (!result->is_uintx()) return false;
aoqi@0 679 *value = result->get_uintx();
aoqi@0 680 return true;
aoqi@0 681 }
aoqi@0 682
iignatyev@6963 683 bool CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
aoqi@0 684 Flag* result = Flag::find_flag(name, len);
aoqi@0 685 if (result == NULL) return false;
aoqi@0 686 if (!result->is_uintx()) return false;
aoqi@0 687 uintx old_value = result->get_uintx();
aoqi@0 688 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
aoqi@0 689 result->set_uintx(*value);
aoqi@0 690 *value = old_value;
aoqi@0 691 result->set_origin(origin);
aoqi@0 692 return true;
aoqi@0 693 }
aoqi@0 694
aoqi@0 695 void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
aoqi@0 696 Flag* faddr = address_of_flag(flag);
aoqi@0 697 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
aoqi@0 698 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
aoqi@0 699 faddr->set_uintx(value);
aoqi@0 700 faddr->set_origin(origin);
aoqi@0 701 }
aoqi@0 702
iignatyev@6963 703 bool CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value) {
aoqi@0 704 Flag* result = Flag::find_flag(name, len);
aoqi@0 705 if (result == NULL) return false;
aoqi@0 706 if (!result->is_uint64_t()) return false;
aoqi@0 707 *value = result->get_uint64_t();
aoqi@0 708 return true;
aoqi@0 709 }
aoqi@0 710
iignatyev@6963 711 bool CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
aoqi@0 712 Flag* result = Flag::find_flag(name, len);
aoqi@0 713 if (result == NULL) return false;
aoqi@0 714 if (!result->is_uint64_t()) return false;
aoqi@0 715 uint64_t old_value = result->get_uint64_t();
aoqi@0 716 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
aoqi@0 717 result->set_uint64_t(*value);
aoqi@0 718 *value = old_value;
aoqi@0 719 result->set_origin(origin);
aoqi@0 720 return true;
aoqi@0 721 }
aoqi@0 722
aoqi@0 723 void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
aoqi@0 724 Flag* faddr = address_of_flag(flag);
aoqi@0 725 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
aoqi@0 726 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
aoqi@0 727 faddr->set_uint64_t(value);
aoqi@0 728 faddr->set_origin(origin);
aoqi@0 729 }
aoqi@0 730
iignatyev@6963 731 bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value) {
aoqi@0 732 Flag* result = Flag::find_flag(name, len);
aoqi@0 733 if (result == NULL) return false;
aoqi@0 734 if (!result->is_double()) return false;
aoqi@0 735 *value = result->get_double();
aoqi@0 736 return true;
aoqi@0 737 }
aoqi@0 738
iignatyev@6963 739 bool CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
aoqi@0 740 Flag* result = Flag::find_flag(name, len);
aoqi@0 741 if (result == NULL) return false;
aoqi@0 742 if (!result->is_double()) return false;
aoqi@0 743 double old_value = result->get_double();
aoqi@0 744 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
aoqi@0 745 result->set_double(*value);
aoqi@0 746 *value = old_value;
aoqi@0 747 result->set_origin(origin);
aoqi@0 748 return true;
aoqi@0 749 }
aoqi@0 750
aoqi@0 751 void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
aoqi@0 752 Flag* faddr = address_of_flag(flag);
aoqi@0 753 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
aoqi@0 754 trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
aoqi@0 755 faddr->set_double(value);
aoqi@0 756 faddr->set_origin(origin);
aoqi@0 757 }
aoqi@0 758
iignatyev@6963 759 bool CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value) {
aoqi@0 760 Flag* result = Flag::find_flag(name, len);
aoqi@0 761 if (result == NULL) return false;
aoqi@0 762 if (!result->is_ccstr()) return false;
aoqi@0 763 *value = result->get_ccstr();
aoqi@0 764 return true;
aoqi@0 765 }
aoqi@0 766
iignatyev@6963 767 bool CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
aoqi@0 768 Flag* result = Flag::find_flag(name, len);
aoqi@0 769 if (result == NULL) return false;
aoqi@0 770 if (!result->is_ccstr()) return false;
aoqi@0 771 ccstr old_value = result->get_ccstr();
aoqi@0 772 trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
aoqi@0 773 char* new_value = NULL;
aoqi@0 774 if (*value != NULL) {
aoqi@0 775 new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal);
aoqi@0 776 strcpy(new_value, *value);
aoqi@0 777 }
aoqi@0 778 result->set_ccstr(new_value);
aoqi@0 779 if (result->is_default() && old_value != NULL) {
aoqi@0 780 // Prior value is NOT heap allocated, but was a literal constant.
aoqi@0 781 char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
aoqi@0 782 strcpy(old_value_to_free, old_value);
aoqi@0 783 old_value = old_value_to_free;
aoqi@0 784 }
aoqi@0 785 *value = old_value;
aoqi@0 786 result->set_origin(origin);
aoqi@0 787 return true;
aoqi@0 788 }
aoqi@0 789
aoqi@0 790 void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
aoqi@0 791 Flag* faddr = address_of_flag(flag);
aoqi@0 792 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
aoqi@0 793 ccstr old_value = faddr->get_ccstr();
aoqi@0 794 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
aoqi@0 795 char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
aoqi@0 796 strcpy(new_value, value);
aoqi@0 797 faddr->set_ccstr(new_value);
aoqi@0 798 if (!faddr->is_default() && old_value != NULL) {
aoqi@0 799 // Prior value is heap allocated so free it.
aoqi@0 800 FREE_C_HEAP_ARRAY(char, old_value, mtInternal);
aoqi@0 801 }
aoqi@0 802 faddr->set_origin(origin);
aoqi@0 803 }
aoqi@0 804
aoqi@0 805 extern "C" {
aoqi@0 806 static int compare_flags(const void* void_a, const void* void_b) {
aoqi@0 807 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
aoqi@0 808 }
aoqi@0 809 }
aoqi@0 810
aoqi@0 811 void CommandLineFlags::printSetFlags(outputStream* out) {
aoqi@0 812 // Print which flags were set on the command line
aoqi@0 813 // note: this method is called before the thread structure is in place
aoqi@0 814 // which means resource allocation cannot be used.
aoqi@0 815
aoqi@0 816 // The last entry is the null entry.
aoqi@0 817 const size_t length = Flag::numFlags - 1;
aoqi@0 818
aoqi@0 819 // Sort
aoqi@0 820 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
aoqi@0 821 for (size_t i = 0; i < length; i++) {
aoqi@0 822 array[i] = &flagTable[i];
aoqi@0 823 }
aoqi@0 824 qsort(array, length, sizeof(Flag*), compare_flags);
aoqi@0 825
aoqi@0 826 // Print
aoqi@0 827 for (size_t i = 0; i < length; i++) {
aoqi@0 828 if (array[i]->get_origin() /* naked field! */) {
aoqi@0 829 array[i]->print_as_flag(out);
aoqi@0 830 out->print(" ");
aoqi@0 831 }
aoqi@0 832 }
aoqi@0 833 out->cr();
aoqi@0 834 FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
aoqi@0 835 }
aoqi@0 836
aoqi@0 837 #ifndef PRODUCT
aoqi@0 838
aoqi@0 839
aoqi@0 840 void CommandLineFlags::verify() {
aoqi@0 841 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
aoqi@0 842 }
aoqi@0 843
aoqi@0 844 #endif // PRODUCT
aoqi@0 845
aoqi@0 846 void CommandLineFlags::printFlags(outputStream* out, bool withComments) {
aoqi@0 847 // Print the flags sorted by name
aoqi@0 848 // note: this method is called before the thread structure is in place
aoqi@0 849 // which means resource allocation cannot be used.
aoqi@0 850
aoqi@0 851 // The last entry is the null entry.
aoqi@0 852 const size_t length = Flag::numFlags - 1;
aoqi@0 853
aoqi@0 854 // Sort
aoqi@0 855 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
aoqi@0 856 for (size_t i = 0; i < length; i++) {
aoqi@0 857 array[i] = &flagTable[i];
aoqi@0 858 }
aoqi@0 859 qsort(array, length, sizeof(Flag*), compare_flags);
aoqi@0 860
aoqi@0 861 // Print
aoqi@0 862 out->print_cr("[Global flags]");
aoqi@0 863 for (size_t i = 0; i < length; i++) {
aoqi@0 864 if (array[i]->is_unlocked()) {
aoqi@0 865 array[i]->print_on(out, withComments);
aoqi@0 866 }
aoqi@0 867 }
aoqi@0 868 FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
aoqi@0 869 }

mercurial