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