1 /*
   2  * Copyright (c) 1997, 2016, 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/commandLineFlagWriteableList.hpp"
  33 #include "runtime/commandLineFlagRangeList.hpp"
  34 #include "runtime/os.hpp"
  35 #include "runtime/sharedRuntime.hpp"
  36 #include "trace/tracing.hpp"
  37 #include "utilities/defaultStream.hpp"
  38 #include "utilities/macros.hpp"
  39 #include "utilities/ostream.hpp"
  40 #if INCLUDE_ALL_GCS
  41 #include "gc/g1/g1_globals.hpp"
  42 #endif // INCLUDE_ALL_GCS
  43 #ifdef COMPILER1
  44 #include "c1/c1_globals.hpp"
  45 #endif
  46 #if INCLUDE_JVMCI
  47 #include "jvmci/jvmci_globals.hpp"
  48 #endif
  49 #ifdef COMPILER2
  50 #include "opto/c2_globals.hpp"
  51 #endif
  52 #ifdef SHARK
  53 #include "shark/shark_globals.hpp"
  54 #endif
  55 
  56 RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
  57               MATERIALIZE_PD_DEVELOPER_FLAG, \
  58               MATERIALIZE_PRODUCT_FLAG, \
  59               MATERIALIZE_PD_PRODUCT_FLAG, \
  60               MATERIALIZE_DIAGNOSTIC_FLAG, \
  61               MATERIALIZE_EXPERIMENTAL_FLAG, \
  62               MATERIALIZE_NOTPRODUCT_FLAG, \
  63               MATERIALIZE_MANAGEABLE_FLAG, \
  64               MATERIALIZE_PRODUCT_RW_FLAG, \
  65               MATERIALIZE_LP64_PRODUCT_FLAG, \
  66               IGNORE_RANGE, \
  67               IGNORE_CONSTRAINT, \
  68               IGNORE_WRITEABLE)
  69 
  70 RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
  71                  MATERIALIZE_PD_DEVELOPER_FLAG, \
  72                  MATERIALIZE_PRODUCT_FLAG, \
  73                  MATERIALIZE_PD_PRODUCT_FLAG, \
  74                  MATERIALIZE_DIAGNOSTIC_FLAG, \
  75                  MATERIALIZE_NOTPRODUCT_FLAG, \
  76                  IGNORE_RANGE, \
  77                  IGNORE_CONSTRAINT, \
  78                  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 = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin);
 336 }
 337 
 338 bool Flag::is_default() {
 339   return (get_origin() == DEFAULT);
 340 }
 341 
 342 bool Flag::is_ergonomic() {
 343   return (get_origin() == ERGONOMIC);
 344 }
 345 
 346 bool Flag::is_command_line() {
 347   return (get_origin() == COMMAND_LINE);
 348 }
 349 
 350 bool Flag::is_product() const {
 351   return (_flags & KIND_PRODUCT) != 0;
 352 }
 353 
 354 bool Flag::is_manageable() const {
 355   return (_flags & KIND_MANAGEABLE) != 0;
 356 }
 357 
 358 bool Flag::is_diagnostic() const {
 359   return (_flags & KIND_DIAGNOSTIC) != 0;
 360 }
 361 
 362 bool Flag::is_experimental() const {
 363   return (_flags & KIND_EXPERIMENTAL) != 0;
 364 }
 365 
 366 bool Flag::is_notproduct() const {
 367   return (_flags & KIND_NOT_PRODUCT) != 0;
 368 }
 369 
 370 bool Flag::is_develop() const {
 371   return (_flags & KIND_DEVELOP) != 0;
 372 }
 373 
 374 bool Flag::is_read_write() const {
 375   return (_flags & KIND_READ_WRITE) != 0;
 376 }
 377 
 378 bool Flag::is_commercial() const {
 379   return (_flags & KIND_COMMERCIAL) != 0;
 380 }
 381 
 382 /**
 383  * Returns if this flag is a constant in the binary.  Right now this is
 384  * true for notproduct and develop flags in product builds.
 385  */
 386 bool Flag::is_constant_in_binary() const {
 387 #ifdef PRODUCT
 388     return is_notproduct() || is_develop();
 389 #else
 390     return false;
 391 #endif
 392 }
 393 
 394 bool Flag::is_unlocker() const {
 395   return strcmp(_name, "UnlockDiagnosticVMOptions") == 0     ||
 396          strcmp(_name, "UnlockExperimentalVMOptions") == 0   ||
 397          is_unlocker_ext();
 398 }
 399 
 400 bool Flag::is_unlocked() const {
 401   if (is_diagnostic()) {
 402     return UnlockDiagnosticVMOptions;
 403   }
 404   if (is_experimental()) {
 405     return UnlockExperimentalVMOptions;
 406   }
 407   return is_unlocked_ext();
 408 }
 409 
 410 void Flag::unlock_diagnostic() {
 411   assert(is_diagnostic(), "sanity");
 412   _flags = Flags(_flags & ~KIND_DIAGNOSTIC);
 413 }
 414 
 415 // Get custom message for this locked flag, or NULL if
 416 // none is available. Returns message type produced.
 417 Flag::MsgType Flag::get_locked_message(char* buf, int buflen) const {
 418   buf[0] = '\0';
 419   if (is_diagnostic() && !is_unlocked()) {
 420     jio_snprintf(buf, buflen,
 421                  "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n"
 422                  "Error: The unlock option must precede '%s'.\n",
 423                  _name, _name);
 424     return Flag::DIAGNOSTIC_FLAG_BUT_LOCKED;
 425   }
 426   if (is_experimental() && !is_unlocked()) {
 427     jio_snprintf(buf, buflen,
 428                  "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n"
 429                  "Error: The unlock option must precede '%s'.\n",
 430                  _name, _name);
 431     return Flag::EXPERIMENTAL_FLAG_BUT_LOCKED;
 432   }
 433   if (is_develop() && is_product_build()) {
 434     jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n",
 435                  _name);
 436     return Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD;
 437   }
 438   if (is_notproduct() && is_product_build()) {
 439     jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
 440                  _name);
 441     return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
 442   }
 443   get_locked_message_ext(buf, buflen);
 444   return Flag::NONE;
 445 }
 446 
 447 bool Flag::is_writeable() const {
 448   return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
 449 }
 450 
 451 // All flags except "manageable" are assumed to be internal flags.
 452 // Long term, we need to define a mechanism to specify which flags
 453 // are external/stable and change this function accordingly.
 454 bool Flag::is_external() const {
 455   return is_manageable() || is_external_ext();
 456 }
 457 
 458 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
 459   // Don't print notproduct and develop flags in a product build.
 460   if (is_constant_in_binary()) {
 461     return;
 462   }
 463 
 464   if (!printRanges) {
 465 
 466     st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
 467 
 468     if (is_bool()) {
 469       st->print("%-16s", get_bool() ? "true" : "false");
 470     } else if (is_int()) {
 471       st->print("%-16d", get_int());
 472     } else if (is_uint()) {
 473       st->print("%-16u", get_uint());
 474     } else if (is_intx()) {
 475       st->print(INTX_FORMAT_W(-16), get_intx());
 476     } else if (is_uintx()) {
 477       st->print(UINTX_FORMAT_W(-16), get_uintx());
 478     } else if (is_uint64_t()) {
 479       st->print(UINT64_FORMAT_W(-16), get_uint64_t());
 480     } else if (is_size_t()) {
 481       st->print(SIZE_FORMAT_W(-16), get_size_t());
 482     } else if (is_double()) {
 483       st->print("%-16f", get_double());
 484     } else if (is_ccstr()) {
 485       const char* cp = get_ccstr();
 486       if (cp != NULL) {
 487         const char* eol;
 488         while ((eol = strchr(cp, '\n')) != NULL) {
 489           size_t llen = pointer_delta(eol, cp, sizeof(char));
 490           st->print("%.*s", (int)llen, cp);
 491           st->cr();
 492           cp = eol+1;
 493           st->print("%5s %-35s += ", "", _name);
 494         }
 495         st->print("%-16s", cp);
 496       }
 497       else st->print("%-16s", "");
 498     }
 499 
 500     st->print("%-20s", " ");
 501     print_kind(st);
 502 
 503 #ifndef PRODUCT
 504     if (withComments) {
 505       st->print("%s", _doc);
 506     }
 507 #endif
 508 
 509     st->cr();
 510 
 511   } else if (!is_bool() && !is_ccstr()) {
 512     st->print("%9s %-50s ", _type, _name);
 513 
 514     RangeStrFunc func = NULL;
 515     if (is_int()) {
 516       func = Flag::get_int_default_range_str;
 517     } else if (is_uint()) {
 518       func = Flag::get_uint_default_range_str;
 519     } else if (is_intx()) {
 520       func = Flag::get_intx_default_range_str;
 521     } else if (is_uintx()) {
 522       func = Flag::get_uintx_default_range_str;
 523     } else if (is_uint64_t()) {
 524       func = Flag::get_uint64_t_default_range_str;
 525     } else if (is_size_t()) {
 526       func = Flag::get_size_t_default_range_str;
 527     } else if (is_double()) {
 528       func = Flag::get_double_default_range_str;
 529     } else {
 530       ShouldNotReachHere();
 531     }
 532     CommandLineFlagRangeList::print(st, _name, func);
 533 
 534     st->print(" %-20s", " ");
 535     print_kind(st);
 536 
 537 #ifndef PRODUCT
 538     if (withComments) {
 539       st->print("%s", _doc);
 540     }
 541 #endif
 542 
 543     st->cr();
 544   }
 545 }
 546 
 547 void Flag::print_kind(outputStream* st) {
 548   struct Data {
 549     int flag;
 550     const char* name;
 551   };
 552 
 553   Data data[] = {
 554       { KIND_JVMCI, "JVMCI" },
 555       { KIND_C1, "C1" },
 556       { KIND_C2, "C2" },
 557       { KIND_ARCH, "ARCH" },
 558       { KIND_SHARK, "SHARK" },
 559       { KIND_PLATFORM_DEPENDENT, "pd" },
 560       { KIND_PRODUCT, "product" },
 561       { KIND_MANAGEABLE, "manageable" },
 562       { KIND_DIAGNOSTIC, "diagnostic" },
 563       { KIND_EXPERIMENTAL, "experimental" },
 564       { KIND_COMMERCIAL, "commercial" },
 565       { KIND_NOT_PRODUCT, "notproduct" },
 566       { KIND_DEVELOP, "develop" },
 567       { KIND_LP64_PRODUCT, "lp64_product" },
 568       { KIND_READ_WRITE, "rw" },
 569       { -1, "" }
 570   };
 571 
 572   if ((_flags & KIND_MASK) != 0) {
 573     st->print("{");
 574     bool is_first = true;
 575 
 576     for (int i = 0; data[i].flag != -1; i++) {
 577       Data d = data[i];
 578       if ((_flags & d.flag) != 0) {
 579         if (is_first) {
 580           is_first = false;
 581         } else {
 582           st->print(" ");
 583         }
 584         st->print("%s", d.name);
 585       }
 586     }
 587 
 588     st->print("}");
 589   }
 590 }
 591 
 592 void Flag::print_as_flag(outputStream* st) {
 593   if (is_bool()) {
 594     st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
 595   } else if (is_int()) {
 596     st->print("-XX:%s=%d", _name, get_int());
 597   } else if (is_uint()) {
 598     st->print("-XX:%s=%u", _name, get_uint());
 599   } else if (is_intx()) {
 600     st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
 601   } else if (is_uintx()) {
 602     st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
 603   } else if (is_uint64_t()) {
 604     st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
 605   } else if (is_size_t()) {
 606     st->print("-XX:%s=" SIZE_FORMAT, _name, get_size_t());
 607   } else if (is_double()) {
 608     st->print("-XX:%s=%f", _name, get_double());
 609   } else if (is_ccstr()) {
 610     st->print("-XX:%s=", _name);
 611     const char* cp = get_ccstr();
 612     if (cp != NULL) {
 613       // Need to turn embedded '\n's back into separate arguments
 614       // Not so efficient to print one character at a time,
 615       // but the choice is to do the transformation to a buffer
 616       // and print that.  And this need not be efficient.
 617       for (; *cp != '\0'; cp += 1) {
 618         switch (*cp) {
 619           default:
 620             st->print("%c", *cp);
 621             break;
 622           case '\n':
 623             st->print(" -XX:%s=", _name);
 624             break;
 625         }
 626       }
 627     }
 628   } else {
 629     ShouldNotReachHere();
 630   }
 631 }
 632 
 633 const char* Flag::flag_error_str(Flag::Error error) {
 634   switch (error) {
 635     case Flag::MISSING_NAME: return "MISSING_NAME";
 636     case Flag::MISSING_VALUE: return "MISSING_VALUE";
 637     case Flag::NON_WRITABLE: return "NON_WRITABLE";
 638     case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS";
 639     case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT";
 640     case Flag::INVALID_FLAG: return "INVALID_FLAG";
 641     case Flag::ERR_OTHER: return "ERR_OTHER";
 642     case Flag::SUCCESS: return "SUCCESS";
 643     default: ShouldNotReachHere(); return "NULL";
 644   }
 645 }
 646 
 647 // 4991491 do not "optimize out" the was_set false values: omitting them
 648 // tickles a Microsoft compiler bug causing flagTable to be malformed
 649 
 650 #define RUNTIME_PRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) },
 651 #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) },
 652 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) },
 653 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) },
 654 #define RUNTIME_MANAGEABLE_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) },
 655 #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) },
 656 #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) },
 657 #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) },
 658 #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) },
 659 
 660 #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) },
 661 #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) },
 662 #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) },
 663 #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) },
 664 #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) },
 665 #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) },
 666 #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) },
 667 
 668 #ifdef _LP64
 669 #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) },
 670 #else
 671 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
 672 #endif // _LP64
 673 
 674 #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) },
 675 #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) },
 676 #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) },
 677 #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) },
 678 #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) },
 679 #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) },
 680 
 681 #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) },
 682 #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) },
 683 #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) },
 684 #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) },
 685 #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) },
 686 #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) },
 687 #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) },
 688 
 689 #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) },
 690 #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) },
 691 #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) },
 692 #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) },
 693 #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) },
 694 
 695 #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) },
 696 #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) },
 697 #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) },
 698 #define SHARK_DEVELOP_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP) },
 699 #define SHARK_PD_DEVELOP_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
 700 #define SHARK_NOTPRODUCT_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_NOT_PRODUCT) },
 701 
 702 static Flag flagTable[] = {
 703  RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 704                RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 705                RUNTIME_PRODUCT_FLAG_STRUCT, \
 706                RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 707                RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 708                RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
 709                RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 710                RUNTIME_MANAGEABLE_FLAG_STRUCT, \
 711                RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
 712                RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \
 713                IGNORE_RANGE, \
 714                IGNORE_CONSTRAINT, \
 715                IGNORE_WRITEABLE)
 716  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 717                   RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 718                   RUNTIME_PRODUCT_FLAG_STRUCT, \
 719                   RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 720                   RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 721                   RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 722                   IGNORE_RANGE, \
 723                   IGNORE_CONSTRAINT, \
 724                   IGNORE_WRITEABLE)
 725 #if INCLUDE_ALL_GCS
 726  G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
 727           RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
 728           RUNTIME_PRODUCT_FLAG_STRUCT, \
 729           RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
 730           RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
 731           RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
 732           RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
 733           RUNTIME_MANAGEABLE_FLAG_STRUCT, \
 734           RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
 735           IGNORE_RANGE, \
 736           IGNORE_CONSTRAINT, \
 737           IGNORE_WRITEABLE)
 738 #endif // INCLUDE_ALL_GCS
 739 #if INCLUDE_JVMCI
 740  JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \
 741              JVMCI_PD_DEVELOP_FLAG_STRUCT, \
 742              JVMCI_PRODUCT_FLAG_STRUCT, \
 743              JVMCI_PD_PRODUCT_FLAG_STRUCT, \
 744              JVMCI_DIAGNOSTIC_FLAG_STRUCT, \
 745              JVMCI_EXPERIMENTAL_FLAG_STRUCT, \
 746              JVMCI_NOTPRODUCT_FLAG_STRUCT, \
 747              IGNORE_RANGE, \
 748              IGNORE_CONSTRAINT, \
 749              IGNORE_WRITEABLE)
 750 #endif // INCLUDE_JVMCI
 751 #ifdef COMPILER1
 752  C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
 753           C1_PD_DEVELOP_FLAG_STRUCT, \
 754           C1_PRODUCT_FLAG_STRUCT, \
 755           C1_PD_PRODUCT_FLAG_STRUCT, \
 756           C1_DIAGNOSTIC_FLAG_STRUCT, \
 757           C1_NOTPRODUCT_FLAG_STRUCT, \
 758           IGNORE_RANGE, \
 759           IGNORE_CONSTRAINT, \
 760           IGNORE_WRITEABLE)
 761 #endif // COMPILER1
 762 #ifdef COMPILER2
 763  C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \
 764           C2_PD_DEVELOP_FLAG_STRUCT, \
 765           C2_PRODUCT_FLAG_STRUCT, \
 766           C2_PD_PRODUCT_FLAG_STRUCT, \
 767           C2_DIAGNOSTIC_FLAG_STRUCT, \
 768           C2_EXPERIMENTAL_FLAG_STRUCT, \
 769           C2_NOTPRODUCT_FLAG_STRUCT, \
 770           IGNORE_RANGE, \
 771           IGNORE_CONSTRAINT, \
 772           IGNORE_WRITEABLE)
 773 #endif // COMPILER2
 774 #ifdef SHARK
 775  SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \
 776              SHARK_PD_DEVELOP_FLAG_STRUCT, \
 777              SHARK_PRODUCT_FLAG_STRUCT, \
 778              SHARK_PD_PRODUCT_FLAG_STRUCT, \
 779              SHARK_DIAGNOSTIC_FLAG_STRUCT, \
 780              SHARK_NOTPRODUCT_FLAG_STRUCT, \
 781              IGNORE_RANGE, \
 782              IGNORE_CONSTRAINT, \
 783              IGNORE_WRITEABLE)
 784 #endif // SHARK
 785  ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
 786             ARCH_PRODUCT_FLAG_STRUCT, \
 787             ARCH_DIAGNOSTIC_FLAG_STRUCT, \
 788             ARCH_EXPERIMENTAL_FLAG_STRUCT, \
 789             ARCH_NOTPRODUCT_FLAG_STRUCT, \
 790             IGNORE_RANGE, \
 791             IGNORE_CONSTRAINT, \
 792             IGNORE_WRITEABLE)
 793  FLAGTABLE_EXT
 794  {0, NULL, NULL}
 795 };
 796 
 797 Flag* Flag::flags = flagTable;
 798 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
 799 
 800 inline bool str_equal(const char* s, const char* q, size_t len) {
 801   // s is null terminated, q is not!
 802   if (strlen(s) != (unsigned int) len) return false;
 803   return strncmp(s, q, len) == 0;
 804 }
 805 
 806 // Search the flag table for a named flag
 807 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
 808   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 809     if (str_equal(current->_name, name, length)) {
 810       // Found a matching entry.
 811       // Don't report notproduct and develop flags in product builds.
 812       if (current->is_constant_in_binary()) {
 813         return (return_flag ? current : NULL);
 814       }
 815       // Report locked flags only if allowed.
 816       if (!(current->is_unlocked() || current->is_unlocker())) {
 817         if (!allow_locked) {
 818           // disable use of locked flags, e.g. diagnostic, experimental,
 819           // commercial... until they are explicitly unlocked
 820           return NULL;
 821         }
 822       }
 823       return current;
 824     }
 825   }
 826   // Flag name is not in the flag table
 827   return NULL;
 828 }
 829 
 830 // Compute string similarity based on Dice's coefficient
 831 static float str_similar(const char* str1, const char* str2, size_t len2) {
 832   int len1 = (int) strlen(str1);
 833   int total = len1 + (int) len2;
 834 
 835   int hit = 0;
 836 
 837   for (int i = 0; i < len1 -1; ++i) {
 838     for (int j = 0; j < (int) len2 -1; ++j) {
 839       if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
 840         ++hit;
 841         break;
 842       }
 843     }
 844   }
 845 
 846   return 2.0f * (float) hit / (float) total;
 847 }
 848 
 849 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
 850   float VMOptionsFuzzyMatchSimilarity = 0.7f;
 851   Flag* match = NULL;
 852   float score;
 853   float max_score = -1;
 854 
 855   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
 856     score = str_similar(current->_name, name, length);
 857     if (score > max_score) {
 858       max_score = score;
 859       match = current;
 860     }
 861   }
 862 
 863   if (!(match->is_unlocked() || match->is_unlocker())) {
 864     if (!allow_locked) {
 865       return NULL;
 866     }
 867   }
 868 
 869   if (max_score < VMOptionsFuzzyMatchSimilarity) {
 870     return NULL;
 871   }
 872 
 873   return match;
 874 }
 875 
 876 // Returns the address of the index'th element
 877 static Flag* address_of_flag(CommandLineFlagWithType flag) {
 878   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 879   return &Flag::flags[flag];
 880 }
 881 
 882 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
 883   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 884   Flag* f = &Flag::flags[flag];
 885   return f->is_default();
 886 }
 887 
 888 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
 889   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 890   Flag* f = &Flag::flags[flag];
 891   return f->is_ergonomic();
 892 }
 893 
 894 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
 895   assert((size_t)flag < Flag::numFlags, "bad command line flag index");
 896   Flag* f = &Flag::flags[flag];
 897   return f->is_command_line();
 898 }
 899 
 900 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
 901   Flag* result = Flag::find_flag((char*)name, strlen(name));
 902   if (result == NULL) return false;
 903   *value = result->is_command_line();
 904   return true;
 905 }
 906 
 907 template<class E, class T>
 908 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
 909   E e;
 910   e.set_name(name);
 911   e.set_old_value(old_value);
 912   e.set_new_value(new_value);
 913   e.set_origin(origin);
 914   e.commit();
 915 }
 916 
 917 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose) {
 918   Flag::Error status = Flag::SUCCESS;
 919   CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 920   if (constraint != NULL) {
 921     status = constraint->apply_bool(new_value, verbose);
 922   }
 923   return status;
 924 }
 925 
 926 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* 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_bool()) return Flag::WRONG_FORMAT;
 930   *value = result->get_bool();
 931   return Flag::SUCCESS;
 932 }
 933 
 934 Flag::Error CommandLineFlags::boolAtPut(Flag* flag, bool* value, Flag::Flags origin) {
 935   const char* name;
 936   if (flag == NULL) return Flag::INVALID_FLAG;
 937   if (!flag->is_bool()) return Flag::WRONG_FORMAT;
 938   name = flag->_name;
 939   Flag::Error check = apply_constraint_and_check_range_bool(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 940   if (check != Flag::SUCCESS) return check;
 941   bool old_value = flag->get_bool();
 942   trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
 943   check = flag->set_bool(*value);
 944   *value = old_value;
 945   flag->set_origin(origin);
 946   return check;
 947 }
 948 
 949 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
 950   Flag* result = Flag::find_flag(name, len);
 951   return boolAtPut(result, value, origin);
 952 }
 953 
 954 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
 955   Flag* faddr = address_of_flag(flag);
 956   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
 957   return CommandLineFlags::boolAtPut(faddr, &value, origin);
 958 }
 959 
 960 static Flag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose) {
 961   Flag::Error status = Flag::SUCCESS;
 962   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 963   if (range != NULL) {
 964     status = range->check_int(new_value, verbose);
 965   }
 966   if (status == Flag::SUCCESS) {
 967     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
 968     if (constraint != NULL) {
 969       status = constraint->apply_int(new_value, verbose);
 970     }
 971   }
 972   return status;
 973 }
 974 
 975 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* 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_int()) return Flag::WRONG_FORMAT;
 979   *value = result->get_int();
 980   return Flag::SUCCESS;
 981 }
 982 
 983 Flag::Error CommandLineFlags::intAtPut(Flag* flag, int* value, Flag::Flags origin) {
 984   const char* name;
 985   if (flag == NULL) return Flag::INVALID_FLAG;
 986   if (!flag->is_int()) return Flag::WRONG_FORMAT;
 987   name = flag->_name;
 988   Flag::Error check = apply_constraint_and_check_range_int(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
 989   if (check != Flag::SUCCESS) return check;
 990   int old_value = flag->get_int();
 991   trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
 992   check = flag->set_int(*value);
 993   *value = old_value;
 994   flag->set_origin(origin);
 995   return check;
 996 }
 997 
 998 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
 999   Flag* result = Flag::find_flag(name, len);
1000   return intAtPut(result, value, origin);
1001 }
1002 
1003 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
1004   Flag* faddr = address_of_flag(flag);
1005   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
1006   return CommandLineFlags::intAtPut(faddr, &value, origin);
1007 }
1008 
1009 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose) {
1010   Flag::Error status = Flag::SUCCESS;
1011   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1012   if (range != NULL) {
1013     status = range->check_uint(new_value, verbose);
1014   }
1015   if (status == Flag::SUCCESS) {
1016     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1017     if (constraint != NULL) {
1018       status = constraint->apply_uint(new_value, verbose);
1019     }
1020   }
1021   return status;
1022 }
1023 
1024 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* 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_uint()) return Flag::WRONG_FORMAT;
1028   *value = result->get_uint();
1029   return Flag::SUCCESS;
1030 }
1031 
1032 Flag::Error CommandLineFlags::uintAtPut(Flag* flag, uint* value, Flag::Flags origin) {
1033   const char* name;
1034   if (flag == NULL) return Flag::INVALID_FLAG;
1035   if (!flag->is_uint()) return Flag::WRONG_FORMAT;
1036   name = flag->_name;
1037   Flag::Error check = apply_constraint_and_check_range_uint(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1038   if (check != Flag::SUCCESS) return check;
1039   uint old_value = flag->get_uint();
1040   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
1041   check = flag->set_uint(*value);
1042   *value = old_value;
1043   flag->set_origin(origin);
1044   return check;
1045 }
1046 
1047 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
1048   Flag* result = Flag::find_flag(name, len);
1049   return uintAtPut(result, value, origin);
1050 }
1051 
1052 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
1053   Flag* faddr = address_of_flag(flag);
1054   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
1055   return CommandLineFlags::uintAtPut(faddr, &value, origin);
1056 }
1057 
1058 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
1059   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1060   if (result == NULL) return Flag::INVALID_FLAG;
1061   if (!result->is_intx()) return Flag::WRONG_FORMAT;
1062   *value = result->get_intx();
1063   return Flag::SUCCESS;
1064 }
1065 
1066 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose) {
1067   Flag::Error status = Flag::SUCCESS;
1068   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1069   if (range != NULL) {
1070     status = range->check_intx(new_value, verbose);
1071   }
1072   if (status == Flag::SUCCESS) {
1073     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1074     if (constraint != NULL) {
1075       status = constraint->apply_intx(new_value, verbose);
1076     }
1077   }
1078   return status;
1079 }
1080 
1081 Flag::Error CommandLineFlags::intxAtPut(Flag* flag, intx* value, Flag::Flags origin) {
1082   const char* name;
1083   if (flag == NULL) return Flag::INVALID_FLAG;
1084   if (!flag->is_intx()) return Flag::WRONG_FORMAT;
1085   name = flag->_name;
1086   Flag::Error check = apply_constraint_and_check_range_intx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1087   if (check != Flag::SUCCESS) return check;
1088   intx old_value = flag->get_intx();
1089   trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
1090   check = flag->set_intx(*value);
1091   *value = old_value;
1092   flag->set_origin(origin);
1093   return check;
1094 }
1095 
1096 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
1097   Flag* result = Flag::find_flag(name, len);
1098   return intxAtPut(result, value, origin);
1099 }
1100 
1101 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
1102   Flag* faddr = address_of_flag(flag);
1103   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
1104   return CommandLineFlags::intxAtPut(faddr, &value, origin);
1105 }
1106 
1107 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
1108   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1109   if (result == NULL) return Flag::INVALID_FLAG;
1110   if (!result->is_uintx()) return Flag::WRONG_FORMAT;
1111   *value = result->get_uintx();
1112   return Flag::SUCCESS;
1113 }
1114 
1115 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose) {
1116   Flag::Error status = Flag::SUCCESS;
1117   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1118   if (range != NULL) {
1119     status = range->check_uintx(new_value, verbose);
1120   }
1121   if (status == Flag::SUCCESS) {
1122     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1123     if (constraint != NULL) {
1124       status = constraint->apply_uintx(new_value, verbose);
1125     }
1126   }
1127   return status;
1128 }
1129 
1130 Flag::Error CommandLineFlags::uintxAtPut(Flag* flag, uintx* value, Flag::Flags origin) {
1131   const char* name;
1132   if (flag == NULL) return Flag::INVALID_FLAG;
1133   if (!flag->is_uintx()) return Flag::WRONG_FORMAT;
1134   name = flag->_name;
1135   Flag::Error check = apply_constraint_and_check_range_uintx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1136   if (check != Flag::SUCCESS) return check;
1137   uintx old_value = flag->get_uintx();
1138   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1139   check = flag->set_uintx(*value);
1140   *value = old_value;
1141   flag->set_origin(origin);
1142   return check;
1143 }
1144 
1145 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
1146   Flag* result = Flag::find_flag(name, len);
1147   return uintxAtPut(result, value, origin);
1148 }
1149 
1150 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
1151   Flag* faddr = address_of_flag(flag);
1152   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
1153   return CommandLineFlags::uintxAtPut(faddr, &value, origin);
1154 }
1155 
1156 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
1157   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1158   if (result == NULL) return Flag::INVALID_FLAG;
1159   if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1160   *value = result->get_uint64_t();
1161   return Flag::SUCCESS;
1162 }
1163 
1164 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose) {
1165   Flag::Error status = Flag::SUCCESS;
1166   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1167   if (range != NULL) {
1168     status = range->check_uint64_t(new_value, verbose);
1169   }
1170   if (status == Flag::SUCCESS) {
1171     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1172     if (constraint != NULL) {
1173       status = constraint->apply_uint64_t(new_value, verbose);
1174     }
1175   }
1176   return status;
1177 }
1178 
1179 Flag::Error CommandLineFlags::uint64_tAtPut(Flag* flag, uint64_t* value, Flag::Flags origin) {
1180   const char* name;
1181   if (flag == NULL) return Flag::INVALID_FLAG;
1182   if (!flag->is_uint64_t()) return Flag::WRONG_FORMAT;
1183   name = flag->_name;
1184   Flag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1185   if (check != Flag::SUCCESS) return check;
1186   uint64_t old_value = flag->get_uint64_t();
1187   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1188   check = flag->set_uint64_t(*value);
1189   *value = old_value;
1190   flag->set_origin(origin);
1191   return check;
1192 }
1193 
1194 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
1195   Flag* result = Flag::find_flag(name, len);
1196   return uint64_tAtPut(result, value, origin);
1197 }
1198 
1199 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
1200   Flag* faddr = address_of_flag(flag);
1201   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
1202   return CommandLineFlags::uint64_tAtPut(faddr, &value, origin);
1203 }
1204 
1205 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
1206   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1207   if (result == NULL) return Flag::INVALID_FLAG;
1208   if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1209   *value = result->get_size_t();
1210   return Flag::SUCCESS;
1211 }
1212 
1213 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose) {
1214   Flag::Error status = Flag::SUCCESS;
1215   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1216   if (range != NULL) {
1217     status = range->check_size_t(new_value, verbose);
1218   }
1219   if (status == Flag::SUCCESS) {
1220     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1221     if (constraint != NULL) {
1222       status = constraint->apply_size_t(new_value, verbose);
1223     }
1224   }
1225   return status;
1226 }
1227 
1228 
1229 Flag::Error CommandLineFlags::size_tAtPut(Flag* flag, size_t* value, Flag::Flags origin) {
1230   const char* name;
1231   if (flag == NULL) return Flag::INVALID_FLAG;
1232   if (!flag->is_size_t()) return Flag::WRONG_FORMAT;
1233   name = flag->_name;
1234   Flag::Error check = apply_constraint_and_check_range_size_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1235   if (check != Flag::SUCCESS) return check;
1236   size_t old_value = flag->get_size_t();
1237   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1238   check = flag->set_size_t(*value);
1239   *value = old_value;
1240   flag->set_origin(origin);
1241   return check;
1242 }
1243 
1244 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
1245   Flag* result = Flag::find_flag(name, len);
1246   return size_tAtPut(result, value, origin);
1247 }
1248 
1249 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
1250   Flag* faddr = address_of_flag(flag);
1251   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
1252   return CommandLineFlags::size_tAtPut(faddr, &value, origin);
1253 }
1254 
1255 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
1256   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1257   if (result == NULL) return Flag::INVALID_FLAG;
1258   if (!result->is_double()) return Flag::WRONG_FORMAT;
1259   *value = result->get_double();
1260   return Flag::SUCCESS;
1261 }
1262 
1263 static Flag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose) {
1264   Flag::Error status = Flag::SUCCESS;
1265   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1266   if (range != NULL) {
1267     status = range->check_double(new_value, verbose);
1268   }
1269   if (status == Flag::SUCCESS) {
1270     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
1271     if (constraint != NULL) {
1272       status = constraint->apply_double(new_value, verbose);
1273     }
1274   }
1275   return status;
1276 }
1277 
1278 Flag::Error CommandLineFlags::doubleAtPut(Flag* flag, double* value, Flag::Flags origin) {
1279   const char* name;
1280   if (flag == NULL) return Flag::INVALID_FLAG;
1281   if (!flag->is_double()) return Flag::WRONG_FORMAT;
1282   name = flag->_name;
1283   Flag::Error check = apply_constraint_and_check_range_double(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
1284   if (check != Flag::SUCCESS) return check;
1285   double old_value = flag->get_double();
1286   trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
1287   check = flag->set_double(*value);
1288   *value = old_value;
1289   flag->set_origin(origin);
1290   return check;
1291 }
1292 
1293 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
1294   Flag* result = Flag::find_flag(name, len);
1295   return doubleAtPut(result, value, origin);
1296 }
1297 
1298 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
1299   Flag* faddr = address_of_flag(flag);
1300   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
1301   return CommandLineFlags::doubleAtPut(faddr, &value, origin);
1302 }
1303 
1304 Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
1305   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1306   if (result == NULL) return Flag::INVALID_FLAG;
1307   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1308   *value = result->get_ccstr();
1309   return Flag::SUCCESS;
1310 }
1311 
1312 Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
1313   Flag* result = Flag::find_flag(name, len);
1314   if (result == NULL) return Flag::INVALID_FLAG;
1315   if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
1316   ccstr old_value = result->get_ccstr();
1317   trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
1318   char* new_value = NULL;
1319   if (*value != NULL) {
1320     new_value = os::strdup_check_oom(*value);
1321   }
1322   Flag::Error check = result->set_ccstr(new_value);
1323   if (result->is_default() && old_value != NULL) {
1324     // Prior value is NOT heap allocated, but was a literal constant.
1325     old_value = os::strdup_check_oom(old_value);
1326   }
1327   *value = old_value;
1328   result->set_origin(origin);
1329   return check;
1330 }
1331 
1332 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
1333   Flag* faddr = address_of_flag(flag);
1334   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
1335   ccstr old_value = faddr->get_ccstr();
1336   trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
1337   char* new_value = os::strdup_check_oom(value);
1338   Flag::Error check = faddr->set_ccstr(new_value);
1339   if (!faddr->is_default() && old_value != NULL) {
1340     // Prior value is heap allocated so free it.
1341     FREE_C_HEAP_ARRAY(char, old_value);
1342   }
1343   faddr->set_origin(origin);
1344   return check;
1345 }
1346 
1347 extern "C" {
1348   static int compare_flags(const void* void_a, const void* void_b) {
1349     return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1350   }
1351 }
1352 
1353 void CommandLineFlags::printSetFlags(outputStream* out) {
1354   // Print which flags were set on the command line
1355   // note: this method is called before the thread structure is in place
1356   //       which means resource allocation cannot be used.
1357 
1358   // The last entry is the null entry.
1359   const size_t length = Flag::numFlags - 1;
1360 
1361   // Sort
1362   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments);
1363   for (size_t i = 0; i < length; i++) {
1364     array[i] = &flagTable[i];
1365   }
1366   qsort(array, length, sizeof(Flag*), compare_flags);
1367 
1368   // Print
1369   for (size_t i = 0; i < length; i++) {
1370     if (array[i]->get_origin() /* naked field! */) {
1371       array[i]->print_as_flag(out);
1372       out->print(" ");
1373     }
1374   }
1375   out->cr();
1376   FREE_C_HEAP_ARRAY(Flag*, array);
1377 }
1378 
1379 #ifndef PRODUCT
1380 
1381 void CommandLineFlags::verify() {
1382   assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
1383 }
1384 
1385 #endif // PRODUCT
1386 
1387 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
1388   // Print the flags sorted by name
1389   // note: this method is called before the thread structure is in place
1390   //       which means resource allocation cannot be used.
1391 
1392   // The last entry is the null entry.
1393   const size_t length = Flag::numFlags - 1;
1394 
1395   // Sort
1396   Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments);
1397   for (size_t i = 0; i < length; i++) {
1398     array[i] = &flagTable[i];
1399   }
1400   qsort(array, length, sizeof(Flag*), compare_flags);
1401 
1402   // Print
1403   if (!printRanges) {
1404     out->print_cr("[Global flags]");
1405   } else {
1406     out->print_cr("[Global flags ranges]");
1407   }
1408 
1409   for (size_t i = 0; i < length; i++) {
1410     if (array[i]->is_unlocked()) {
1411       array[i]->print_on(out, withComments, printRanges);
1412     }
1413   }
1414   FREE_C_HEAP_ARRAY(Flag*, array);
1415 }