src/share/vm/runtime/globals.cpp

Fri, 24 Jun 2016 17:12:13 +0800

author
aoqi<aoqi@loongson.cn>
date
Fri, 24 Jun 2016 17:12:13 +0800
changeset 25
873fd82b133d
parent 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

[Code Reorganization] Removed GC related modifications made by Loongson, for example, UseOldNUMA.

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
aoqi@0 246 // Get custom message for this locked flag, or return NULL if
aoqi@0 247 // none is available.
aoqi@0 248 void Flag::get_locked_message(char* buf, int buflen) const {
aoqi@0 249 buf[0] = '\0';
aoqi@0 250 if (is_diagnostic() && !is_unlocked()) {
aoqi@0 251 jio_snprintf(buf, buflen, "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n",
aoqi@0 252 _name);
aoqi@0 253 return;
aoqi@0 254 }
aoqi@0 255 if (is_experimental() && !is_unlocked()) {
aoqi@0 256 jio_snprintf(buf, buflen, "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n",
aoqi@0 257 _name);
aoqi@0 258 return;
aoqi@0 259 }
aoqi@0 260 if (is_develop() && is_product_build()) {
aoqi@0 261 jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n",
aoqi@0 262 _name);
aoqi@0 263 return;
aoqi@0 264 }
aoqi@0 265 if (is_notproduct() && is_product_build()) {
aoqi@0 266 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
aoqi@0 267 _name);
aoqi@0 268 return;
aoqi@0 269 }
aoqi@0 270 get_locked_message_ext(buf, buflen);
aoqi@0 271 }
aoqi@0 272
aoqi@0 273 bool Flag::is_writeable() const {
aoqi@0 274 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
aoqi@0 275 }
aoqi@0 276
aoqi@0 277 // All flags except "manageable" are assumed to be internal flags.
aoqi@0 278 // Long term, we need to define a mechanism to specify which flags
aoqi@0 279 // are external/stable and change this function accordingly.
aoqi@0 280 bool Flag::is_external() const {
aoqi@0 281 return is_manageable() || is_external_ext();
aoqi@0 282 }
aoqi@0 283
aoqi@0 284
aoqi@0 285 // Length of format string (e.g. "%.1234s") for printing ccstr below
aoqi@0 286 #define FORMAT_BUFFER_LEN 16
aoqi@0 287
aoqi@0 288 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
aoqi@0 289 void Flag::print_on(outputStream* st, bool withComments) {
aoqi@0 290 // Don't print notproduct and develop flags in a product build.
aoqi@0 291 if (is_constant_in_binary()) {
aoqi@0 292 return;
aoqi@0 293 }
aoqi@0 294
aoqi@0 295 st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
aoqi@0 296
aoqi@0 297 if (is_bool()) {
aoqi@0 298 st->print("%-16s", get_bool() ? "true" : "false");
aoqi@0 299 }
aoqi@0 300 if (is_intx()) {
aoqi@0 301 st->print("%-16ld", get_intx());
aoqi@0 302 }
aoqi@0 303 if (is_uintx()) {
aoqi@0 304 st->print("%-16lu", get_uintx());
aoqi@0 305 }
aoqi@0 306 if (is_uint64_t()) {
aoqi@0 307 st->print("%-16lu", get_uint64_t());
aoqi@0 308 }
aoqi@0 309 if (is_double()) {
aoqi@0 310 st->print("%-16f", get_double());
aoqi@0 311 }
aoqi@0 312 if (is_ccstr()) {
aoqi@0 313 const char* cp = get_ccstr();
aoqi@0 314 if (cp != NULL) {
aoqi@0 315 const char* eol;
aoqi@0 316 while ((eol = strchr(cp, '\n')) != NULL) {
aoqi@0 317 char format_buffer[FORMAT_BUFFER_LEN];
aoqi@0 318 size_t llen = pointer_delta(eol, cp, sizeof(char));
aoqi@0 319 jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
aoqi@0 320 "%%." SIZE_FORMAT "s", llen);
aoqi@0 321 PRAGMA_DIAG_PUSH
aoqi@0 322 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
aoqi@0 323 st->print(format_buffer, cp);
aoqi@0 324 PRAGMA_DIAG_POP
aoqi@0 325 st->cr();
aoqi@0 326 cp = eol+1;
aoqi@0 327 st->print("%5s %-35s += ", "", _name);
aoqi@0 328 }
aoqi@0 329 st->print("%-16s", cp);
aoqi@0 330 }
aoqi@0 331 else st->print("%-16s", "");
aoqi@0 332 }
aoqi@0 333
aoqi@0 334 st->print("%-20s", " ");
aoqi@0 335 print_kind(st);
aoqi@0 336
aoqi@0 337 if (withComments) {
aoqi@0 338 #ifndef PRODUCT
aoqi@0 339 st->print("%s", _doc);
aoqi@0 340 #endif
aoqi@0 341 }
aoqi@0 342 st->cr();
aoqi@0 343 }
aoqi@0 344
aoqi@0 345 void Flag::print_kind(outputStream* st) {
aoqi@0 346 struct Data {
aoqi@0 347 int flag;
aoqi@0 348 const char* name;
aoqi@0 349 };
aoqi@0 350
aoqi@0 351 Data data[] = {
aoqi@0 352 { KIND_C1, "C1" },
aoqi@0 353 { KIND_C2, "C2" },
aoqi@0 354 { KIND_ARCH, "ARCH" },
aoqi@0 355 { KIND_SHARK, "SHARK" },
aoqi@0 356 { KIND_PLATFORM_DEPENDENT, "pd" },
aoqi@0 357 { KIND_PRODUCT, "product" },
aoqi@0 358 { KIND_MANAGEABLE, "manageable" },
aoqi@0 359 { KIND_DIAGNOSTIC, "diagnostic" },
aoqi@0 360 { KIND_EXPERIMENTAL, "experimental" },
aoqi@0 361 { KIND_COMMERCIAL, "commercial" },
aoqi@0 362 { KIND_NOT_PRODUCT, "notproduct" },
aoqi@0 363 { KIND_DEVELOP, "develop" },
aoqi@0 364 { KIND_LP64_PRODUCT, "lp64_product" },
aoqi@0 365 { KIND_READ_WRITE, "rw" },
aoqi@0 366 { -1, "" }
aoqi@0 367 };
aoqi@0 368
aoqi@0 369 if ((_flags & KIND_MASK) != 0) {
aoqi@0 370 st->print("{");
aoqi@0 371 bool is_first = true;
aoqi@0 372
aoqi@0 373 for (int i = 0; data[i].flag != -1; i++) {
aoqi@0 374 Data d = data[i];
aoqi@0 375 if ((_flags & d.flag) != 0) {
aoqi@0 376 if (is_first) {
aoqi@0 377 is_first = false;
aoqi@0 378 } else {
aoqi@0 379 st->print(" ");
aoqi@0 380 }
aoqi@0 381 st->print("%s", d.name);
aoqi@0 382 }
aoqi@0 383 }
aoqi@0 384
aoqi@0 385 st->print("}");
aoqi@0 386 }
aoqi@0 387 }
aoqi@0 388
aoqi@0 389 void Flag::print_as_flag(outputStream* st) {
aoqi@0 390 if (is_bool()) {
aoqi@0 391 st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
aoqi@0 392 } else if (is_intx()) {
aoqi@0 393 st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
aoqi@0 394 } else if (is_uintx()) {
aoqi@0 395 st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
aoqi@0 396 } else if (is_uint64_t()) {
aoqi@0 397 st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
aoqi@0 398 } else if (is_double()) {
aoqi@0 399 st->print("-XX:%s=%f", _name, get_double());
aoqi@0 400 } else if (is_ccstr()) {
aoqi@0 401 st->print("-XX:%s=", _name);
aoqi@0 402 const char* cp = get_ccstr();
aoqi@0 403 if (cp != NULL) {
aoqi@0 404 // Need to turn embedded '\n's back into separate arguments
aoqi@0 405 // Not so efficient to print one character at a time,
aoqi@0 406 // but the choice is to do the transformation to a buffer
aoqi@0 407 // and print that. And this need not be efficient.
aoqi@0 408 for (; *cp != '\0'; cp += 1) {
aoqi@0 409 switch (*cp) {
aoqi@0 410 default:
aoqi@0 411 st->print("%c", *cp);
aoqi@0 412 break;
aoqi@0 413 case '\n':
aoqi@0 414 st->print(" -XX:%s=", _name);
aoqi@0 415 break;
aoqi@0 416 }
aoqi@0 417 }
aoqi@0 418 }
aoqi@0 419 } else {
aoqi@0 420 ShouldNotReachHere();
aoqi@0 421 }
aoqi@0 422 }
aoqi@0 423
aoqi@0 424 // 4991491 do not "optimize out" the was_set false values: omitting them
aoqi@0 425 // tickles a Microsoft compiler bug causing flagTable to be malformed
aoqi@0 426
aoqi@0 427 #define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name)
aoqi@0 428
aoqi@0 429 #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 430 #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 431 #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 432 #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 433 #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 434 #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 435 #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 436 #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 437 #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 438
aoqi@0 439 #ifdef _LP64
aoqi@0 440 #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 441 #else
aoqi@0 442 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
aoqi@0 443 #endif // _LP64
aoqi@0 444
aoqi@0 445 #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 446 #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 447 #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 448 #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 449 #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 450 #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 451
aoqi@0 452 #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 453 #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 454 #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 455 #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 456 #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 457 #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 458 #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 459
aoqi@0 460 #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 461 #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 462 #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 463 #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 464 #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 465
aoqi@0 466 #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 467 #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 468 #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 469 #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 470 #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 471 #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 472
aoqi@0 473 static Flag flagTable[] = {
aoqi@0 474 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 475 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 476 #if INCLUDE_ALL_GCS
aoqi@0 477 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 478 #endif // INCLUDE_ALL_GCS
aoqi@0 479 #ifdef COMPILER1
aoqi@0 480 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 481 #endif
aoqi@0 482 #ifdef COMPILER2
aoqi@0 483 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 484 #endif
aoqi@0 485 #ifdef SHARK
aoqi@0 486 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 487 #endif
aoqi@0 488 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT)
aoqi@0 489 FLAGTABLE_EXT
aoqi@0 490 {0, NULL, NULL}
aoqi@0 491 };
aoqi@0 492
aoqi@0 493 Flag* Flag::flags = flagTable;
aoqi@0 494 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
aoqi@0 495
aoqi@0 496 inline bool str_equal(const char* s, const char* q, size_t len) {
aoqi@0 497 // s is null terminated, q is not!
aoqi@0 498 if (strlen(s) != (unsigned int) len) return false;
aoqi@0 499 return strncmp(s, q, len) == 0;
aoqi@0 500 }
aoqi@0 501
aoqi@0 502 // Search the flag table for a named flag
aoqi@0 503 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
aoqi@0 504 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
aoqi@0 505 if (str_equal(current->_name, name, length)) {
aoqi@0 506 // Found a matching entry.
aoqi@0 507 // Don't report notproduct and develop flags in product builds.
aoqi@0 508 if (current->is_constant_in_binary()) {
aoqi@0 509 return (return_flag == true ? current : NULL);
aoqi@0 510 }
aoqi@0 511 // Report locked flags only if allowed.
aoqi@0 512 if (!(current->is_unlocked() || current->is_unlocker())) {
aoqi@0 513 if (!allow_locked) {
aoqi@0 514 // disable use of locked flags, e.g. diagnostic, experimental,
aoqi@0 515 // commercial... until they are explicitly unlocked
aoqi@0 516 return NULL;
aoqi@0 517 }
aoqi@0 518 }
aoqi@0 519 return current;
aoqi@0 520 }
aoqi@0 521 }
aoqi@0 522 // Flag name is not in the flag table
aoqi@0 523 return NULL;
aoqi@0 524 }
aoqi@0 525
aoqi@0 526 // Compute string similarity based on Dice's coefficient
aoqi@0 527 static float str_similar(const char* str1, const char* str2, size_t len2) {
aoqi@0 528 int len1 = (int) strlen(str1);
aoqi@0 529 int total = len1 + (int) len2;
aoqi@0 530
aoqi@0 531 int hit = 0;
aoqi@0 532
aoqi@0 533 for (int i = 0; i < len1 -1; ++i) {
aoqi@0 534 for (int j = 0; j < (int) len2 -1; ++j) {
aoqi@0 535 if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
aoqi@0 536 ++hit;
aoqi@0 537 break;
aoqi@0 538 }
aoqi@0 539 }
aoqi@0 540 }
aoqi@0 541
aoqi@0 542 return 2.0f * (float) hit / (float) total;
aoqi@0 543 }
aoqi@0 544
aoqi@0 545 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
aoqi@0 546 float VMOptionsFuzzyMatchSimilarity = 0.7f;
aoqi@0 547 Flag* match = NULL;
aoqi@0 548 float score;
aoqi@0 549 float max_score = -1;
aoqi@0 550
aoqi@0 551 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
aoqi@0 552 score = str_similar(current->_name, name, length);
aoqi@0 553 if (score > max_score) {
aoqi@0 554 max_score = score;
aoqi@0 555 match = current;
aoqi@0 556 }
aoqi@0 557 }
aoqi@0 558
aoqi@0 559 if (!(match->is_unlocked() || match->is_unlocker())) {
aoqi@0 560 if (!allow_locked) {
aoqi@0 561 return NULL;
aoqi@0 562 }
aoqi@0 563 }
aoqi@0 564
aoqi@0 565 if (max_score < VMOptionsFuzzyMatchSimilarity) {
aoqi@0 566 return NULL;
aoqi@0 567 }
aoqi@0 568
aoqi@0 569 return match;
aoqi@0 570 }
aoqi@0 571
aoqi@0 572 // Returns the address of the index'th element
aoqi@0 573 static Flag* address_of_flag(CommandLineFlagWithType flag) {
aoqi@0 574 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 575 return &Flag::flags[flag];
aoqi@0 576 }
aoqi@0 577
aoqi@0 578 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
aoqi@0 579 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 580 Flag* f = &Flag::flags[flag];
aoqi@0 581 return f->is_default();
aoqi@0 582 }
aoqi@0 583
aoqi@0 584 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
aoqi@0 585 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 586 Flag* f = &Flag::flags[flag];
aoqi@0 587 return f->is_ergonomic();
aoqi@0 588 }
aoqi@0 589
aoqi@0 590 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
aoqi@0 591 assert((size_t)flag < Flag::numFlags, "bad command line flag index");
aoqi@0 592 Flag* f = &Flag::flags[flag];
aoqi@0 593 return f->is_command_line();
aoqi@0 594 }
aoqi@0 595
aoqi@0 596 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
aoqi@0 597 Flag* result = Flag::find_flag((char*)name, strlen(name));
aoqi@0 598 if (result == NULL) return false;
aoqi@0 599 *value = result->is_command_line();
aoqi@0 600 return true;
aoqi@0 601 }
aoqi@0 602
aoqi@0 603 template<class E, class T>
aoqi@0 604 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin)
aoqi@0 605 {
aoqi@0 606 E e;
aoqi@0 607 e.set_name(name);
aoqi@0 608 e.set_old_value(old_value);
aoqi@0 609 e.set_new_value(new_value);
aoqi@0 610 e.set_origin(origin);
aoqi@0 611 e.commit();
aoqi@0 612 }
aoqi@0 613
aoqi@0 614 bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) {
aoqi@0 615 Flag* result = Flag::find_flag(name, len);
aoqi@0 616 if (result == NULL) return false;
aoqi@0 617 if (!result->is_bool()) return false;
aoqi@0 618 *value = result->get_bool();
aoqi@0 619 return true;
aoqi@0 620 }
aoqi@0 621
aoqi@0 622 bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin) {
aoqi@0 623 Flag* result = Flag::find_flag(name, len);
aoqi@0 624 if (result == NULL) return false;
aoqi@0 625 if (!result->is_bool()) return false;
aoqi@0 626 bool old_value = result->get_bool();
aoqi@0 627 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
aoqi@0 628 result->set_bool(*value);
aoqi@0 629 *value = old_value;
aoqi@0 630 result->set_origin(origin);
aoqi@0 631 return true;
aoqi@0 632 }
aoqi@0 633
aoqi@0 634 void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
aoqi@0 635 Flag* faddr = address_of_flag(flag);
aoqi@0 636 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
aoqi@0 637 trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
aoqi@0 638 faddr->set_bool(value);
aoqi@0 639 faddr->set_origin(origin);
aoqi@0 640 }
aoqi@0 641
aoqi@0 642 bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) {
aoqi@0 643 Flag* result = Flag::find_flag(name, len);
aoqi@0 644 if (result == NULL) return false;
aoqi@0 645 if (!result->is_intx()) return false;
aoqi@0 646 *value = result->get_intx();
aoqi@0 647 return true;
aoqi@0 648 }
aoqi@0 649
aoqi@0 650 bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin) {
aoqi@0 651 Flag* result = Flag::find_flag(name, len);
aoqi@0 652 if (result == NULL) return false;
aoqi@0 653 if (!result->is_intx()) return false;
aoqi@0 654 intx old_value = result->get_intx();
aoqi@0 655 trace_flag_changed<EventLongFlagChanged, s8>(name, old_value, *value, origin);
aoqi@0 656 result->set_intx(*value);
aoqi@0 657 *value = old_value;
aoqi@0 658 result->set_origin(origin);
aoqi@0 659 return true;
aoqi@0 660 }
aoqi@0 661
aoqi@0 662 void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
aoqi@0 663 Flag* faddr = address_of_flag(flag);
aoqi@0 664 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
aoqi@0 665 trace_flag_changed<EventLongFlagChanged, s8>(faddr->_name, faddr->get_intx(), value, origin);
aoqi@0 666 faddr->set_intx(value);
aoqi@0 667 faddr->set_origin(origin);
aoqi@0 668 }
aoqi@0 669
aoqi@0 670 bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) {
aoqi@0 671 Flag* result = Flag::find_flag(name, len);
aoqi@0 672 if (result == NULL) return false;
aoqi@0 673 if (!result->is_uintx()) return false;
aoqi@0 674 *value = result->get_uintx();
aoqi@0 675 return true;
aoqi@0 676 }
aoqi@0 677
aoqi@0 678 bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin) {
aoqi@0 679 Flag* result = Flag::find_flag(name, len);
aoqi@0 680 if (result == NULL) return false;
aoqi@0 681 if (!result->is_uintx()) return false;
aoqi@0 682 uintx old_value = result->get_uintx();
aoqi@0 683 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
aoqi@0 684 result->set_uintx(*value);
aoqi@0 685 *value = old_value;
aoqi@0 686 result->set_origin(origin);
aoqi@0 687 return true;
aoqi@0 688 }
aoqi@0 689
aoqi@0 690 void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
aoqi@0 691 Flag* faddr = address_of_flag(flag);
aoqi@0 692 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
aoqi@0 693 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
aoqi@0 694 faddr->set_uintx(value);
aoqi@0 695 faddr->set_origin(origin);
aoqi@0 696 }
aoqi@0 697
aoqi@0 698 bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) {
aoqi@0 699 Flag* result = Flag::find_flag(name, len);
aoqi@0 700 if (result == NULL) return false;
aoqi@0 701 if (!result->is_uint64_t()) return false;
aoqi@0 702 *value = result->get_uint64_t();
aoqi@0 703 return true;
aoqi@0 704 }
aoqi@0 705
aoqi@0 706 bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin) {
aoqi@0 707 Flag* result = Flag::find_flag(name, len);
aoqi@0 708 if (result == NULL) return false;
aoqi@0 709 if (!result->is_uint64_t()) return false;
aoqi@0 710 uint64_t old_value = result->get_uint64_t();
aoqi@0 711 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
aoqi@0 712 result->set_uint64_t(*value);
aoqi@0 713 *value = old_value;
aoqi@0 714 result->set_origin(origin);
aoqi@0 715 return true;
aoqi@0 716 }
aoqi@0 717
aoqi@0 718 void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
aoqi@0 719 Flag* faddr = address_of_flag(flag);
aoqi@0 720 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
aoqi@0 721 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
aoqi@0 722 faddr->set_uint64_t(value);
aoqi@0 723 faddr->set_origin(origin);
aoqi@0 724 }
aoqi@0 725
aoqi@0 726 bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) {
aoqi@0 727 Flag* result = Flag::find_flag(name, len);
aoqi@0 728 if (result == NULL) return false;
aoqi@0 729 if (!result->is_double()) return false;
aoqi@0 730 *value = result->get_double();
aoqi@0 731 return true;
aoqi@0 732 }
aoqi@0 733
aoqi@0 734 bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin) {
aoqi@0 735 Flag* result = Flag::find_flag(name, len);
aoqi@0 736 if (result == NULL) return false;
aoqi@0 737 if (!result->is_double()) return false;
aoqi@0 738 double old_value = result->get_double();
aoqi@0 739 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
aoqi@0 740 result->set_double(*value);
aoqi@0 741 *value = old_value;
aoqi@0 742 result->set_origin(origin);
aoqi@0 743 return true;
aoqi@0 744 }
aoqi@0 745
aoqi@0 746 void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
aoqi@0 747 Flag* faddr = address_of_flag(flag);
aoqi@0 748 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
aoqi@0 749 trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
aoqi@0 750 faddr->set_double(value);
aoqi@0 751 faddr->set_origin(origin);
aoqi@0 752 }
aoqi@0 753
aoqi@0 754 bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) {
aoqi@0 755 Flag* result = Flag::find_flag(name, len);
aoqi@0 756 if (result == NULL) return false;
aoqi@0 757 if (!result->is_ccstr()) return false;
aoqi@0 758 *value = result->get_ccstr();
aoqi@0 759 return true;
aoqi@0 760 }
aoqi@0 761
aoqi@0 762 // Contract: Flag will make private copy of the incoming value.
aoqi@0 763 // Outgoing value is always malloc-ed, and caller MUST call free.
aoqi@0 764 bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin) {
aoqi@0 765 Flag* result = Flag::find_flag(name, len);
aoqi@0 766 if (result == NULL) return false;
aoqi@0 767 if (!result->is_ccstr()) return false;
aoqi@0 768 ccstr old_value = result->get_ccstr();
aoqi@0 769 trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
aoqi@0 770 char* new_value = NULL;
aoqi@0 771 if (*value != NULL) {
aoqi@0 772 new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal);
aoqi@0 773 strcpy(new_value, *value);
aoqi@0 774 }
aoqi@0 775 result->set_ccstr(new_value);
aoqi@0 776 if (result->is_default() && old_value != NULL) {
aoqi@0 777 // Prior value is NOT heap allocated, but was a literal constant.
aoqi@0 778 char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
aoqi@0 779 strcpy(old_value_to_free, old_value);
aoqi@0 780 old_value = old_value_to_free;
aoqi@0 781 }
aoqi@0 782 *value = old_value;
aoqi@0 783 result->set_origin(origin);
aoqi@0 784 return true;
aoqi@0 785 }
aoqi@0 786
aoqi@0 787 // Contract: Flag will make private copy of the incoming value.
aoqi@0 788 void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
aoqi@0 789 Flag* faddr = address_of_flag(flag);
aoqi@0 790 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
aoqi@0 791 ccstr old_value = faddr->get_ccstr();
aoqi@0 792 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
aoqi@0 793 char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
aoqi@0 794 strcpy(new_value, value);
aoqi@0 795 faddr->set_ccstr(new_value);
aoqi@0 796 if (!faddr->is_default() && old_value != NULL) {
aoqi@0 797 // Prior value is heap allocated so free it.
aoqi@0 798 FREE_C_HEAP_ARRAY(char, old_value, mtInternal);
aoqi@0 799 }
aoqi@0 800 faddr->set_origin(origin);
aoqi@0 801 }
aoqi@0 802
aoqi@0 803 extern "C" {
aoqi@0 804 static int compare_flags(const void* void_a, const void* void_b) {
aoqi@0 805 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
aoqi@0 806 }
aoqi@0 807 }
aoqi@0 808
aoqi@0 809 void CommandLineFlags::printSetFlags(outputStream* out) {
aoqi@0 810 // Print which flags were set on the command line
aoqi@0 811 // note: this method is called before the thread structure is in place
aoqi@0 812 // which means resource allocation cannot be used.
aoqi@0 813
aoqi@0 814 // The last entry is the null entry.
aoqi@0 815 const size_t length = Flag::numFlags - 1;
aoqi@0 816
aoqi@0 817 // Sort
aoqi@0 818 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
aoqi@0 819 for (size_t i = 0; i < length; i++) {
aoqi@0 820 array[i] = &flagTable[i];
aoqi@0 821 }
aoqi@0 822 qsort(array, length, sizeof(Flag*), compare_flags);
aoqi@0 823
aoqi@0 824 // Print
aoqi@0 825 for (size_t i = 0; i < length; i++) {
aoqi@0 826 if (array[i]->get_origin() /* naked field! */) {
aoqi@0 827 array[i]->print_as_flag(out);
aoqi@0 828 out->print(" ");
aoqi@0 829 }
aoqi@0 830 }
aoqi@0 831 out->cr();
aoqi@0 832 FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
aoqi@0 833 }
aoqi@0 834
aoqi@0 835 #ifndef PRODUCT
aoqi@0 836
aoqi@0 837
aoqi@0 838 void CommandLineFlags::verify() {
aoqi@0 839 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
aoqi@0 840 }
aoqi@0 841
aoqi@0 842 #endif // PRODUCT
aoqi@0 843
aoqi@0 844 void CommandLineFlags::printFlags(outputStream* out, bool withComments) {
aoqi@0 845 // Print the flags sorted by name
aoqi@0 846 // note: this method is called before the thread structure is in place
aoqi@0 847 // which means resource allocation cannot be used.
aoqi@0 848
aoqi@0 849 // The last entry is the null entry.
aoqi@0 850 const size_t length = Flag::numFlags - 1;
aoqi@0 851
aoqi@0 852 // Sort
aoqi@0 853 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
aoqi@0 854 for (size_t i = 0; i < length; i++) {
aoqi@0 855 array[i] = &flagTable[i];
aoqi@0 856 }
aoqi@0 857 qsort(array, length, sizeof(Flag*), compare_flags);
aoqi@0 858
aoqi@0 859 // Print
aoqi@0 860 out->print_cr("[Global flags]");
aoqi@0 861 for (size_t i = 0; i < length; i++) {
aoqi@0 862 if (array[i]->is_unlocked()) {
aoqi@0 863 array[i]->print_on(out, withComments);
aoqi@0 864 }
aoqi@0 865 }
aoqi@0 866 FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
aoqi@0 867 }

mercurial