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