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,
 314                  "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n"
 315                  "Error: The unlock option must precede '%s'.\n",
 316                  _name, _name);
 317     return;
 318   }
 319   if (is_experimental() && !is_unlocked()) {
 320     jio_snprintf(buf, buflen,
 321                  "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n"
 322                  "Error: The unlock option must precede '%s'.\n",
 323                  _name, _name);
 324     return;
 325   }
 326   if (is_develop() && is_product_build()) {
 327     jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n",
 328                  _name);
 329     return;
 330   }
 331   if (is_notproduct() && is_product_build()) {
 332     jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
 333                  _name);
 334     return;
 335   }
 336   get_locked_message_ext(buf, buflen);
 337 }
 338 
 339 bool Flag::is_writeable() const {
 340   return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
 341 }
 342 
 343 // All flags except "manageable" are assumed to be internal flags.
 344 // Long term, we need to define a mechanism to specify which flags
 345 // are external/stable and change this function accordingly.
 346 bool Flag::is_external() const {
 347   return is_manageable() || is_external_ext();
 348 }
 349 
 350 
 351 // Length of format string (e.g. "%.1234s") for printing ccstr below
 352 #define FORMAT_BUFFER_LEN 16
 353 
 354 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
 355 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
 356   // Don't print notproduct and develop flags in a product build.
 357   if (is_constant_in_binary()) {
 358     return;
 359   }
 360 
 361   if (!printRanges) {
 362 
 363     st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
 364 
 365     if (is_bool()) {
 366       st->print("%-16s", get_bool() ? "true" : "false");
 367     } else if (is_int()) {
 368       st->print("%-16d", get_int());
 369     } else if (is_uint()) {
 370       st->print("%-16u", get_uint());
 371     } else if (is_intx()) {
 372       st->print("%-16ld", get_intx());
 373     } else if (is_uintx()) {
 374       st->print("%-16lu", get_uintx());
 375     } else if (is_uint64_t()) {
 376       st->print("%-16lu", get_uint64_t());
 377     } else if (is_size_t()) {
 378       st->print(SIZE_FORMAT_W(-16), get_size_t());
 379     } else if (is_double()) {
 380       st->print("%-16f", get_double());
 381     } else if (is_ccstr()) {
 382       const char* cp = get_ccstr();
 383       if (cp != NULL) {
 384         const char* eol;
 385         while ((eol = strchr(cp, '\n')) != NULL) {
 386           char format_buffer[FORMAT_BUFFER_LEN];
 387           size_t llen = pointer_delta(eol, cp, sizeof(char));
 388           jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
 389                        "%%." SIZE_FORMAT "s", llen);
 390           PRAGMA_DIAG_PUSH
 391           PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
 392           st->print(format_buffer, cp);
 393           PRAGMA_DIAG_POP
 394           st->cr();
 395           cp = eol+1;
 396           st->print("%5s %-35s += ", "", _name);
 397         }
 398         st->print("%-16s", cp);
 399       }
 400       else st->print("%-16s", "");
 401     }
 402 
 403     st->print("%-20s", " ");
 404     print_kind(st);
 405 
 406 #ifndef PRODUCT
 407     if (withComments) {
 408       st->print("%s", _doc);
 409     }
 410 #endif
 411 
 412     st->cr();
 413 
 414   } else if (!is_bool() && !is_ccstr()) {
 415 
 416     if (printRanges) {
 417 
 418       st->print("%9s %-50s ", _type, _name);
 419 
 420       CommandLineFlagRangeList::print(_name, st, true);
 421 
 422       st->print(" %-20s", " ");
 423       print_kind(st);
 424 
 425 #ifndef PRODUCT
 426       if (withComments) {
 427         st->print("%s", _doc);
 428       }
 429 #endif
 430 
 431       st->cr();
 432 
 433     }
 434   }
 435 }
 436 
 437 void Flag::print_kind(outputStream* st) {
 438   struct Data {
 439     int flag;
 440     const char* name;
 441   };
 442 
 443   Data data[] = {
 444       { KIND_C1, "C1" },
 445       { KIND_C2, "C2" },
 446       { KIND_ARCH, "ARCH" },
 447       { KIND_SHARK, "SHARK" },
 448       { KIND_PLATFORM_DEPENDENT, "pd" },
 449       { KIND_PRODUCT, "product" },
 450       { KIND_MANAGEABLE, "manageable" },
 451       { KIND_DIAGNOSTIC, "diagnostic" },
 452       { KIND_EXPERIMENTAL, "experimental" },
 453       { KIND_COMMERCIAL, "commercial" },
 454       { KIND_NOT_PRODUCT, "notproduct" },
 455       { KIND_DEVELOP, "develop" },
 456       { KIND_LP64_PRODUCT, "lp64_product" },
 457       { KIND_READ_WRITE, "rw" },
 458       { -1, "" }
 459   };
 460 
 461   if ((_flags & KIND_MASK) != 0) {
 462     st->print("{");
 463     bool is_first = true;
 464 
 465     for (int i = 0; data[i].flag != -1; i++) {
 466       Data d = data[i];
 467       if ((_flags & d.flag) != 0) {
 468         if (is_first) {
 469           is_first = false;
 470         } else {
 471           st->print(" ");
 472         }
 473         st->print("%s", d.name);
 474       }
 475     }
 476 
 477     st->print("}");
 478   }
 479 }
 480 
 481 void Flag::print_as_flag(outputStream* st) {
 482   if (is_bool()) {
 483     st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
 484   } else if (is_int()) {
 485     st->print("-XX:%s=%d", _name, get_int());
 486   } else if (is_uint()) {
 487     st->print("-XX:%s=%u", _name, get_uint());
 488   } else if (is_intx()) {
 489     st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
 490   } else if (is_uintx()) {
 491     st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
 492   } else if (is_uint64_t()) {
 493     st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
 494   } else if (is_size_t()) {
 495     st->print("-XX:%s=" SIZE_FORMAT, _name, get_size_t());
 496   } else if (is_double()) {
 497     st->print("-XX:%s=%f", _name, get_double());
 498   } else if (is_ccstr()) {
 499     st->print("-XX:%s=", _name);
 500     const char* cp = get_ccstr();
 501     if (cp != NULL) {
 502       // Need to turn embedded '\n's back into separate arguments
 503       // Not so efficient to print one character at a time,
 504       // but the choice is to do the transformation to a buffer
 505       // and print that.  And this need not be efficient.
 506       for (; *cp != '\0'; cp += 1) {
 507         switch (*cp) {
 508           default:
 509             st->print("%c", *cp);
 510             break;
 511           case '\n':
 512             st->print(" -XX:%s=", _name);
 513             break;
 514         }
 515       }
 516     }
 517   } else {
 518     ShouldNotReachHere();
 519   }
 520 }
 521 
 522 const char* Flag::flag_error_str(Flag::Error error) {
 523   switch (error) {
 524     case Flag::MISSING_NAME: return "MISSING_NAME";
 525     case Flag::MISSING_VALUE: return "MISSING_VALUE";
 526     case Flag::NON_WRITABLE: return "NON_WRITABLE";
 527     case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS";
 528     case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT";
 529     case Flag::INVALID_FLAG: return "INVALID_FLAG";
 530     case Flag::ERR_OTHER: return "ERR_OTHER";
 531     case Flag::SUCCESS: return "SUCCESS";
 532     default: ShouldNotReachHere(); return "NULL";
 533   }
 534 }
 535 
 536 // 4991491 do not "optimize out" the was_set false values: omitting them
 537 // tickles a Microsoft compiler bug causing flagTable to be malformed
 538 
 539 #define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name)
 540 
 541 #define RUNTIME_PRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) },
 542 #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) },
 543 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) },
 544 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) },
 545 #define RUNTIME_MANAGEABLE_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) },
 546 #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) },
 547 #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) },
 548 #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) },
 549 #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) },
 550 
 551 #ifdef _LP64
 552 #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) },
 553 #else
 554 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
 555 #endif // _LP64
 556 
 557 #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) },
 558 #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) },
 559 #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) },
 560 #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) },
 561 #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) },
 562 #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) },
 563 
 564 #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) },
 565 #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) },
 566 #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) },
 567 #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) },
 568 #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) },
 569 #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) },
 570 #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) },
 571 
 572 #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) },
 573 #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) },
 574 #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) },
 575 #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) },
 576 #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) },
 577 
 578 #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) },
 579 #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) },
 580 #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) },
 581 #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) },
 582 #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) },
 583 #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) },
 584 
 585 static Flag flagTable[] = {
 586  RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 587                RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 588                RUNTIME_PRODUCT_FLAG_STRUCT, \
 589                RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 590                RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 591                RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
 592                RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 593                RUNTIME_MANAGEABLE_FLAG_STRUCT, \
 594                RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
 595                RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \
 596                IGNORE_RANGE, \
 597                IGNORE_CONSTRAINT)
 598  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 599                   RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 600                   RUNTIME_PRODUCT_FLAG_STRUCT, \
 601                   RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 602                   RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 603                   RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 604                   IGNORE_RANGE, \
 605                   IGNORE_CONSTRAINT)
 606 #if INCLUDE_ALL_GCS
 607  G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 608           RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 609           RUNTIME_PRODUCT_FLAG_STRUCT, \
 610           RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 611           RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 612           RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
 613           RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 614           RUNTIME_MANAGEABLE_FLAG_STRUCT, \
 615           RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
 616           IGNORE_RANGE, \
 617           IGNORE_CONSTRAINT)
 618 #endif // INCLUDE_ALL_GCS
 619 #ifdef COMPILER1
 620  C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
 621           C1_PD_DEVELOP_FLAG_STRUCT, \
 622           C1_PRODUCT_FLAG_STRUCT, \
 623           C1_PD_PRODUCT_FLAG_STRUCT, \
 624           C1_DIAGNOSTIC_FLAG_STRUCT, \
 625           C1_NOTPRODUCT_FLAG_STRUCT, \
 626           IGNORE_RANGE, \
 627           IGNORE_CONSTRAINT)
 628 #endif // COMPILER1
 629 #ifdef COMPILER2
 630  C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \
 631           C2_PD_DEVELOP_FLAG_STRUCT, \
 632           C2_PRODUCT_FLAG_STRUCT, \
 633           C2_PD_PRODUCT_FLAG_STRUCT, \
 634           C2_DIAGNOSTIC_FLAG_STRUCT, \
 635           C2_EXPERIMENTAL_FLAG_STRUCT, \
 636           C2_NOTPRODUCT_FLAG_STRUCT, \
 637           IGNORE_RANGE, \
 638           IGNORE_CONSTRAINT)
 639 #endif // COMPILER2
 640 #ifdef SHARK
 641  SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \
 642              SHARK_PD_DEVELOP_FLAG_STRUCT, \
 643              SHARK_PRODUCT_FLAG_STRUCT, \
 644              SHARK_PD_PRODUCT_FLAG_STRUCT, \
 645              SHARK_DIAGNOSTIC_FLAG_STRUCT, \
 646              SHARK_NOTPRODUCT_FLAG_STRUCT)
 647 #endif // SHARK
 648  ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
 649             ARCH_PRODUCT_FLAG_STRUCT, \
 650             ARCH_DIAGNOSTIC_FLAG_STRUCT, \
 651             ARCH_EXPERIMENTAL_FLAG_STRUCT, \
 652             ARCH_NOTPRODUCT_FLAG_STRUCT, \
 653             IGNORE_RANGE, \
 654             IGNORE_CONSTRAINT)
 655  FLAGTABLE_EXT
 656  {0, NULL, NULL}
 657 };
 658 
 659 Flag* Flag::flags = flagTable;
 660 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
 661 
 662 inline bool str_equal(const char* s, const char* q, size_t len) {
 663   // s is null terminated, q is not!
 664   if (strlen(s) != (unsigned int) len) return false;
 665   return strncmp(s, q, len) == 0;
 666 }
 667 
 668 // Search the flag table for a named flag
 669 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
 670   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 671     if (str_equal(current->_name, name, length)) {
 672       // Found a matching entry.
 673       // Don't report notproduct and develop flags in product builds.
 674       if (current->is_constant_in_binary()) {
 675         return (return_flag ? current : NULL);
 676       }
 677       // Report locked flags only if allowed.
 678       if (!(current->is_unlocked() || current->is_unlocker())) {
 679         if (!allow_locked) {
 680           // disable use of locked flags, e.g. diagnostic, experimental,
 681           // commercial... until they are explicitly unlocked
 682           return NULL;
 683         }
 684       }
 685       return current;
 686     }
 687   }
 688   // Flag name is not in the flag table
 689   return NULL;
 690 }
 691 
 692 // Compute string similarity based on Dice's coefficient
 693 static float str_similar(const char* str1, const char* str2, size_t len2) {
 694   int len1 = (int) strlen(str1);
 695   int total = len1 + (int) len2;
 696 
 697   int hit = 0;
 698 
 699   for (int i = 0; i < len1 -1; ++i) {
 700     for (int j = 0; j < (int) len2 -1; ++j) {
 701       if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
 702         ++hit;
 703         break;
 704       }
 705     }
 706   }
 707 
 708   return 2.0f * (float) hit / (float) total;
 709 }
 710 
 711 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
 712   float VMOptionsFuzzyMatchSimilarity = 0.7f;
 713   Flag* match = NULL;
 714   float score;
 715   float max_score = -1;
 716 
 717   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 718     score = str_similar(current->_name, name, length);
 719     if (score > max_score) {
 720       max_score = score;
 721       match = current;
 722     }
 723   }
 724 
 725   if (!(match->is_unlocked() || match->is_unlocker())) {
 726     if (!allow_locked) {
 727       return NULL;
 728     }
 729   }
 730 
 731   if (max_score < VMOptionsFuzzyMatchSimilarity) {
 732     return NULL;
 733   }
 734 
 735   return match;
 736 }
 737 
 738 // Returns the address of the index'th element
 739 static Flag* address_of_flag(CommandLineFlagWithType flag) {
 740   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 741   return &Flag::flags[flag];
 742 }
 743 
 744 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
 745   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 746   Flag* f = &Flag::flags[flag];
 747   return f->is_default();
 748 }
 749 
 750 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
 751   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 752   Flag* f = &Flag::flags[flag];
 753   return f->is_ergonomic();
 754 }
 755 
 756 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
 757   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 758   Flag* f = &Flag::flags[flag];
 759   return f->is_command_line();
 760 }
 761 
 762 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
 763   Flag* result = Flag::find_flag((char*)name, strlen(name));
 764   if (result == NULL) return false;
 765   *value = result->is_command_line();
 766   return true;
 767 }
 768 
 769 template<class E, class T>
 770 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
 771   E e;
 772   e.set_name(name);
 773   e.set_old_value(old_value);
 774   e.set_new_value(new_value);
 775   e.set_origin(origin);
 776   e.commit();
 777 }
 778 
 779 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose = true) {
 780   Flag::Error status = Flag::SUCCESS;
 781   CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 782   if (constraint != NULL) {
 783     status = constraint->apply_bool(new_value, verbose);
 784   }
 785   return status;
 786 }
 787 
 788 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
 789   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 790   if (result == NULL) return Flag::INVALID_FLAG;
 791   if (!result->is_bool()) return Flag::WRONG_FORMAT;
 792   *value = result->get_bool();
 793   return Flag::SUCCESS;
 794 }
 795 
 796 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
 797   Flag* result = Flag::find_flag(name, len);
 798   if (result == NULL) return Flag::INVALID_FLAG;
 799   if (!result->is_bool()) return Flag::WRONG_FORMAT;
 800   Flag::Error check = apply_constraint_and_check_range_bool(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 801   if (check != Flag::SUCCESS) return check;
 802   bool old_value = result->get_bool();
 803   trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
 804   result->set_bool(*value);
 805   *value = old_value;
 806   result->set_origin(origin);
 807   return Flag::SUCCESS;
 808 }
 809 
 810 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
 811   Flag* faddr = address_of_flag(flag);
 812   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
 813   Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, value);
 814   if (check != Flag::SUCCESS) return check;
 815   trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
 816   faddr->set_bool(value);
 817   faddr->set_origin(origin);
 818   return Flag::SUCCESS;
 819 }
 820 
 821 static Flag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose = true) {
 822   Flag::Error status = Flag::SUCCESS;
 823   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 824   if (range != NULL) {
 825     status = range->check_int(new_value, verbose);
 826   }
 827   if (status == Flag::SUCCESS) {
 828     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 829     if (constraint != NULL) {
 830       status = constraint->apply_int(new_value, verbose);
 831     }
 832   }
 833   return status;
 834 }
 835 
 836 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
 837   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 838   if (result == NULL) return Flag::INVALID_FLAG;
 839   if (!result->is_int()) return Flag::WRONG_FORMAT;
 840   *value = result->get_int();
 841   return Flag::SUCCESS;
 842 }
 843 
 844 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
 845   Flag* result = Flag::find_flag(name, len);
 846   if (result == NULL) return Flag::INVALID_FLAG;
 847   if (!result->is_int()) return Flag::WRONG_FORMAT;
 848   Flag::Error check = apply_constraint_and_check_range_int(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 849   if (check != Flag::SUCCESS) return check;
 850   int old_value = result->get_int();
 851   trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
 852   result->set_int(*value);
 853   *value = old_value;
 854   result->set_origin(origin);
 855   return Flag::SUCCESS;
 856 }
 857 
 858 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
 859   Flag* faddr = address_of_flag(flag);
 860   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
 861   Flag::Error check = apply_constraint_and_check_range_int(faddr->_name, value, !CommandLineFlagConstraintList::validated_after_ergo());
 862   if (check != Flag::SUCCESS) return check;
 863   trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
 864   faddr->set_int(value);
 865   faddr->set_origin(origin);
 866   return Flag::SUCCESS;
 867 }
 868 
 869 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose = true) {
 870   Flag::Error status = Flag::SUCCESS;
 871   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 872   if (range != NULL) {
 873     status = range->check_uint(new_value, verbose);
 874   }
 875   if (status == Flag::SUCCESS) {
 876     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 877     if (constraint != NULL) {
 878       status = constraint->apply_uint(new_value, verbose);
 879     }
 880   }
 881   return status;
 882 }
 883 
 884 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
 885   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 886   if (result == NULL) return Flag::INVALID_FLAG;
 887   if (!result->is_uint()) return Flag::WRONG_FORMAT;
 888   *value = result->get_uint();
 889   return Flag::SUCCESS;
 890 }
 891 
 892 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
 893   Flag* result = Flag::find_flag(name, len);
 894   if (result == NULL) return Flag::INVALID_FLAG;
 895   if (!result->is_uint()) return Flag::WRONG_FORMAT;
 896   Flag::Error check = apply_constraint_and_check_range_uint(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 897   if (check != Flag::SUCCESS) return check;
 898   uint old_value = result->get_uint();
 899   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
 900   result->set_uint(*value);
 901   *value = old_value;
 902   result->set_origin(origin);
 903   return Flag::SUCCESS;
 904 }
 905 
 906 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
 907   Flag* faddr = address_of_flag(flag);
 908   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
 909   Flag::Error check = apply_constraint_and_check_range_uint(faddr->_name, value, !CommandLineFlagConstraintList::validated_after_ergo());
 910   if (check != Flag::SUCCESS) return check;
 911   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
 912   faddr->set_uint(value);
 913   faddr->set_origin(origin);
 914   return Flag::SUCCESS;
 915 }
 916 
 917 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
 918   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 919   if (result == NULL) return Flag::INVALID_FLAG;
 920   if (!result->is_intx()) return Flag::WRONG_FORMAT;
 921   *value = result->get_intx();
 922   return Flag::SUCCESS;
 923 }
 924 
 925 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose = true) {
 926   Flag::Error status = Flag::SUCCESS;
 927   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 928   if (range != NULL) {
 929     status = range->check_intx(new_value, verbose);
 930   }
 931   if (status == Flag::SUCCESS) {
 932     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 933     if (constraint != NULL) {
 934       status = constraint->apply_intx(new_value, verbose);
 935     }
 936   }
 937   return status;
 938 }
 939 
 940 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
 941   Flag* result = Flag::find_flag(name, len);
 942   if (result == NULL) return Flag::INVALID_FLAG;
 943   if (!result->is_intx()) return Flag::WRONG_FORMAT;
 944   Flag::Error check = apply_constraint_and_check_range_intx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 945   if (check != Flag::SUCCESS) return check;
 946   intx old_value = result->get_intx();
 947   trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
 948   result->set_intx(*value);
 949   *value = old_value;
 950   result->set_origin(origin);
 951   return Flag::SUCCESS;
 952 }
 953 
 954 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
 955   Flag* faddr = address_of_flag(flag);
 956   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
 957   Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, value);
 958   if (check != Flag::SUCCESS) return check;
 959   trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
 960   faddr->set_intx(value);
 961   faddr->set_origin(origin);
 962   return Flag::SUCCESS;
 963 }
 964 
 965 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
 966   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 967   if (result == NULL) return Flag::INVALID_FLAG;
 968   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
 969   *value = result->get_uintx();
 970   return Flag::SUCCESS;
 971 }
 972 
 973 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose = true) {
 974   Flag::Error status = Flag::SUCCESS;
 975   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 976   if (range != NULL) {
 977     status = range->check_uintx(new_value, verbose);
 978   }
 979   if (status == Flag::SUCCESS) {
 980     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 981     if (constraint != NULL) {
 982       status = constraint->apply_uintx(new_value, verbose);
 983     }
 984   }
 985   return status;
 986 }
 987 
 988 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
 989   Flag* result = Flag::find_flag(name, len);
 990   if (result == NULL) return Flag::INVALID_FLAG;
 991   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
 992   Flag::Error check = apply_constraint_and_check_range_uintx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 993   if (check != Flag::SUCCESS) return check;
 994   uintx old_value = result->get_uintx();
 995   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
 996   result->set_uintx(*value);
 997   *value = old_value;
 998   result->set_origin(origin);
 999   return Flag::SUCCESS;
1000 }
1001 
1002 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
1003   Flag* faddr = address_of_flag(flag);
1004   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
1005   Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, value);
1006   if (check != Flag::SUCCESS) return check;
1007   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
1008   faddr->set_uintx(value);
1009   faddr->set_origin(origin);
1010   return Flag::SUCCESS;
1011 }
1012 
1013 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
1014   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1015   if (result == NULL) return Flag::INVALID_FLAG;
1016   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1017   *value = result->get_uint64_t();
1018   return Flag::SUCCESS;
1019 }
1020 
1021 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose = true) {
1022   Flag::Error status = Flag::SUCCESS;
1023   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1024   if (range != NULL) {
1025     status = range->check_uint64_t(new_value, verbose);
1026   }
1027   if (status == Flag::SUCCESS) {
1028     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1029     if (constraint != NULL) {
1030       status = constraint->apply_uint64_t(new_value, verbose);
1031     }
1032   }
1033   return status;
1034 }
1035 
1036 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
1037   Flag* result = Flag::find_flag(name, len);
1038   if (result == NULL) return Flag::INVALID_FLAG;
1039   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1040   Flag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1041   if (check != Flag::SUCCESS) return check;
1042   uint64_t old_value = result->get_uint64_t();
1043   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1044   result->set_uint64_t(*value);
1045   *value = old_value;
1046   result->set_origin(origin);
1047   return Flag::SUCCESS;
1048 }
1049 
1050 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
1051   Flag* faddr = address_of_flag(flag);
1052   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
1053   Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, value);
1054   if (check != Flag::SUCCESS) return check;
1055   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
1056   faddr->set_uint64_t(value);
1057   faddr->set_origin(origin);
1058   return Flag::SUCCESS;
1059 }
1060 
1061 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
1062   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1063   if (result == NULL) return Flag::INVALID_FLAG;
1064   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1065   *value = result->get_size_t();
1066   return Flag::SUCCESS;
1067 }
1068 
1069 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose = true) {
1070   Flag::Error status = Flag::SUCCESS;
1071   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1072   if (range != NULL) {
1073     status = range->check_size_t(new_value, verbose);
1074   }
1075   if (status == Flag::SUCCESS) {
1076     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1077     if (constraint != NULL) {
1078       status = constraint->apply_size_t(new_value, verbose);
1079     }
1080   }
1081   return status;
1082 }
1083 
1084 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
1085   Flag* result = Flag::find_flag(name, len);
1086   if (result == NULL) return Flag::INVALID_FLAG;
1087   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1088   Flag::Error check = apply_constraint_and_check_range_size_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1089   if (check != Flag::SUCCESS) return check;
1090   size_t old_value = result->get_size_t();
1091   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1092   result->set_size_t(*value);
1093   *value = old_value;
1094   result->set_origin(origin);
1095   return Flag::SUCCESS;
1096 }
1097 
1098 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
1099   Flag* faddr = address_of_flag(flag);
1100   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
1101   Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, value);
1102   if (check != Flag::SUCCESS) return check;
1103   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
1104   faddr->set_size_t(value);
1105   faddr->set_origin(origin);
1106   return Flag::SUCCESS;
1107 }
1108 
1109 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
1110   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1111   if (result == NULL) return Flag::INVALID_FLAG;
1112   if (!result->is_double()) return Flag::WRONG_FORMAT;
1113   *value = result->get_double();
1114   return Flag::SUCCESS;
1115 }
1116 
1117 static Flag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose = true) {
1118   Flag::Error status = Flag::SUCCESS;
1119   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1120   if (range != NULL) {
1121     status = range->check_double(new_value, verbose);
1122   }
1123   if (status == Flag::SUCCESS) {
1124     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1125     if (constraint != NULL) {
1126       status = constraint->apply_double(new_value, verbose);
1127     }
1128   }
1129   return status;
1130 }
1131 
1132 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
1133   Flag* result = Flag::find_flag(name, len);
1134   if (result == NULL) return Flag::INVALID_FLAG;
1135   if (!result->is_double()) return Flag::WRONG_FORMAT;
1136   Flag::Error check = apply_constraint_and_check_range_double(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1137   if (check != Flag::SUCCESS) return check;
1138   double old_value = result->get_double();
1139   trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
1140   result->set_double(*value);
1141   *value = old_value;
1142   result->set_origin(origin);
1143   return Flag::SUCCESS;
1144 }
1145 
1146 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
1147   Flag* faddr = address_of_flag(flag);
1148   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
1149   Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, value);
1150   if (check != Flag::SUCCESS) return check;
1151   trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
1152   faddr->set_double(value);
1153   faddr->set_origin(origin);
1154   return Flag::SUCCESS;
1155 }
1156 
1157 Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
1158   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1159   if (result == NULL) return Flag::INVALID_FLAG;
1160   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1161   *value = result->get_ccstr();
1162   return Flag::SUCCESS;
1163 }
1164 
1165 Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
1166   Flag* result = Flag::find_flag(name, len);
1167   if (result == NULL) return Flag::INVALID_FLAG;
1168   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1169   ccstr old_value = result->get_ccstr();
1170   trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
1171   char* new_value = NULL;
1172   if (*value != NULL) {
1173     new_value = os::strdup_check_oom(*value);
1174   }
1175   result->set_ccstr(new_value);
1176   if (result->is_default() && old_value != NULL) {
1177     // Prior value is NOT heap allocated, but was a literal constant.
1178     old_value = os::strdup_check_oom(old_value);
1179   }
1180   *value = old_value;
1181   result->set_origin(origin);
1182   return Flag::SUCCESS;
1183 }
1184 
1185 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
1186   Flag* faddr = address_of_flag(flag);
1187   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
1188   ccstr old_value = faddr->get_ccstr();
1189   trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
1190   char* new_value = os::strdup_check_oom(value);
1191   faddr->set_ccstr(new_value);
1192   if (!faddr->is_default() && old_value != NULL) {
1193     // Prior value is heap allocated so free it.
1194     FREE_C_HEAP_ARRAY(char, old_value);
1195   }
1196   faddr->set_origin(origin);
1197   return Flag::SUCCESS;
1198 }
1199 
1200 extern "C" {
1201   static int compare_flags(const void* void_a, const void* void_b) {
1202     return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1203   }
1204 }
1205 
1206 void CommandLineFlags::printSetFlags(outputStream* out) {
1207   // Print which flags were set on the command line
1208   // note: this method is called before the thread structure is in place
1209   //       which means resource allocation cannot be used.
1210 
1211   // The last entry is the null entry.
1212   const size_t length = Flag::numFlags - 1;
1213 
1214   // Sort
1215   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1216   for (size_t i = 0; i < length; i++) {
1217     array[i] = &flagTable[i];
1218   }
1219   qsort(array, length, sizeof(Flag*), compare_flags);
1220 
1221   // Print
1222   for (size_t i = 0; i < length; i++) {
1223     if (array[i]->get_origin() /* naked field! */) {
1224       array[i]->print_as_flag(out);
1225       out->print(" ");
1226     }
1227   }
1228   out->cr();
1229   FREE_C_HEAP_ARRAY(Flag*, array);
1230 }
1231 
1232 #ifndef PRODUCT
1233 
1234 void CommandLineFlags::verify() {
1235   assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
1236 }
1237 
1238 #endif // PRODUCT
1239 
1240 #define ONLY_PRINT_PRODUCT_FLAGS
1241 
1242 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
1243   // Print the flags sorted by name
1244   // note: this method is called before the thread structure is in place
1245   //       which means resource allocation cannot be used.
1246 
1247   // The last entry is the null entry.
1248   const size_t length = Flag::numFlags - 1;
1249 
1250   // Sort
1251   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1252   for (size_t i = 0; i < length; i++) {
1253     array[i] = &flagTable[i];
1254   }
1255   qsort(array, length, sizeof(Flag*), compare_flags);
1256 
1257   // Print
1258   if (!printRanges) {
1259     out->print_cr("[Global flags]");
1260   } else {
1261     out->print_cr("[Global flags ranges]");
1262   }
1263 
1264   for (size_t i = 0; i < length; i++) {
1265     if (array[i]->is_unlocked()) {
1266 #ifdef ONLY_PRINT_PRODUCT_FLAGS
1267       if (!array[i]->is_notproduct() && !array[i]->is_develop())
1268 #endif // ONLY_PRINT_PRODUCT_FLAGS
1269       array[i]->print_on(out, withComments, printRanges);
1270     }
1271   }
1272   FREE_C_HEAP_ARRAY(Flag*, array);
1273 }