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