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