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     JIMAGE_RESOURCE  = 8,
46 
47     LAST_VALUE_ORIGIN = JIMAGE_RESOURCE,
48     VALUE_ORIGIN_BITS = 4,
49     VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS),
50 
51     // flag kind
52     KIND_PRODUCT            = 1 << 4,
53     KIND_MANAGEABLE         = 1 << 5,
54     KIND_DIAGNOSTIC         = 1 << 6,
55     KIND_EXPERIMENTAL       = 1 << 7,
56     KIND_NOT_PRODUCT        = 1 << 8,
57     KIND_DEVELOP            = 1 << 9,
58     KIND_PLATFORM_DEPENDENT = 1 << 10,
59     KIND_READ_WRITE         = 1 << 11,
60     KIND_C1                 = 1 << 12,
61     KIND_C2                 = 1 << 13,
62     KIND_ARCH               = 1 << 14,
63     KIND_LP64_PRODUCT       = 1 << 15,
64     KIND_JVMCI              = 1 << 16,
65 
66     // set this bit if the flag was set on the command line
67     ORIG_COMMAND_LINE       = 1 << 17,
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   };
106 
107   const char* _type;
108   const char* _name;
109   void* _addr;
110   NOT_PRODUCT(const char* _doc;)
111   Flags _flags;
112   size_t _name_len;
113 
114   // points to all Flags static array
115   static JVMFlag* flags;
116 
117   // number of flags
118   static size_t numFlags;
119 
find_flagJVMFlag120   static JVMFlag* find_flag(const char* name) { return find_flag(name, strlen(name), true, true); };
121   static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked = false, bool return_flag = false);
122   static JVMFlag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
123 
124   static const char* get_int_default_range_str();
125   static const char* get_uint_default_range_str();
126   static const char* get_intx_default_range_str();
127   static const char* get_uintx_default_range_str();
128   static const char* get_uint64_t_default_range_str();
129   static const char* get_size_t_default_range_str();
130   static const char* get_double_default_range_str();
131 
132   JVMFlag::Error check_writable(bool changed);
133 
134   bool is_bool() const;
135   bool get_bool() const;
136   JVMFlag::Error set_bool(bool value);
137 
138   bool is_int() const;
139   int get_int() const;
140   JVMFlag::Error set_int(int value);
141 
142   bool is_uint() const;
143   uint get_uint() const;
144   JVMFlag::Error set_uint(uint value);
145 
146   bool is_intx() const;
147   intx get_intx() const;
148   JVMFlag::Error set_intx(intx value);
149 
150   bool is_uintx() const;
151   uintx get_uintx() const;
152   JVMFlag::Error set_uintx(uintx value);
153 
154   bool is_uint64_t() const;
155   uint64_t get_uint64_t() const;
156   JVMFlag::Error set_uint64_t(uint64_t value);
157 
158   bool is_size_t() const;
159   size_t get_size_t() const;
160   JVMFlag::Error set_size_t(size_t value);
161 
162   bool is_double() const;
163   double get_double() const;
164   JVMFlag::Error set_double(double value);
165 
166   bool is_ccstr() const;
167   bool ccstr_accumulates() const;
168   ccstr get_ccstr() const;
169   JVMFlag::Error set_ccstr(ccstr value);
170 
171   Flags get_origin();
172   void set_origin(Flags origin);
173 
174   size_t get_name_length();
175 
176   bool is_default();
177   bool is_ergonomic();
178   bool is_jimage_resource();
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 
215 public:
216   static JVMFlag::Error boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false);
boolAtJVMFlag217   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);
boolAtPutJVMFlag220   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);
intAtJVMFlag223   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);
intAtPutJVMFlag226   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);
uintAtJVMFlag229   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);
uintAtPutJVMFlag232   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);
intxAtJVMFlag235   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);
intxAtPutJVMFlag238   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);
uintxAtJVMFlag241   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);
uintxAtPutJVMFlag244   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);
size_tAtJVMFlag247   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);
size_tAtPutJVMFlag250   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);
uint64_tAtJVMFlag253   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);
uint64_tAtPutJVMFlag256   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);
doubleAtJVMFlag259   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);
doubleAtPutJVMFlag262   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);
ccstrAtJVMFlag265   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);
ccstrAtPutJVMFlag269   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, ...);
278 
279   static void verify() PRODUCT_RETURN;
280 };
281 
282 #endif // SHARE_VM_RUNTIME_FLAGS_JVMFLAG_HPP
283