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