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
31class outputStream;
32
33// function type that will construct default range string
34typedef const char* (*RangeStrFunc)(void);
35
36struct 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 withComments = 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
215public:
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 withComments, 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