1 /*
   2  * Copyright (c) 1997, 2018, 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 #ifndef SHARE_VM_RUNTIME_FLAGS_JVMFLAG_HPP
  26 #define SHARE_VM_RUNTIME_FLAGS_JVMFLAG_HPP
  27 
  28 #include "utilities/globalDefinitions.hpp"
  29 #include "utilities/macros.hpp"
  30 
  31 // function type that will construct default range string
  32 typedef const char* (*RangeStrFunc)(void);
  33 
  34 struct JVMFlag {
  35   enum Flags {
  36     // latest value origin
  37     DEFAULT          = 0,
  38     COMMAND_LINE     = 1,
  39     ENVIRON_VAR      = 2,
  40     CONFIG_FILE      = 3,
  41     MANAGEMENT       = 4,
  42     ERGONOMIC        = 5,
  43     ATTACH_ON_DEMAND = 6,
  44     INTERNAL         = 7,
  45 
  46     LAST_VALUE_ORIGIN = INTERNAL,
  47     VALUE_ORIGIN_BITS = 4,
  48     VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS),
  49 
  50     // flag kind
  51     KIND_PRODUCT            = 1 << 4,
  52     KIND_MANAGEABLE         = 1 << 5,
  53     KIND_DIAGNOSTIC         = 1 << 6,
  54     KIND_EXPERIMENTAL       = 1 << 7,
  55     KIND_NOT_PRODUCT        = 1 << 8,
  56     KIND_DEVELOP            = 1 << 9,
  57     KIND_PLATFORM_DEPENDENT = 1 << 10,
  58     KIND_READ_WRITE         = 1 << 11,
  59     KIND_C1                 = 1 << 12,
  60     KIND_C2                 = 1 << 13,
  61     KIND_ARCH               = 1 << 14,
  62     KIND_LP64_PRODUCT       = 1 << 15,
  63     KIND_COMMERCIAL         = 1 << 16,
  64     KIND_JVMCI              = 1 << 17,
  65 
  66     // set this bit if the flag was set on the command line
  67     ORIG_COMMAND_LINE       = 1 << 18,
  68 
  69     KIND_MASK = ~(VALUE_ORIGIN_MASK | ORIG_COMMAND_LINE)
  70   };
  71 
  72   enum Error {
  73     // no error
  74     SUCCESS = 0,
  75     // flag name is missing
  76     MISSING_NAME,
  77     // flag value is missing
  78     MISSING_VALUE,
  79     // error parsing the textual form of the value
  80     WRONG_FORMAT,
  81     // flag is not writable
  82     NON_WRITABLE,
  83     // flag value is outside of its bounds
  84     OUT_OF_BOUNDS,
  85     // flag value violates its constraint
  86     VIOLATES_CONSTRAINT,
  87     // there is no flag with the given name
  88     INVALID_FLAG,
  89     // the flag can only be set only on command line during invocation of the VM
  90     COMMAND_LINE_ONLY,
  91     // the flag may only be set once
  92     SET_ONLY_ONCE,
  93     // the flag is not writable in this combination of product/debug build
  94     CONSTANT,
  95     // other, unspecified error related to setting the flag
  96     ERR_OTHER
  97   };
  98 
  99   enum MsgType {
 100     NONE = 0,
 101     DIAGNOSTIC_FLAG_BUT_LOCKED,
 102     EXPERIMENTAL_FLAG_BUT_LOCKED,
 103     DEVELOPER_FLAG_BUT_PRODUCT_BUILD,
 104     NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD,
 105     COMMERCIAL_FLAG_BUT_DISABLED,
 106     COMMERCIAL_FLAG_BUT_LOCKED
 107   };
 108 
 109   const char* _type;
 110   const char* _name;
 111   void* _addr;
 112   NOT_PRODUCT(const char* _doc;)
 113   Flags _flags;
 114   size_t _name_len;
 115 
 116   // points to all Flags static array
 117   static JVMFlag* flags;
 118 
 119   // number of flags
 120   static size_t numFlags;
 121 
 122   static JVMFlag* find_flag(const char* name) { return find_flag(name, strlen(name), true, true); };
 123   static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked = false, bool return_flag = false);
 124   static JVMFlag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
 125 
 126   static const char* get_int_default_range_str();
 127   static const char* get_uint_default_range_str();
 128   static const char* get_intx_default_range_str();
 129   static const char* get_uintx_default_range_str();
 130   static const char* get_uint64_t_default_range_str();
 131   static const char* get_size_t_default_range_str();
 132   static const char* get_double_default_range_str();
 133 
 134   JVMFlag::Error check_writable(bool changed);
 135 
 136   bool is_bool() const;
 137   bool get_bool() const;
 138   JVMFlag::Error set_bool(bool value);
 139 
 140   bool is_int() const;
 141   int get_int() const;
 142   JVMFlag::Error set_int(int value);
 143 
 144   bool is_uint() const;
 145   uint get_uint() const;
 146   JVMFlag::Error set_uint(uint value);
 147 
 148   bool is_intx() const;
 149   intx get_intx() const;
 150   JVMFlag::Error set_intx(intx value);
 151 
 152   bool is_uintx() const;
 153   uintx get_uintx() const;
 154   JVMFlag::Error set_uintx(uintx value);
 155 
 156   bool is_uint64_t() const;
 157   uint64_t get_uint64_t() const;
 158   JVMFlag::Error set_uint64_t(uint64_t value);
 159 
 160   bool is_size_t() const;
 161   size_t get_size_t() const;
 162   JVMFlag::Error set_size_t(size_t value);
 163 
 164   bool is_double() const;
 165   double get_double() const;
 166   JVMFlag::Error set_double(double value);
 167 
 168   bool is_ccstr() const;
 169   bool ccstr_accumulates() const;
 170   ccstr get_ccstr() const;
 171   JVMFlag::Error set_ccstr(ccstr value);
 172 
 173   Flags get_origin();
 174   void set_origin(Flags origin);
 175 
 176   size_t get_name_length();
 177 
 178   bool is_default();
 179   bool is_ergonomic();
 180   bool is_command_line();
 181   void set_command_line();
 182 
 183   bool is_product() const;
 184   bool is_manageable() const;
 185   bool is_diagnostic() const;
 186   bool is_experimental() const;
 187   bool is_notproduct() const;
 188   bool is_develop() const;
 189   bool is_read_write() const;
 190   bool is_commercial() const;
 191 
 192   bool is_constant_in_binary() const;
 193 
 194   bool is_unlocker() const;
 195   bool is_unlocked() const;
 196   bool is_writeable() const;
 197   bool is_external() const;
 198 
 199   bool is_unlocker_ext() const;
 200   bool is_unlocked_ext() const;
 201   bool is_writeable_ext() const;
 202   bool is_external_ext() const;
 203 
 204   void clear_diagnostic();
 205 
 206   JVMFlag::MsgType get_locked_message(char*, int) const;
 207   JVMFlag::MsgType get_locked_message_ext(char*, int) const;
 208 
 209   // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
 210   void print_on(outputStream* st, bool withComments = false, bool printRanges = false);
 211   void print_kind(outputStream* st, unsigned int width);
 212   void print_origin(outputStream* st, unsigned int width);
 213   void print_as_flag(outputStream* st);
 214 
 215   static const char* flag_error_str(JVMFlag::Error error);
 216 
 217 public:
 218   static JVMFlag::Error boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false);
 219   static JVMFlag::Error boolAt(const char* name, bool* value, bool allow_locked = false, bool return_flag = false)      { return boolAt(name, strlen(name), value, allow_locked, return_flag); }
 220   static JVMFlag::Error boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin);
 221   static JVMFlag::Error boolAtPut(const char* name, size_t len, bool* value, JVMFlag::Flags origin);
 222   static JVMFlag::Error boolAtPut(const char* name, bool* value, JVMFlag::Flags origin)   { return boolAtPut(name, strlen(name), value, origin); }
 223 
 224   static JVMFlag::Error intAt(const char* name, size_t len, int* value, bool allow_locked = false, bool return_flag = false);
 225   static JVMFlag::Error intAt(const char* name, int* value, bool allow_locked = false, bool return_flag = false)      { return intAt(name, strlen(name), value, allow_locked, return_flag); }
 226   static JVMFlag::Error intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin);
 227   static JVMFlag::Error intAtPut(const char* name, size_t len, int* value, JVMFlag::Flags origin);
 228   static JVMFlag::Error intAtPut(const char* name, int* value, JVMFlag::Flags origin)   { return intAtPut(name, strlen(name), value, origin); }
 229 
 230   static JVMFlag::Error uintAt(const char* name, size_t len, uint* value, bool allow_locked = false, bool return_flag = false);
 231   static JVMFlag::Error uintAt(const char* name, uint* value, bool allow_locked = false, bool return_flag = false)      { return uintAt(name, strlen(name), value, allow_locked, return_flag); }
 232   static JVMFlag::Error uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin);
 233   static JVMFlag::Error uintAtPut(const char* name, size_t len, uint* value, JVMFlag::Flags origin);
 234   static JVMFlag::Error uintAtPut(const char* name, uint* value, JVMFlag::Flags origin)   { return uintAtPut(name, strlen(name), value, origin); }
 235 
 236   static JVMFlag::Error intxAt(const char* name, size_t len, intx* value, bool allow_locked = false, bool return_flag = false);
 237   static JVMFlag::Error intxAt(const char* name, intx* value, bool allow_locked = false, bool return_flag = false)      { return intxAt(name, strlen(name), value, allow_locked, return_flag); }
 238   static JVMFlag::Error intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin);
 239   static JVMFlag::Error intxAtPut(const char* name, size_t len, intx* value, JVMFlag::Flags origin);
 240   static JVMFlag::Error intxAtPut(const char* name, intx* value, JVMFlag::Flags origin)   { return intxAtPut(name, strlen(name), value, origin); }
 241 
 242   static JVMFlag::Error uintxAt(const char* name, size_t len, uintx* value, bool allow_locked = false, bool return_flag = false);
 243   static JVMFlag::Error uintxAt(const char* name, uintx* value, bool allow_locked = false, bool return_flag = false)    { return uintxAt(name, strlen(name), value, allow_locked, return_flag); }
 244   static JVMFlag::Error uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin);
 245   static JVMFlag::Error uintxAtPut(const char* name, size_t len, uintx* value, JVMFlag::Flags origin);
 246   static JVMFlag::Error uintxAtPut(const char* name, uintx* value, JVMFlag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
 247 
 248   static JVMFlag::Error size_tAt(const char* name, size_t len, size_t* value, bool allow_locked = false, bool return_flag = false);
 249   static JVMFlag::Error size_tAt(const char* name, size_t* value, bool allow_locked = false, bool return_flag = false)    { return size_tAt(name, strlen(name), value, allow_locked, return_flag); }
 250   static JVMFlag::Error size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin);
 251   static JVMFlag::Error size_tAtPut(const char* name, size_t len, size_t* value, JVMFlag::Flags origin);
 252   static JVMFlag::Error size_tAtPut(const char* name, size_t* value, JVMFlag::Flags origin) { return size_tAtPut(name, strlen(name), value, origin); }
 253 
 254   static JVMFlag::Error uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked = false, bool return_flag = false);
 255   static JVMFlag::Error uint64_tAt(const char* name, uint64_t* value, bool allow_locked = false, bool return_flag = false) { return uint64_tAt(name, strlen(name), value, allow_locked, return_flag); }
 256   static JVMFlag::Error uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin);
 257   static JVMFlag::Error uint64_tAtPut(const char* name, size_t len, uint64_t* value, JVMFlag::Flags origin);
 258   static JVMFlag::Error uint64_tAtPut(const char* name, uint64_t* value, JVMFlag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
 259 
 260   static JVMFlag::Error doubleAt(const char* name, size_t len, double* value, bool allow_locked = false, bool return_flag = false);
 261   static JVMFlag::Error doubleAt(const char* name, double* value, bool allow_locked = false, bool return_flag = false)    { return doubleAt(name, strlen(name), value, allow_locked, return_flag); }
 262   static JVMFlag::Error doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin);
 263   static JVMFlag::Error doubleAtPut(const char* name, size_t len, double* value, JVMFlag::Flags origin);
 264   static JVMFlag::Error doubleAtPut(const char* name, double* value, JVMFlag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
 265 
 266   static JVMFlag::Error ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked = false, bool return_flag = false);
 267   static JVMFlag::Error ccstrAt(const char* name, ccstr* value, bool allow_locked = false, bool return_flag = false)    { return ccstrAt(name, strlen(name), value, allow_locked, return_flag); }
 268   // Contract:  JVMFlag will make private copy of the incoming value.
 269   // Outgoing value is always malloc-ed, and caller MUST call free.
 270   static JVMFlag::Error ccstrAtPut(const char* name, size_t len, ccstr* value, JVMFlag::Flags origin);
 271   static JVMFlag::Error ccstrAtPut(const char* name, ccstr* value, JVMFlag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
 272 
 273   // Returns false if name is not a command line flag.
 274   static bool wasSetOnCmdline(const char* name, bool* value);
 275   static void printSetFlags(outputStream* out);
 276 
 277   // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
 278   static void printFlags(outputStream* out, bool withComments, bool printRanges = false, bool skipDefaults = false);
 279   static void printError(bool verbose, const char* msg, ...);
 280 
 281   static void verify() PRODUCT_RETURN;
 282 };
 283 
 284 #endif // SHARE_VM_RUNTIME_FLAGS_JVMFLAG_HPP