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