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 printRanges, bool withComments) {
 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 == true ? current : NULL);
 658       }
 659       // Report locked flags only if allowed.
 660       if (!(current->is_unlocked() || current->is_unlocker())) {
 661         if (!allow_locked) {
 662           // disable use of locked flags, e.g. diagnostic, experimental,
 663           // commercial... until they are explicitly unlocked
 664           return NULL;
 665         }
 666       }
 667       return current;
 668     }
 669   }
 670   // Flag name is not in the flag table
 671   return NULL;
 672 }
 673 
 674 // Compute string similarity based on Dice's coefficient
 675 static float str_similar(const char* str1, const char* str2, size_t len2) {
 676   int len1 = (int) strlen(str1);
 677   int total = len1 + (int) len2;
 678 
 679   int hit = 0;
 680 
 681   for (int i = 0; i < len1 -1; ++i) {
 682     for (int j = 0; j < (int) len2 -1; ++j) {
 683       if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
 684         ++hit;
 685         break;
 686       }
 687     }
 688   }
 689 
 690   return 2.0f * (float) hit / (float) total;
 691 }
 692 
 693 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
 694   float VMOptionsFuzzyMatchSimilarity = 0.7f;
 695   Flag* match = NULL;
 696   float score;
 697   float max_score = -1;
 698 
 699   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 700     score = str_similar(current->_name, name, length);
 701     if (score > max_score) {
 702       max_score = score;
 703       match = current;
 704     }
 705   }
 706 
 707   if (!(match->is_unlocked() || match->is_unlocker())) {
 708     if (!allow_locked) {
 709       return NULL;
 710     }
 711   }
 712 
 713   if (max_score < VMOptionsFuzzyMatchSimilarity) {
 714     return NULL;
 715   }
 716 
 717   return match;
 718 }
 719 
 720 // Returns the address of the index'th element
 721 static Flag* address_of_flag(CommandLineFlagWithType flag) {
 722   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 723   return &Flag::flags[flag];
 724 }
 725 
 726 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
 727   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 728   Flag* f = &Flag::flags[flag];
 729   return f->is_default();
 730 }
 731 
 732 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
 733   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 734   Flag* f = &Flag::flags[flag];
 735   return f->is_ergonomic();
 736 }
 737 
 738 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
 739   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 740   Flag* f = &Flag::flags[flag];
 741   return f->is_command_line();
 742 }
 743 
 744 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
 745   Flag* result = Flag::find_flag((char*)name, strlen(name));
 746   if (result == NULL) return false;
 747   *value = result->is_command_line();
 748   return true;
 749 }
 750 
 751 template<class E, class T>
 752 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
 753   E e;
 754   e.set_name(name);
 755   e.set_old_value(old_value);
 756   e.set_new_value(new_value);
 757   e.set_origin(origin);
 758   e.commit();
 759 }
 760 
 761 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool* new_value, bool verbose = true) {
 762   Flag::Error status = Flag::SUCCESS;
 763   CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
 764   if (constraint != NULL) {
 765     status = constraint->apply_bool(new_value, verbose);
 766   }
 767   return status;
 768 }
 769 
 770 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
 771   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 772   if (result == NULL) return Flag::INVALID_FLAG;
 773   if (!result->is_bool()) return Flag::WRONG_FORMAT;
 774   *value = result->get_bool();
 775   return Flag::SUCCESS;
 776 }
 777 
 778 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
 779   Flag* result = Flag::find_flag(name, len);
 780   if (result == NULL) return Flag::INVALID_FLAG;
 781   if (!result->is_bool()) return Flag::WRONG_FORMAT;
 782   Flag::Error check = apply_constraint_and_check_range_bool(name, value, !CommandLineFlags::finishedInitializing());
 783   if (check != Flag::SUCCESS) return check;
 784   bool old_value = result->get_bool();
 785   trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
 786   result->set_bool(*value);
 787   *value = old_value;
 788   result->set_origin(origin);
 789   return Flag::SUCCESS;
 790 }
 791 
 792 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
 793   Flag* faddr = address_of_flag(flag);
 794   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
 795   Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, &value);
 796   if (check != Flag::SUCCESS) return check;
 797   trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
 798   faddr->set_bool(value);
 799   faddr->set_origin(origin);
 800   return Flag::SUCCESS;
 801 }
 802 
 803 static Flag::Error apply_constraint_and_check_range_int(const char* name, int* new_value, bool verbose = true) {
 804   Flag::Error status = Flag::SUCCESS;
 805   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 806   if (range != NULL) {
 807     status = range->check_int(*new_value, verbose);
 808   }
 809   if (status == Flag::SUCCESS) {
 810     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
 811     if (constraint != NULL) {
 812       status = constraint->apply_int(new_value, verbose);
 813     }
 814   }
 815   return status;
 816 }
 817 
 818 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
 819   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 820   if (result == NULL) return Flag::INVALID_FLAG;
 821   if (!result->is_int()) return Flag::WRONG_FORMAT;
 822   *value = result->get_int();
 823   return Flag::SUCCESS;
 824 }
 825 
 826 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
 827   Flag* result = Flag::find_flag(name, len);
 828   if (result == NULL) return Flag::INVALID_FLAG;
 829   if (!result->is_int()) return Flag::WRONG_FORMAT;
 830   Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlags::finishedInitializing());
 831   if (check != Flag::SUCCESS) return check;
 832   int old_value = result->get_int();
 833   trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
 834   result->set_int(*value);
 835   *value = old_value;
 836   result->set_origin(origin);
 837   return Flag::SUCCESS;
 838 }
 839 
 840 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
 841   Flag* faddr = address_of_flag(flag);
 842   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
 843   trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
 844   faddr->set_int(value);
 845   faddr->set_origin(origin);
 846   return Flag::SUCCESS;
 847 }
 848 
 849 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint* new_value, bool verbose = true) {
 850   Flag::Error status = Flag::SUCCESS;
 851   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 852   if (range != NULL) {
 853     status = range->check_uint(*new_value, verbose);
 854   }
 855   if (status == Flag::SUCCESS) {
 856     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
 857     if (constraint != NULL) {
 858       status = constraint->apply_uint(new_value, verbose);
 859     }
 860   }
 861   return status;
 862 }
 863 
 864 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
 865   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 866   if (result == NULL) return Flag::INVALID_FLAG;
 867   if (!result->is_uint()) return Flag::WRONG_FORMAT;
 868   *value = result->get_uint();
 869   return Flag::SUCCESS;
 870 }
 871 
 872 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
 873   Flag* result = Flag::find_flag(name, len);
 874   if (result == NULL) return Flag::INVALID_FLAG;
 875   if (!result->is_uint()) return Flag::WRONG_FORMAT;
 876   Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlags::finishedInitializing());
 877   if (check != Flag::SUCCESS) return check;
 878   uint old_value = result->get_uint();
 879   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
 880   result->set_uint(*value);
 881   *value = old_value;
 882   result->set_origin(origin);
 883   return Flag::SUCCESS;
 884 }
 885 
 886 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
 887   Flag* faddr = address_of_flag(flag);
 888   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
 889   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
 890   faddr->set_uint(value);
 891   faddr->set_origin(origin);
 892   return Flag::SUCCESS;
 893 }
 894 
 895 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
 896   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 897   if (result == NULL) return Flag::INVALID_FLAG;
 898   if (!result->is_intx()) return Flag::WRONG_FORMAT;
 899   *value = result->get_intx();
 900   return Flag::SUCCESS;
 901 }
 902 
 903 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx* new_value, bool verbose = true) {
 904   Flag::Error status = Flag::SUCCESS;
 905   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 906   if (range != NULL) {
 907     status = range->check_intx(*new_value, verbose);
 908   }
 909   if (status == Flag::SUCCESS) {
 910     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
 911     if (constraint != NULL) {
 912       status = constraint->apply_intx(new_value, verbose);
 913     }
 914   }
 915   return status;
 916 }
 917 
 918 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
 919   Flag* result = Flag::find_flag(name, len);
 920   if (result == NULL) return Flag::INVALID_FLAG;
 921   if (!result->is_intx()) return Flag::WRONG_FORMAT;
 922   Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlags::finishedInitializing());
 923   if (check != Flag::SUCCESS) return check;
 924   intx old_value = result->get_intx();
 925   trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
 926   result->set_intx(*value);
 927   *value = old_value;
 928   result->set_origin(origin);
 929   return Flag::SUCCESS;
 930 }
 931 
 932 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
 933   Flag* faddr = address_of_flag(flag);
 934   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
 935   Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, &value);
 936   if (check != Flag::SUCCESS) return check;
 937   trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
 938   faddr->set_intx(value);
 939   faddr->set_origin(origin);
 940   return Flag::SUCCESS;
 941 }
 942 
 943 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
 944   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 945   if (result == NULL) return Flag::INVALID_FLAG;
 946   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
 947   *value = result->get_uintx();
 948   return Flag::SUCCESS;
 949 }
 950 
 951 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx* new_value, bool verbose = true) {
 952   Flag::Error status = Flag::SUCCESS;
 953   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 954   if (range != NULL) {
 955     status = range->check_uintx(*new_value, verbose);
 956   }
 957   if (status == Flag::SUCCESS) {
 958     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
 959     if (constraint != NULL) {
 960       status = constraint->apply_uintx(new_value, verbose);
 961     }
 962   }
 963   return status;
 964 }
 965 
 966 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
 967   Flag* result = Flag::find_flag(name, len);
 968   if (result == NULL) return Flag::INVALID_FLAG;
 969   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
 970   Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlags::finishedInitializing());
 971   if (check != Flag::SUCCESS) return check;
 972   uintx old_value = result->get_uintx();
 973   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
 974   result->set_uintx(*value);
 975   *value = old_value;
 976   result->set_origin(origin);
 977   return Flag::SUCCESS;
 978 }
 979 
 980 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
 981   Flag* faddr = address_of_flag(flag);
 982   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
 983   Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, &value);
 984   if (check != Flag::SUCCESS) return check;
 985   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
 986   faddr->set_uintx(value);
 987   faddr->set_origin(origin);
 988   return Flag::SUCCESS;
 989 }
 990 
 991 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
 992   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
 993   if (result == NULL) return Flag::INVALID_FLAG;
 994   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
 995   *value = result->get_uint64_t();
 996   return Flag::SUCCESS;
 997 }
 998 
 999 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t* new_value, bool verbose = true) {
1000   Flag::Error status = Flag::SUCCESS;
1001   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1002   if (range != NULL) {
1003     status = range->check_uint64_t(*new_value, verbose);
1004   }
1005   if (status == Flag::SUCCESS) {
1006     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1007     if (constraint != NULL) {
1008       status = constraint->apply_uint64_t(new_value, verbose);
1009     }
1010   }
1011   return status;
1012 }
1013 
1014 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
1015   Flag* result = Flag::find_flag(name, len);
1016   if (result == NULL) return Flag::INVALID_FLAG;
1017   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1018   Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlags::finishedInitializing());
1019   if (check != Flag::SUCCESS) return check;
1020   uint64_t old_value = result->get_uint64_t();
1021   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1022   result->set_uint64_t(*value);
1023   *value = old_value;
1024   result->set_origin(origin);
1025   return Flag::SUCCESS;
1026 }
1027 
1028 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
1029   Flag* faddr = address_of_flag(flag);
1030   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
1031   Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, &value);
1032   if (check != Flag::SUCCESS) return check;
1033   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
1034   faddr->set_uint64_t(value);
1035   faddr->set_origin(origin);
1036   return Flag::SUCCESS;
1037 }
1038 
1039 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
1040   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1041   if (result == NULL) return Flag::INVALID_FLAG;
1042   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1043   *value = result->get_size_t();
1044   return Flag::SUCCESS;
1045 }
1046 
1047 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t* new_value, bool verbose = true) {
1048   Flag::Error status = Flag::SUCCESS;
1049   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1050   if (range != NULL) {
1051     status = range->check_size_t(*new_value, verbose);
1052   }
1053   if (status == Flag::SUCCESS) {
1054     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1055     if (constraint != NULL) {
1056       status = constraint->apply_size_t(new_value, verbose);
1057     }
1058   }
1059   return status;
1060 }
1061 
1062 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
1063   Flag* result = Flag::find_flag(name, len);
1064   if (result == NULL) return Flag::INVALID_FLAG;
1065   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1066   Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlags::finishedInitializing());
1067   if (check != Flag::SUCCESS) return check;
1068   size_t old_value = result->get_size_t();
1069   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1070   result->set_size_t(*value);
1071   *value = old_value;
1072   result->set_origin(origin);
1073   return Flag::SUCCESS;
1074 }
1075 
1076 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
1077   Flag* faddr = address_of_flag(flag);
1078   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
1079   Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, &value);
1080   if (check != Flag::SUCCESS) return check;
1081   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
1082   faddr->set_size_t(value);
1083   faddr->set_origin(origin);
1084   return Flag::SUCCESS;
1085 }
1086 
1087 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
1088   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1089   if (result == NULL) return Flag::INVALID_FLAG;
1090   if (!result->is_double()) return Flag::WRONG_FORMAT;
1091   *value = result->get_double();
1092   return Flag::SUCCESS;
1093 }
1094 
1095 static Flag::Error apply_constraint_and_check_range_double(const char* name, double* new_value, bool verbose = true) {
1096   Flag::Error status = Flag::SUCCESS;
1097   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1098   if (range != NULL) {
1099     status = range->check_double(*new_value, verbose);
1100   }
1101   if (status == Flag::SUCCESS) {
1102     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1103     if (constraint != NULL) {
1104       status = constraint->apply_double(new_value, verbose);
1105     }
1106   }
1107   return status;
1108 }
1109 
1110 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
1111   Flag* result = Flag::find_flag(name, len);
1112   if (result == NULL) return Flag::INVALID_FLAG;
1113   if (!result->is_double()) return Flag::WRONG_FORMAT;
1114   Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlags::finishedInitializing());
1115   if (check != Flag::SUCCESS) return check;
1116   double old_value = result->get_double();
1117   trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
1118   result->set_double(*value);
1119   *value = old_value;
1120   result->set_origin(origin);
1121   return Flag::SUCCESS;
1122 }
1123 
1124 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
1125   Flag* faddr = address_of_flag(flag);
1126   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
1127   Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value, !CommandLineFlags::finishedInitializing());
1128   if (check != Flag::SUCCESS) return check;
1129   trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
1130   faddr->set_double(value);
1131   faddr->set_origin(origin);
1132   return Flag::SUCCESS;
1133 }
1134 
1135 Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
1136   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1137   if (result == NULL) return Flag::INVALID_FLAG;
1138   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1139   *value = result->get_ccstr();
1140   return Flag::SUCCESS;
1141 }
1142 
1143 Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
1144   Flag* result = Flag::find_flag(name, len);
1145   if (result == NULL) return Flag::INVALID_FLAG;
1146   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1147   ccstr old_value = result->get_ccstr();
1148   trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
1149   char* new_value = NULL;
1150   if (*value != NULL) {
1151     new_value = os::strdup_check_oom(*value);
1152   }
1153   result->set_ccstr(new_value);
1154   if (result->is_default() && old_value != NULL) {
1155     // Prior value is NOT heap allocated, but was a literal constant.
1156     old_value = os::strdup_check_oom(old_value);
1157   }
1158   *value = old_value;
1159   result->set_origin(origin);
1160   return Flag::SUCCESS;
1161 }
1162 
1163 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
1164   Flag* faddr = address_of_flag(flag);
1165   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
1166   ccstr old_value = faddr->get_ccstr();
1167   trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
1168   char* new_value = os::strdup_check_oom(value);
1169   faddr->set_ccstr(new_value);
1170   if (!faddr->is_default() && old_value != NULL) {
1171     // Prior value is heap allocated so free it.
1172     FREE_C_HEAP_ARRAY(char, old_value);
1173   }
1174   faddr->set_origin(origin);
1175   return Flag::SUCCESS;
1176 }
1177 
1178 //#define PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1179 #ifndef PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1180 
1181 extern "C" {
1182   static int compare_flags(const void* void_a, const void* void_b) {
1183     return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1184   }
1185 }
1186 
1187 #else // PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1188 
1189 void print_kind(Flag::Flags flags, char* string, int size) {
1190   struct Data {
1191     int flag;
1192     const char* name;
1193   };
1194 
1195   Data data[] = {
1196     { Flag::KIND_C1, "C1" },
1197     { Flag::KIND_C2, "C2" },
1198     { Flag::KIND_ARCH, "ARCH" },
1199     { Flag::KIND_SHARK, "SHARK" },
1200     { Flag::KIND_PLATFORM_DEPENDENT, "pd" },
1201     { Flag::KIND_PRODUCT, "product" },
1202     { Flag::KIND_MANAGEABLE, "manageable" },
1203     { Flag::KIND_DIAGNOSTIC, "diagnostic" },
1204     { Flag::KIND_EXPERIMENTAL, "experimental" },
1205     { Flag::KIND_COMMERCIAL, "commercial" },
1206     { Flag::KIND_NOT_PRODUCT, "notproduct" },
1207     { Flag::KIND_DEVELOP, "develop" },
1208     { Flag::KIND_LP64_PRODUCT, "lp64_product" },
1209     { Flag::KIND_READ_WRITE, "rw" },
1210     { -1, "" }
1211   };
1212 
1213   if ((flags & Flag::KIND_MASK) != 0) {
1214     strncpy(string, "{", size);
1215     bool is_first = true;
1216 
1217     for (int i = 0; data[i].flag != -1; i++) {
1218       Data d = data[i];
1219       if ((flags & d.flag) != 0) {
1220         if (is_first) {
1221           is_first = false;
1222         } else {
1223           os::strlcat(string, " ", size);
1224         }
1225         os::strlcat(string, d.name, size);
1226       }
1227     }
1228 
1229     os::strlcat(string, "}", size);
1230   }
1231 }
1232 
1233 extern "C" {
1234   // by kind, name
1235   static int compare_flags(const void* void_a, const void* void_b) {
1236     char buf_a[128];
1237     print_kind((*((Flag**) void_a))->_flags, &buf_a[0], 127);
1238     char buf_b[128];
1239     print_kind((*((Flag**) void_b))->_flags, &buf_b[0], 127);
1240     int comp_kind = strncmp(buf_a, buf_b, 127);
1241     if (comp_kind != 0) {
1242       return comp_kind;
1243     } else {
1244       return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1245     }
1246   }
1247 }
1248 
1249 #endif //PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1250 
1251 void CommandLineFlags::printSetFlags(outputStream* out) {
1252   // Print which flags were set on the command line
1253   // note: this method is called before the thread structure is in place
1254   //       which means resource allocation cannot be used.
1255 
1256   // The last entry is the null entry.
1257   const size_t length = Flag::numFlags - 1;
1258 
1259   // Sort
1260   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1261   for (size_t i = 0; i < length; i++) {
1262     array[i] = &flagTable[i];
1263   }
1264   qsort(array, length, sizeof(Flag*), compare_flags);
1265 
1266   // Print
1267   for (size_t i = 0; i < length; i++) {
1268     if (array[i]->get_origin() /* naked field! */) {
1269       array[i]->print_as_flag(out);
1270       out->print(" ");
1271     }
1272   }
1273   out->cr();
1274   FREE_C_HEAP_ARRAY(Flag*, array);
1275 }
1276 
1277 bool CommandLineFlags::_finished_initializing = false;
1278 
1279 bool CommandLineFlags::check_all_ranges_and_constraints() {
1280 //#define PRINT_RANGES_AND_CONSTRAINTS_SIZES
1281 #ifdef PRINT_RANGES_AND_CONSTRAINTS_SIZES
1282   {
1283     size_t size_ranges = sizeof(CommandLineFlagRangeList);
1284     for (int i=0; i<CommandLineFlagRangeList::length(); i++) {
1285       size_ranges += sizeof(CommandLineFlagRange);
1286       CommandLineFlagRange* range = CommandLineFlagRangeList::at(i);
1287       const char* name = range->name();
1288       Flag* flag = Flag::find_flag(name, strlen(name), true, true);
1289       if (flag->is_intx()) {
1290         size_ranges += 2*sizeof(intx);
1291         size_ranges += sizeof(CommandLineFlagRange*);
1292       } else if (flag->is_uintx()) {
1293         size_ranges += 2*sizeof(uintx);
1294         size_ranges += sizeof(CommandLineFlagRange*);
1295       } else if (flag->is_uint64_t()) {
1296         size_ranges += 2*sizeof(uint64_t);
1297         size_ranges += sizeof(CommandLineFlagRange*);
1298       } else if (flag->is_size_t()) {
1299         size_ranges += 2*sizeof(size_t);
1300         size_ranges += sizeof(CommandLineFlagRange*);
1301       } else if (flag->is_double()) {
1302         size_ranges += 2*sizeof(double);
1303         size_ranges += sizeof(CommandLineFlagRange*);
1304       }
1305     }
1306     fprintf(stderr, "Size of %d ranges: "SIZE_FORMAT" bytes\n",
1307             CommandLineFlagRangeList::length(), size_ranges);
1308   }
1309   {
1310     size_t size_constraints = sizeof(CommandLineFlagConstraintList);
1311     for (int i=0; i<CommandLineFlagConstraintList::length(); i++) {
1312       size_constraints += sizeof(CommandLineFlagConstraint);
1313       CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::at(i);
1314       const char* name = constraint->name();
1315       Flag* flag = Flag::find_flag(name, strlen(name), true, true);
1316       if (flag->is_bool()) {
1317         size_constraints += sizeof(CommandLineFlagConstraintFunc_bool);
1318         size_constraints += sizeof(CommandLineFlagConstraint*);
1319       } else if (flag->is_intx()) {
1320         size_constraints += sizeof(CommandLineFlagConstraintFunc_intx);
1321         size_constraints += sizeof(CommandLineFlagConstraint*);
1322       } else if (flag->is_uintx()) {
1323         size_constraints += sizeof(CommandLineFlagConstraintFunc_uintx);
1324         size_constraints += sizeof(CommandLineFlagConstraint*);
1325       } else if (flag->is_uint64_t()) {
1326         size_constraints += sizeof(CommandLineFlagConstraintFunc_uint64_t);
1327         size_constraints += sizeof(CommandLineFlagConstraint*);
1328       } else if (flag->is_size_t()) {
1329         size_constraints += sizeof(CommandLineFlagConstraintFunc_size_t);
1330         size_constraints += sizeof(CommandLineFlagConstraint*);
1331       } else if (flag->is_double()) {
1332         size_constraints += sizeof(CommandLineFlagConstraintFunc_double);
1333         size_constraints += sizeof(CommandLineFlagConstraint*);
1334       }
1335     }
1336     fprintf(stderr, "Size of %d constraints: "SIZE_FORMAT" bytes\n",
1337             CommandLineFlagConstraintList::length(), size_constraints);
1338   }
1339 #endif // PRINT_RANGES_AND_CONSTRAINTS_SIZES
1340 
1341   _finished_initializing = true;
1342 
1343   bool status = true;
1344   for (int i=0; i<CommandLineFlagRangeList::length(); i++) {
1345     CommandLineFlagRange* range = CommandLineFlagRangeList::at(i);
1346     const char* name = range->name();
1347     Flag* flag = Flag::find_flag(name, strlen(name), true, true);
1348     if (flag != NULL) {
1349       if (flag->is_intx()) {
1350         intx value = flag->get_intx();
1351         if (range->check_intx(value, true) != Flag::SUCCESS) status = false;
1352       } else if (flag->is_uintx()) {
1353         uintx value = flag->get_uintx();
1354         if (range->check_uintx(value, true) != Flag::SUCCESS) status = false;
1355       } else if (flag->is_uint64_t()) {
1356         uint64_t value = flag->get_uint64_t();
1357         if (range->check_uint64_t(value, true) != Flag::SUCCESS) status = false;
1358       } else if (flag->is_size_t()) {
1359         size_t value = flag->get_size_t();
1360         if (range->check_size_t(value, true) != Flag::SUCCESS) status = false;
1361       } else if (flag->is_double()) {
1362         double value = flag->get_double();
1363         if (range->check_double(value, true) != Flag::SUCCESS) status = false;
1364       }
1365     }
1366   }
1367   for (int i=0; i<CommandLineFlagConstraintList::length(); i++) {
1368     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::at(i);
1369     const char*name = constraint->name();
1370     Flag* flag = Flag::find_flag(name, strlen(name), true, true);
1371     if (flag != NULL) {
1372       if (flag->is_bool()) {
1373         bool value = flag->get_bool();
1374         if (constraint->apply_bool(&value, true) != Flag::SUCCESS) status = false;
1375       } else if (flag->is_intx()) {
1376         intx value = flag->get_intx();
1377         if (constraint->apply_intx(&value, true) != Flag::SUCCESS) status = false;
1378       } else if (flag->is_uintx()) {
1379         uintx value = flag->get_uintx();
1380         if (constraint->apply_uintx(&value, true) != Flag::SUCCESS) status = false;
1381       } else if (flag->is_uint64_t()) {
1382         uint64_t value = flag->get_uint64_t();
1383         if (constraint->apply_uint64_t(&value, true) != Flag::SUCCESS) status = false;
1384       } else if (flag->is_size_t()) {
1385         size_t value = flag->get_size_t();
1386         if (constraint->apply_size_t(&value, true) != Flag::SUCCESS) status = false;
1387       } else if (flag->is_double()) {
1388         double value = flag->get_double();
1389         if (constraint->apply_double(&value, true) != Flag::SUCCESS) status = false;
1390       }
1391     }
1392   }
1393   
1394   Arguments::post_final_range_and_constraint_check(status);
1395 
1396   return status;
1397 }
1398 
1399 #ifndef PRODUCT
1400 
1401 void CommandLineFlags::verify() {
1402   assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
1403 }
1404 
1405 #endif // PRODUCT
1406 
1407 #define ONLY_PRINT_PRODUCT_FLAGS
1408 
1409 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
1410   // Print the flags sorted by name
1411   // note: this method is called before the thread structure is in place
1412   //       which means resource allocation cannot be used.
1413 
1414   // The last entry is the null entry.
1415   const size_t length = Flag::numFlags - 1;
1416 
1417   // Sort
1418   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1419   for (size_t i = 0; i < length; i++) {
1420     array[i] = &flagTable[i];
1421   }
1422   qsort(array, length, sizeof(Flag*), compare_flags);
1423 
1424   // Print
1425   if (printRanges == false) {
1426     out->print_cr("[Global flags]");
1427   } else {
1428     out->print_cr("[Global flags ranges]");
1429   }
1430 
1431   for (size_t i = 0; i < length; i++) {
1432     if (array[i]->is_unlocked()) {
1433 #ifdef ONLY_PRINT_PRODUCT_FLAGS
1434       if (!array[i]->is_notproduct() && !array[i]->is_develop())
1435 #endif // ONLY_PRINT_PRODUCT_FLAGS
1436       array[i]->print_on(out, printRanges, withComments);
1437     }
1438   }
1439   FREE_C_HEAP_ARRAY(Flag*, array);
1440 }