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 const char* Flag::flag_error_str(Flag::Error error) {
 519   switch (error) {
 520     case Flag::MISSING_NAME: return "MISSING_NAME";
 521     case Flag::MISSING_VALUE: return "MISSING_VALUE";
 522     case Flag::NON_WRITABLE: return "NON_WRITABLE";
 523     case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS";
 524     case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT";
 525     case Flag::INVALID_FLAG: return "INVALID_FLAG";
 526     case Flag::ERR_OTHER: return "ERR_OTHER";
 527     case Flag::SUCCESS: return "SUCCESS";
 528     default: ShouldNotReachHere(); return "NULL";
 529   }
 530 }
 531 
 532 // 4991491 do not "optimize out" the was_set false values: omitting them
 533 // tickles a Microsoft compiler bug causing flagTable to be malformed
 534 
 535 #define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name)
 536 
 537 #define RUNTIME_PRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) },
 538 #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) },
 539 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) },
 540 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) },
 541 #define RUNTIME_MANAGEABLE_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) },
 542 #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) },
 543 #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) },
 544 #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) },
 545 #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) },
 546 
 547 #ifdef _LP64
 548 #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) },
 549 #else
 550 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
 551 #endif // _LP64
 552 
 553 #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) },
 554 #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) },
 555 #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) },
 556 #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) },
 557 #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) },
 558 #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) },
 559 
 560 #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) },
 561 #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) },
 562 #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) },
 563 #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) },
 564 #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) },
 565 #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) },
 566 #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) },
 567 
 568 #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) },
 569 #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) },
 570 #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) },
 571 #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) },
 572 #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) },
 573 
 574 #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) },
 575 #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) },
 576 #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) },
 577 #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) },
 578 #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) },
 579 #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) },
 580 
 581 static Flag flagTable[] = {
 582  RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 583                RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 584                RUNTIME_PRODUCT_FLAG_STRUCT, \
 585                RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 586                RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 587                RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
 588                RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 589                RUNTIME_MANAGEABLE_FLAG_STRUCT, \
 590                RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
 591                RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \
 592                IGNORE_RANGE, \
 593                IGNORE_CONSTRAINT)
 594  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 595                   RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 596                   RUNTIME_PRODUCT_FLAG_STRUCT, \
 597                   RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 598                   RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 599                   RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 600                   IGNORE_RANGE, \
 601                   IGNORE_CONSTRAINT)
 602 #if INCLUDE_ALL_GCS
 603  G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 604           RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 605           RUNTIME_PRODUCT_FLAG_STRUCT, \
 606           RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 607           RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 608           RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
 609           RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 610           RUNTIME_MANAGEABLE_FLAG_STRUCT, \
 611           RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
 612           IGNORE_RANGE, \
 613           IGNORE_CONSTRAINT)
 614 #endif // INCLUDE_ALL_GCS
 615 #ifdef COMPILER1
 616  C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
 617           C1_PD_DEVELOP_FLAG_STRUCT, \
 618           C1_PRODUCT_FLAG_STRUCT, \
 619           C1_PD_PRODUCT_FLAG_STRUCT, \
 620           C1_DIAGNOSTIC_FLAG_STRUCT, \
 621           C1_NOTPRODUCT_FLAG_STRUCT, \
 622           IGNORE_RANGE, \
 623           IGNORE_CONSTRAINT)
 624 #endif // COMPILER1
 625 #ifdef COMPILER2
 626  C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \
 627           C2_PD_DEVELOP_FLAG_STRUCT, \
 628           C2_PRODUCT_FLAG_STRUCT, \
 629           C2_PD_PRODUCT_FLAG_STRUCT, \
 630           C2_DIAGNOSTIC_FLAG_STRUCT, \
 631           C2_EXPERIMENTAL_FLAG_STRUCT, \
 632           C2_NOTPRODUCT_FLAG_STRUCT, \
 633           IGNORE_RANGE, \
 634           IGNORE_CONSTRAINT)
 635 #endif // COMPILER2
 636 #ifdef SHARK
 637  SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \
 638              SHARK_PD_DEVELOP_FLAG_STRUCT, \
 639              SHARK_PRODUCT_FLAG_STRUCT, \
 640              SHARK_PD_PRODUCT_FLAG_STRUCT, \
 641              SHARK_DIAGNOSTIC_FLAG_STRUCT, \
 642              SHARK_NOTPRODUCT_FLAG_STRUCT)
 643 #endif // SHARK
 644  ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
 645             ARCH_PRODUCT_FLAG_STRUCT, \
 646             ARCH_DIAGNOSTIC_FLAG_STRUCT, \
 647             ARCH_EXPERIMENTAL_FLAG_STRUCT, \
 648             ARCH_NOTPRODUCT_FLAG_STRUCT, \
 649             IGNORE_RANGE, \
 650             IGNORE_CONSTRAINT)
 651  FLAGTABLE_EXT
 652  {0, NULL, NULL}
 653 };
 654 
 655 Flag* Flag::flags = flagTable;
 656 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
 657 
 658 inline bool str_equal(const char* s, const char* q, size_t len) {
 659   // s is null terminated, q is not!
 660   if (strlen(s) != (unsigned int) len) return false;
 661   return strncmp(s, q, len) == 0;
 662 }
 663 
 664 // Search the flag table for a named flag
 665 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
 666   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 667     if (str_equal(current->_name, name, length)) {
 668       // Found a matching entry.
 669       // Don't report notproduct and develop flags in product builds.
 670       if (current->is_constant_in_binary()) {
 671         return (return_flag ? current : NULL);
 672       }
 673       // Report locked flags only if allowed.
 674       if (!(current->is_unlocked() || current->is_unlocker())) {
 675         if (!allow_locked) {
 676           // disable use of locked flags, e.g. diagnostic, experimental,
 677           // commercial... until they are explicitly unlocked
 678           return NULL;
 679         }
 680       }
 681       return current;
 682     }
 683   }
 684   // Flag name is not in the flag table
 685   return NULL;
 686 }
 687 
 688 // Compute string similarity based on Dice's coefficient
 689 static float str_similar(const char* str1, const char* str2, size_t len2) {
 690   int len1 = (int) strlen(str1);
 691   int total = len1 + (int) len2;
 692 
 693   int hit = 0;
 694 
 695   for (int i = 0; i < len1 -1; ++i) {
 696     for (int j = 0; j < (int) len2 -1; ++j) {
 697       if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
 698         ++hit;
 699         break;
 700       }
 701     }
 702   }
 703 
 704   return 2.0f * (float) hit / (float) total;
 705 }
 706 
 707 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
 708   float VMOptionsFuzzyMatchSimilarity = 0.7f;
 709   Flag* match = NULL;
 710   float score;
 711   float max_score = -1;
 712 
 713   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 714     score = str_similar(current->_name, name, length);
 715     if (score > max_score) {
 716       max_score = score;
 717       match = current;
 718     }
 719   }
 720 
 721   if (!(match->is_unlocked() || match->is_unlocker())) {
 722     if (!allow_locked) {
 723       return NULL;
 724     }
 725   }
 726 
 727   if (max_score < VMOptionsFuzzyMatchSimilarity) {
 728     return NULL;
 729   }
 730 
 731   return match;
 732 }
 733 
 734 // Returns the address of the index'th element
 735 static Flag* address_of_flag(CommandLineFlagWithType flag) {
 736   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 737   return &Flag::flags[flag];
 738 }
 739 
 740 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
 741   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 742   Flag* f = &Flag::flags[flag];
 743   return f->is_default();
 744 }
 745 
 746 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
 747   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 748   Flag* f = &Flag::flags[flag];
 749   return f->is_ergonomic();
 750 }
 751 
 752 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
 753   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 754   Flag* f = &Flag::flags[flag];
 755   return f->is_command_line();
 756 }
 757 
 758 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
 759   Flag* result = Flag::find_flag((char*)name, strlen(name));
 760   if (result == NULL) return false;
 761   *value = result->is_command_line();
 762   return true;
 763 }
 764 
 765 template<class E, class T>
 766 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
 767   E e;
 768   e.set_name(name);
 769   e.set_old_value(old_value);
 770   e.set_new_value(new_value);
 771   e.set_origin(origin);
 772   e.commit();
 773 }
 774 
 775 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose = true) {
 776   Flag::Error status = Flag::SUCCESS;
 777   CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 778   if (constraint != NULL) {
 779     status = constraint->apply_bool(new_value, verbose);
 780   }
 781   return status;
 782 }
 783 
 784 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
 785   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 786   if (result == NULL) return Flag::INVALID_FLAG;
 787   if (!result->is_bool()) return Flag::WRONG_FORMAT;
 788   *value = result->get_bool();
 789   return Flag::SUCCESS;
 790 }
 791 
 792 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
 793   Flag* result = Flag::find_flag(name, len);
 794   if (result == NULL) return Flag::INVALID_FLAG;
 795   if (!result->is_bool()) return Flag::WRONG_FORMAT;
 796   Flag::Error check = apply_constraint_and_check_range_bool(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 797   if (check != Flag::SUCCESS) return check;
 798   bool old_value = result->get_bool();
 799   trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
 800   result->set_bool(*value);
 801   *value = old_value;
 802   result->set_origin(origin);
 803   return Flag::SUCCESS;
 804 }
 805 
 806 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
 807   Flag* faddr = address_of_flag(flag);
 808   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
 809   Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, value);
 810   if (check != Flag::SUCCESS) return check;
 811   trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
 812   faddr->set_bool(value);
 813   faddr->set_origin(origin);
 814   return Flag::SUCCESS;
 815 }
 816 
 817 static Flag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose = true) {
 818   Flag::Error status = Flag::SUCCESS;
 819   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 820   if (range != NULL) {
 821     status = range->check_int(new_value, verbose);
 822   }
 823   if (status == Flag::SUCCESS) {
 824     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 825     if (constraint != NULL) {
 826       status = constraint->apply_int(new_value, verbose);
 827     }
 828   }
 829   return status;
 830 }
 831 
 832 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
 833   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 834   if (result == NULL) return Flag::INVALID_FLAG;
 835   if (!result->is_int()) return Flag::WRONG_FORMAT;
 836   *value = result->get_int();
 837   return Flag::SUCCESS;
 838 }
 839 
 840 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
 841   Flag* result = Flag::find_flag(name, len);
 842   if (result == NULL) return Flag::INVALID_FLAG;
 843   if (!result->is_int()) return Flag::WRONG_FORMAT;
 844   Flag::Error check = apply_constraint_and_check_range_int(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 845   if (check != Flag::SUCCESS) return check;
 846   int old_value = result->get_int();
 847   trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
 848   result->set_int(*value);
 849   *value = old_value;
 850   result->set_origin(origin);
 851   return Flag::SUCCESS;
 852 }
 853 
 854 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
 855   Flag* faddr = address_of_flag(flag);
 856   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
 857   Flag::Error check = apply_constraint_and_check_range_int(faddr->_name, value, !CommandLineFlagConstraintList::validated_after_ergo());
 858   if (check != Flag::SUCCESS) return check;
 859   trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
 860   faddr->set_int(value);
 861   faddr->set_origin(origin);
 862   return Flag::SUCCESS;
 863 }
 864 
 865 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose = true) {
 866   Flag::Error status = Flag::SUCCESS;
 867   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 868   if (range != NULL) {
 869     status = range->check_uint(new_value, verbose);
 870   }
 871   if (status == Flag::SUCCESS) {
 872     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 873     if (constraint != NULL) {
 874       status = constraint->apply_uint(new_value, verbose);
 875     }
 876   }
 877   return status;
 878 }
 879 
 880 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
 881   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 882   if (result == NULL) return Flag::INVALID_FLAG;
 883   if (!result->is_uint()) return Flag::WRONG_FORMAT;
 884   *value = result->get_uint();
 885   return Flag::SUCCESS;
 886 }
 887 
 888 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
 889   Flag* result = Flag::find_flag(name, len);
 890   if (result == NULL) return Flag::INVALID_FLAG;
 891   if (!result->is_uint()) return Flag::WRONG_FORMAT;
 892   Flag::Error check = apply_constraint_and_check_range_uint(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 893   if (check != Flag::SUCCESS) return check;
 894   uint old_value = result->get_uint();
 895   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
 896   result->set_uint(*value);
 897   *value = old_value;
 898   result->set_origin(origin);
 899   return Flag::SUCCESS;
 900 }
 901 
 902 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
 903   Flag* faddr = address_of_flag(flag);
 904   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
 905   Flag::Error check = apply_constraint_and_check_range_uint(faddr->_name, value, !CommandLineFlagConstraintList::validated_after_ergo());
 906   if (check != Flag::SUCCESS) return check;
 907   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
 908   faddr->set_uint(value);
 909   faddr->set_origin(origin);
 910   return Flag::SUCCESS;
 911 }
 912 
 913 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
 914   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 915   if (result == NULL) return Flag::INVALID_FLAG;
 916   if (!result->is_intx()) return Flag::WRONG_FORMAT;
 917   *value = result->get_intx();
 918   return Flag::SUCCESS;
 919 }
 920 
 921 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose = true) {
 922   Flag::Error status = Flag::SUCCESS;
 923   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 924   if (range != NULL) {
 925     status = range->check_intx(new_value, verbose);
 926   }
 927   if (status == Flag::SUCCESS) {
 928     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 929     if (constraint != NULL) {
 930       status = constraint->apply_intx(new_value, verbose);
 931     }
 932   }
 933   return status;
 934 }
 935 
 936 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
 937   Flag* result = Flag::find_flag(name, len);
 938   if (result == NULL) return Flag::INVALID_FLAG;
 939   if (!result->is_intx()) return Flag::WRONG_FORMAT;
 940   Flag::Error check = apply_constraint_and_check_range_intx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 941   if (check != Flag::SUCCESS) return check;
 942   intx old_value = result->get_intx();
 943   trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
 944   result->set_intx(*value);
 945   *value = old_value;
 946   result->set_origin(origin);
 947   return Flag::SUCCESS;
 948 }
 949 
 950 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
 951   Flag* faddr = address_of_flag(flag);
 952   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
 953   Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, value);
 954   if (check != Flag::SUCCESS) return check;
 955   trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
 956   faddr->set_intx(value);
 957   faddr->set_origin(origin);
 958   return Flag::SUCCESS;
 959 }
 960 
 961 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
 962   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 963   if (result == NULL) return Flag::INVALID_FLAG;
 964   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
 965   *value = result->get_uintx();
 966   return Flag::SUCCESS;
 967 }
 968 
 969 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose = true) {
 970   Flag::Error status = Flag::SUCCESS;
 971   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 972   if (range != NULL) {
 973     status = range->check_uintx(new_value, verbose);
 974   }
 975   if (status == Flag::SUCCESS) {
 976     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 977     if (constraint != NULL) {
 978       status = constraint->apply_uintx(new_value, verbose);
 979     }
 980   }
 981   return status;
 982 }
 983 
 984 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
 985   Flag* result = Flag::find_flag(name, len);
 986   if (result == NULL) return Flag::INVALID_FLAG;
 987   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
 988   Flag::Error check = apply_constraint_and_check_range_uintx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 989   if (check != Flag::SUCCESS) return check;
 990   uintx old_value = result->get_uintx();
 991   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
 992   result->set_uintx(*value);
 993   *value = old_value;
 994   result->set_origin(origin);
 995   return Flag::SUCCESS;
 996 }
 997 
 998 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
 999   Flag* faddr = address_of_flag(flag);
1000   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
1001   Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, value);
1002   if (check != Flag::SUCCESS) return check;
1003   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
1004   faddr->set_uintx(value);
1005   faddr->set_origin(origin);
1006   return Flag::SUCCESS;
1007 }
1008 
1009 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
1010   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1011   if (result == NULL) return Flag::INVALID_FLAG;
1012   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1013   *value = result->get_uint64_t();
1014   return Flag::SUCCESS;
1015 }
1016 
1017 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose = true) {
1018   Flag::Error status = Flag::SUCCESS;
1019   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1020   if (range != NULL) {
1021     status = range->check_uint64_t(new_value, verbose);
1022   }
1023   if (status == Flag::SUCCESS) {
1024     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1025     if (constraint != NULL) {
1026       status = constraint->apply_uint64_t(new_value, verbose);
1027     }
1028   }
1029   return status;
1030 }
1031 
1032 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
1033   Flag* result = Flag::find_flag(name, len);
1034   if (result == NULL) return Flag::INVALID_FLAG;
1035   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1036   Flag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1037   if (check != Flag::SUCCESS) return check;
1038   uint64_t old_value = result->get_uint64_t();
1039   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1040   result->set_uint64_t(*value);
1041   *value = old_value;
1042   result->set_origin(origin);
1043   return Flag::SUCCESS;
1044 }
1045 
1046 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
1047   Flag* faddr = address_of_flag(flag);
1048   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
1049   Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, value);
1050   if (check != Flag::SUCCESS) return check;
1051   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
1052   faddr->set_uint64_t(value);
1053   faddr->set_origin(origin);
1054   return Flag::SUCCESS;
1055 }
1056 
1057 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
1058   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1059   if (result == NULL) return Flag::INVALID_FLAG;
1060   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1061   *value = result->get_size_t();
1062   return Flag::SUCCESS;
1063 }
1064 
1065 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose = true) {
1066   Flag::Error status = Flag::SUCCESS;
1067   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1068   if (range != NULL) {
1069     status = range->check_size_t(new_value, verbose);
1070   }
1071   if (status == Flag::SUCCESS) {
1072     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1073     if (constraint != NULL) {
1074       status = constraint->apply_size_t(new_value, verbose);
1075     }
1076   }
1077   return status;
1078 }
1079 
1080 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
1081   Flag* result = Flag::find_flag(name, len);
1082   if (result == NULL) return Flag::INVALID_FLAG;
1083   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1084   Flag::Error check = apply_constraint_and_check_range_size_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1085   if (check != Flag::SUCCESS) return check;
1086   size_t old_value = result->get_size_t();
1087   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1088   result->set_size_t(*value);
1089   *value = old_value;
1090   result->set_origin(origin);
1091   return Flag::SUCCESS;
1092 }
1093 
1094 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
1095   Flag* faddr = address_of_flag(flag);
1096   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
1097   Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, value);
1098   if (check != Flag::SUCCESS) return check;
1099   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
1100   faddr->set_size_t(value);
1101   faddr->set_origin(origin);
1102   return Flag::SUCCESS;
1103 }
1104 
1105 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
1106   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1107   if (result == NULL) return Flag::INVALID_FLAG;
1108   if (!result->is_double()) return Flag::WRONG_FORMAT;
1109   *value = result->get_double();
1110   return Flag::SUCCESS;
1111 }
1112 
1113 static Flag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose = true) {
1114   Flag::Error status = Flag::SUCCESS;
1115   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1116   if (range != NULL) {
1117     status = range->check_double(new_value, verbose);
1118   }
1119   if (status == Flag::SUCCESS) {
1120     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1121     if (constraint != NULL) {
1122       status = constraint->apply_double(new_value, verbose);
1123     }
1124   }
1125   return status;
1126 }
1127 
1128 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
1129   Flag* result = Flag::find_flag(name, len);
1130   if (result == NULL) return Flag::INVALID_FLAG;
1131   if (!result->is_double()) return Flag::WRONG_FORMAT;
1132   Flag::Error check = apply_constraint_and_check_range_double(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1133   if (check != Flag::SUCCESS) return check;
1134   double old_value = result->get_double();
1135   trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
1136   result->set_double(*value);
1137   *value = old_value;
1138   result->set_origin(origin);
1139   return Flag::SUCCESS;
1140 }
1141 
1142 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
1143   Flag* faddr = address_of_flag(flag);
1144   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
1145   Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, value);
1146   if (check != Flag::SUCCESS) return check;
1147   trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
1148   faddr->set_double(value);
1149   faddr->set_origin(origin);
1150   return Flag::SUCCESS;
1151 }
1152 
1153 Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
1154   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1155   if (result == NULL) return Flag::INVALID_FLAG;
1156   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1157   *value = result->get_ccstr();
1158   return Flag::SUCCESS;
1159 }
1160 
1161 Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
1162   Flag* result = Flag::find_flag(name, len);
1163   if (result == NULL) return Flag::INVALID_FLAG;
1164   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1165   ccstr old_value = result->get_ccstr();
1166   trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
1167   char* new_value = NULL;
1168   if (*value != NULL) {
1169     new_value = os::strdup_check_oom(*value);
1170   }
1171   result->set_ccstr(new_value);
1172   if (result->is_default() && old_value != NULL) {
1173     // Prior value is NOT heap allocated, but was a literal constant.
1174     old_value = os::strdup_check_oom(old_value);
1175   }
1176   *value = old_value;
1177   result->set_origin(origin);
1178   return Flag::SUCCESS;
1179 }
1180 
1181 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
1182   Flag* faddr = address_of_flag(flag);
1183   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
1184   ccstr old_value = faddr->get_ccstr();
1185   trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
1186   char* new_value = os::strdup_check_oom(value);
1187   faddr->set_ccstr(new_value);
1188   if (!faddr->is_default() && old_value != NULL) {
1189     // Prior value is heap allocated so free it.
1190     FREE_C_HEAP_ARRAY(char, old_value);
1191   }
1192   faddr->set_origin(origin);
1193   return Flag::SUCCESS;
1194 }
1195 
1196 extern "C" {
1197   static int compare_flags(const void* void_a, const void* void_b) {
1198     return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1199   }
1200 }
1201 
1202 void CommandLineFlags::printSetFlags(outputStream* out) {
1203   // Print which flags were set on the command line
1204   // note: this method is called before the thread structure is in place
1205   //       which means resource allocation cannot be used.
1206 
1207   // The last entry is the null entry.
1208   const size_t length = Flag::numFlags - 1;
1209 
1210   // Sort
1211   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1212   for (size_t i = 0; i < length; i++) {
1213     array[i] = &flagTable[i];
1214   }
1215   qsort(array, length, sizeof(Flag*), compare_flags);
1216 
1217   // Print
1218   for (size_t i = 0; i < length; i++) {
1219     if (array[i]->get_origin() /* naked field! */) {
1220       array[i]->print_as_flag(out);
1221       out->print(" ");
1222     }
1223   }
1224   out->cr();
1225   FREE_C_HEAP_ARRAY(Flag*, array);
1226 }
1227 
1228 #ifndef PRODUCT
1229 
1230 void CommandLineFlags::verify() {
1231   assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
1232 }
1233 
1234 #endif // PRODUCT
1235 
1236 #define ONLY_PRINT_PRODUCT_FLAGS
1237 
1238 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
1239   // Print the flags sorted by name
1240   // note: this method is called before the thread structure is in place
1241   //       which means resource allocation cannot be used.
1242 
1243   // The last entry is the null entry.
1244   const size_t length = Flag::numFlags - 1;
1245 
1246   // Sort
1247   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1248   for (size_t i = 0; i < length; i++) {
1249     array[i] = &flagTable[i];
1250   }
1251   qsort(array, length, sizeof(Flag*), compare_flags);
1252 
1253   // Print
1254   if (!printRanges) {
1255     out->print_cr("[Global flags]");
1256   } else {
1257     out->print_cr("[Global flags ranges]");
1258   }
1259 
1260   for (size_t i = 0; i < length; i++) {
1261     if (array[i]->is_unlocked()) {
1262 #ifdef ONLY_PRINT_PRODUCT_FLAGS
1263       if (!array[i]->is_notproduct() && !array[i]->is_develop())
1264 #endif // ONLY_PRINT_PRODUCT_FLAGS
1265       array[i]->print_on(out, withComments, printRanges);
1266     }
1267   }
1268   FREE_C_HEAP_ARRAY(Flag*, array);
1269 }