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