1 /*
2 * Copyright (c) 2015, 2020, 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 #include "precompiled.hpp"
26 #include "classfile/stringTable.hpp"
27 #include "classfile/symbolTable.hpp"
28 #include "gc/shared/jvmFlagConstraintsGC.hpp"
29 #include "runtime/arguments.hpp"
30 #include "runtime/flags/jvmFlag.hpp"
31 #include "runtime/flags/jvmFlagConstraintList.hpp"
32 #include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
33 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
34 #include "runtime/globals.hpp"
35 #include "runtime/globals_extension.hpp"
36 #include "runtime/os.hpp"
37 #include "utilities/macros.hpp"
38
39 class JVMFlagConstraint_bool : public JVMFlagConstraint {
40 JVMFlagConstraintFunc_bool _constraint;
41
42 public:
JVMFlagConstraint_bool(const JVMFlag * flag,JVMFlagConstraintFunc_bool func,ConstraintType type)43 JVMFlagConstraint_bool(const JVMFlag* flag,
44 JVMFlagConstraintFunc_bool func,
45 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
46
apply(bool verbose)47 JVMFlag::Error apply(bool verbose) {
48 return _constraint(_flag->get_bool(), verbose);
49 }
50
apply_bool(bool value,bool verbose)51 JVMFlag::Error apply_bool(bool value, bool verbose) {
52 return _constraint(value, verbose);
53 }
54 };
55
56 class JVMFlagConstraint_int : public JVMFlagConstraint {
57 JVMFlagConstraintFunc_int _constraint;
58
59 public:
JVMFlagConstraint_int(const JVMFlag * flag,JVMFlagConstraintFunc_int func,ConstraintType type)60 JVMFlagConstraint_int(const JVMFlag* flag,
61 JVMFlagConstraintFunc_int func,
62 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
63
apply(bool verbose)64 JVMFlag::Error apply(bool verbose) {
65 return _constraint(_flag->get_int(), verbose);
66 }
67
apply_int(int value,bool verbose)68 JVMFlag::Error apply_int(int value, bool verbose) {
69 return _constraint(value, verbose);
70 }
71 };
72
73 class JVMFlagConstraint_intx : public JVMFlagConstraint {
74 JVMFlagConstraintFunc_intx _constraint;
75
76 public:
JVMFlagConstraint_intx(const JVMFlag * flag,JVMFlagConstraintFunc_intx func,ConstraintType type)77 JVMFlagConstraint_intx(const JVMFlag* flag,
78 JVMFlagConstraintFunc_intx func,
79 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
80
apply(bool verbose)81 JVMFlag::Error apply(bool verbose) {
82 return _constraint(_flag->get_intx(), verbose);
83 }
84
apply_intx(intx value,bool verbose)85 JVMFlag::Error apply_intx(intx value, bool verbose) {
86 return _constraint(value, verbose);
87 }
88 };
89
90 class JVMFlagConstraint_uint : public JVMFlagConstraint {
91 JVMFlagConstraintFunc_uint _constraint;
92
93 public:
JVMFlagConstraint_uint(const JVMFlag * flag,JVMFlagConstraintFunc_uint func,ConstraintType type)94 JVMFlagConstraint_uint(const JVMFlag* flag,
95 JVMFlagConstraintFunc_uint func,
96 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
97
apply(bool verbose)98 JVMFlag::Error apply(bool verbose) {
99 return _constraint(_flag->get_uint(), verbose);
100 }
101
apply_uint(uint value,bool verbose)102 JVMFlag::Error apply_uint(uint value, bool verbose) {
103 return _constraint(value, verbose);
104 }
105 };
106
107 class JVMFlagConstraint_uintx : public JVMFlagConstraint {
108 JVMFlagConstraintFunc_uintx _constraint;
109
110 public:
JVMFlagConstraint_uintx(const JVMFlag * flag,JVMFlagConstraintFunc_uintx func,ConstraintType type)111 JVMFlagConstraint_uintx(const JVMFlag* flag,
112 JVMFlagConstraintFunc_uintx func,
113 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
114
apply(bool verbose)115 JVMFlag::Error apply(bool verbose) {
116 return _constraint(_flag->get_uintx(), verbose);
117 }
118
apply_uintx(uintx value,bool verbose)119 JVMFlag::Error apply_uintx(uintx value, bool verbose) {
120 return _constraint(value, verbose);
121 }
122 };
123
124 class JVMFlagConstraint_uint64_t : public JVMFlagConstraint {
125 JVMFlagConstraintFunc_uint64_t _constraint;
126
127 public:
JVMFlagConstraint_uint64_t(const JVMFlag * flag,JVMFlagConstraintFunc_uint64_t func,ConstraintType type)128 JVMFlagConstraint_uint64_t(const JVMFlag* flag,
129 JVMFlagConstraintFunc_uint64_t func,
130 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
131
apply(bool verbose)132 JVMFlag::Error apply(bool verbose) {
133 return _constraint(_flag->get_uint64_t(), verbose);
134 }
135
apply_uint64_t(uint64_t value,bool verbose)136 JVMFlag::Error apply_uint64_t(uint64_t value, bool verbose) {
137 return _constraint(value, verbose);
138 }
139 };
140
141 class JVMFlagConstraint_size_t : public JVMFlagConstraint {
142 JVMFlagConstraintFunc_size_t _constraint;
143
144 public:
JVMFlagConstraint_size_t(const JVMFlag * flag,JVMFlagConstraintFunc_size_t func,ConstraintType type)145 JVMFlagConstraint_size_t(const JVMFlag* flag,
146 JVMFlagConstraintFunc_size_t func,
147 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
148
apply(bool verbose)149 JVMFlag::Error apply(bool verbose) {
150 return _constraint(_flag->get_size_t(), verbose);
151 }
152
apply_size_t(size_t value,bool verbose)153 JVMFlag::Error apply_size_t(size_t value, bool verbose) {
154 return _constraint(value, verbose);
155 }
156 };
157
158 class JVMFlagConstraint_double : public JVMFlagConstraint {
159 JVMFlagConstraintFunc_double _constraint;
160
161 public:
JVMFlagConstraint_double(const JVMFlag * flag,JVMFlagConstraintFunc_double func,ConstraintType type)162 JVMFlagConstraint_double(const JVMFlag* flag,
163 JVMFlagConstraintFunc_double func,
164 ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
165
apply(bool verbose)166 JVMFlag::Error apply(bool verbose) {
167 return _constraint(_flag->get_double(), verbose);
168 }
169
apply_double(double value,bool verbose)170 JVMFlag::Error apply_double(double value, bool verbose) {
171 return _constraint(value, verbose);
172 }
173 };
174
175 // No constraint emitting
emit_constraint_no(...)176 void emit_constraint_no(...) { /* NOP */ }
177
178 // No constraint emitting if function argument is NOT provided
emit_constraint_bool(const JVMFlag *)179 void emit_constraint_bool(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_ccstr(const JVMFlag *)180 void emit_constraint_ccstr(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_ccstrlist(const JVMFlag *)181 void emit_constraint_ccstrlist(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_int(const JVMFlag *)182 void emit_constraint_int(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_intx(const JVMFlag *)183 void emit_constraint_intx(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_uint(const JVMFlag *)184 void emit_constraint_uint(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_uintx(const JVMFlag *)185 void emit_constraint_uintx(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_uint64_t(const JVMFlag *)186 void emit_constraint_uint64_t(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_size_t(const JVMFlag *)187 void emit_constraint_size_t(const JVMFlag* /*flag*/) { /* NOP */ }
emit_constraint_double(const JVMFlag *)188 void emit_constraint_double(const JVMFlag* /*flag*/) { /* NOP */ }
189
190 // JVMFlagConstraint emitting code functions if function argument is provided
emit_constraint_bool(const JVMFlag * flag,JVMFlagConstraintFunc_bool func,JVMFlagConstraint::ConstraintType type)191 void emit_constraint_bool(const JVMFlag* flag, JVMFlagConstraintFunc_bool func, JVMFlagConstraint::ConstraintType type) {
192 JVMFlagConstraintList::add(new JVMFlagConstraint_bool(flag, func, type));
193 }
emit_constraint_int(const JVMFlag * flag,JVMFlagConstraintFunc_int func,JVMFlagConstraint::ConstraintType type)194 void emit_constraint_int(const JVMFlag* flag, JVMFlagConstraintFunc_int func, JVMFlagConstraint::ConstraintType type) {
195 JVMFlagConstraintList::add(new JVMFlagConstraint_int(flag, func, type));
196 }
emit_constraint_intx(const JVMFlag * flag,JVMFlagConstraintFunc_intx func,JVMFlagConstraint::ConstraintType type)197 void emit_constraint_intx(const JVMFlag* flag, JVMFlagConstraintFunc_intx func, JVMFlagConstraint::ConstraintType type) {
198 JVMFlagConstraintList::add(new JVMFlagConstraint_intx(flag, func, type));
199 }
emit_constraint_uint(const JVMFlag * flag,JVMFlagConstraintFunc_uint func,JVMFlagConstraint::ConstraintType type)200 void emit_constraint_uint(const JVMFlag* flag, JVMFlagConstraintFunc_uint func, JVMFlagConstraint::ConstraintType type) {
201 JVMFlagConstraintList::add(new JVMFlagConstraint_uint(flag, func, type));
202 }
emit_constraint_uintx(const JVMFlag * flag,JVMFlagConstraintFunc_uintx func,JVMFlagConstraint::ConstraintType type)203 void emit_constraint_uintx(const JVMFlag* flag, JVMFlagConstraintFunc_uintx func, JVMFlagConstraint::ConstraintType type) {
204 JVMFlagConstraintList::add(new JVMFlagConstraint_uintx(flag, func, type));
205 }
emit_constraint_uint64_t(const JVMFlag * flag,JVMFlagConstraintFunc_uint64_t func,JVMFlagConstraint::ConstraintType type)206 void emit_constraint_uint64_t(const JVMFlag* flag, JVMFlagConstraintFunc_uint64_t func, JVMFlagConstraint::ConstraintType type) {
207 JVMFlagConstraintList::add(new JVMFlagConstraint_uint64_t(flag, func, type));
208 }
emit_constraint_size_t(const JVMFlag * flag,JVMFlagConstraintFunc_size_t func,JVMFlagConstraint::ConstraintType type)209 void emit_constraint_size_t(const JVMFlag* flag, JVMFlagConstraintFunc_size_t func, JVMFlagConstraint::ConstraintType type) {
210 JVMFlagConstraintList::add(new JVMFlagConstraint_size_t(flag, func, type));
211 }
emit_constraint_double(const JVMFlag * flag,JVMFlagConstraintFunc_double func,JVMFlagConstraint::ConstraintType type)212 void emit_constraint_double(const JVMFlag* flag, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) {
213 JVMFlagConstraintList::add(new JVMFlagConstraint_double(flag, func, type));
214 }
215
216 // Generate code to call emit_constraint_xxx function
217 #define EMIT_CONSTRAINT_START (void)(0
218 #define EMIT_CONSTRAINT(type, name) ); emit_constraint_##type(JVMFlagEx::flag_from_enum(FLAG_MEMBER_ENUM(name))
219 #define EMIT_CONSTRAINT_NO ); emit_constraint_no(0
220 #define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
221 #define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
222 #define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
223 #define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
224 #define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
225 #define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc) EMIT_CONSTRAINT(type, name)
226 #define EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG(type, name, doc) EMIT_CONSTRAINT(type, name)
227 #ifndef PRODUCT
228 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
229 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) EMIT_CONSTRAINT(type, name)
230 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
231 #else
232 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO
233 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) EMIT_CONSTRAINT_NO
234 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO
235 #endif
236 #ifdef _LP64
237 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
238 #else
239 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO
240 #endif
241 #define EMIT_CONSTRAINT_END );
242
243 // Generate func argument to pass into emit_constraint_xxx functions
244 #define EMIT_CONSTRAINT_CHECK(func, type) , func, JVMFlagConstraint::type
245
246 // the "name" argument must be a string literal
247 #define INITIAL_CONSTRAINTS_SIZE 72
248 GrowableArray<JVMFlagConstraint*>* JVMFlagConstraintList::_constraints = NULL;
249 JVMFlagConstraint::ConstraintType JVMFlagConstraintList::_validating_type = JVMFlagConstraint::AtParse;
250
251 // Check the ranges of all flags that have them or print them out and exit if requested
init(void)252 void JVMFlagConstraintList::init(void) {
253 _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
254
255 EMIT_CONSTRAINT_START
256
257 ALL_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
258 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
259 EMIT_CONSTRAINT_PRODUCT_FLAG,
260 EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
261 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
262 EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG,
263 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
264 EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
265 EMIT_CONSTRAINT_MANAGEABLE_FLAG,
266 EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
267 EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
268 IGNORE_RANGE,
269 EMIT_CONSTRAINT_CHECK)
270
271 EMIT_CONSTRAINT_END
272 }
273
find(const JVMFlag * flag)274 JVMFlagConstraint* JVMFlagConstraintList::find(const JVMFlag* flag) {
275 JVMFlagConstraint* found = NULL;
276 for (int i=0; i<length(); i++) {
277 JVMFlagConstraint* constraint = at(i);
278 if (constraint->flag() == flag) {
279 found = constraint;
280 break;
281 }
282 }
283 return found;
284 }
285
286 // Find constraints and return only if found constraint's type is equal or lower than current validating type.
find_if_needs_check(const JVMFlag * flag)287 JVMFlagConstraint* JVMFlagConstraintList::find_if_needs_check(const JVMFlag* flag) {
288 JVMFlagConstraint* found = NULL;
289 JVMFlagConstraint* constraint = find(flag);
290 if (constraint != NULL && (constraint->type() <= _validating_type)) {
291 found = constraint;
292 }
293 return found;
294 }
295
296 // Check constraints for specific constraint type.
check_constraints(JVMFlagConstraint::ConstraintType type)297 bool JVMFlagConstraintList::check_constraints(JVMFlagConstraint::ConstraintType type) {
298 guarantee(type > _validating_type, "Constraint check is out of order.");
299 _validating_type = type;
300
301 bool status = true;
302 for (int i=0; i<length(); i++) {
303 JVMFlagConstraint* constraint = at(i);
304 if (type != constraint->type()) continue;
305 if (constraint->apply(true) != JVMFlag::SUCCESS) status = false;
306 }
307 return status;
308 }
309