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