1/*
2 * Copyright (c) 2015, 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#include "precompiled.hpp"
26#include "code/relocInfo.hpp"
27#include "compiler/compilerDefinitions.hpp"
28#include "oops/metadata.hpp"
29#include "runtime/os.hpp"
30#include "interpreter/invocationCounter.hpp"
31#include "runtime/arguments.hpp"
32#include "runtime/flags/jvmFlag.hpp"
33#include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
34#include "runtime/globals.hpp"
35#include "runtime/globals_extension.hpp"
36
37JVMFlag::Error AliasLevelConstraintFunc(intx value, bool verbose) {
38 if ((value <= 1) && (Arguments::mode() == Arguments::_comp || Arguments::mode() == Arguments::_mixed)) {
39 JVMFlag::printError(verbose,
40 "AliasLevel (" INTX_FORMAT ") is not "
41 "compatible with -Xcomp or -Xmixed\n",
42 value);
43 return JVMFlag::VIOLATES_CONSTRAINT;
44 } else {
45 return JVMFlag::SUCCESS;
46 }
47}
48
49/**
50 * Validate the minimum number of compiler threads needed to run the
51 * JVM. The following configurations are possible.
52 *
53 * 1) The JVM is build using an interpreter only. As a result, the minimum number of
54 * compiler threads is 0.
55 * 2) The JVM is build using the compiler(s) and tiered compilation is disabled. As
56 * a result, either C1 or C2 is used, so the minimum number of compiler threads is 1.
57 * 3) The JVM is build using the compiler(s) and tiered compilation is enabled. However,
58 * the option "TieredStopAtLevel < CompLevel_full_optimization". As a result, only
59 * C1 can be used, so the minimum number of compiler threads is 1.
60 * 4) The JVM is build using the compilers and tiered compilation is enabled. The option
61 * 'TieredStopAtLevel = CompLevel_full_optimization' (the default value). As a result,
62 * the minimum number of compiler threads is 2.
63 */
64JVMFlag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
65 int min_number_of_compiler_threads = 0;
66#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
67 // case 1
68#else
69 if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
70 min_number_of_compiler_threads = 1; // case 2 or case 3
71 } else {
72 min_number_of_compiler_threads = 2; // case 4 (tiered)
73 }
74#endif
75
76 // The default CICompilerCount's value is CI_COMPILER_COUNT.
77 // With a client VM, -XX:+TieredCompilation causes TieredCompilation
78 // to be true here (the option is validated later) and
79 // min_number_of_compiler_threads to exceed CI_COMPILER_COUNT.
80 min_number_of_compiler_threads = MIN2(min_number_of_compiler_threads, CI_COMPILER_COUNT);
81
82 if (value < (intx)min_number_of_compiler_threads) {
83 JVMFlag::printError(verbose,
84 "CICompilerCount (" INTX_FORMAT ") must be "
85 "at least %d \n",
86 value, min_number_of_compiler_threads);
87 return JVMFlag::VIOLATES_CONSTRAINT;
88 } else {
89 return JVMFlag::SUCCESS;
90 }
91}
92
93JVMFlag::Error AllocatePrefetchDistanceConstraintFunc(intx value, bool verbose) {
94 if (value < 0 || value > 512) {
95 JVMFlag::printError(verbose,
96 "AllocatePrefetchDistance (" INTX_FORMAT ") must be "
97 "between 0 and %d\n",
98 AllocatePrefetchDistance, 512);
99 return JVMFlag::VIOLATES_CONSTRAINT;
100 }
101
102 return JVMFlag::SUCCESS;
103}
104
105JVMFlag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose) {
106 if (AllocatePrefetchStyle == 3) {
107 if (value % wordSize != 0) {
108 JVMFlag::printError(verbose,
109 "AllocatePrefetchStepSize (" INTX_FORMAT ") must be multiple of %d\n",
110 value, wordSize);
111 return JVMFlag::VIOLATES_CONSTRAINT;
112 }
113 }
114 return JVMFlag::SUCCESS;
115}
116
117JVMFlag::Error AllocatePrefetchInstrConstraintFunc(intx value, bool verbose) {
118 intx max_value = max_intx;
119#if defined(SPARC)
120 max_value = 1;
121#elif defined(X86)
122 max_value = 3;
123#endif
124 if (value < 0 || value > max_value) {
125 JVMFlag::printError(verbose,
126 "AllocatePrefetchInstr (" INTX_FORMAT ") must be "
127 "between 0 and " INTX_FORMAT "\n", value, max_value);
128 return JVMFlag::VIOLATES_CONSTRAINT;
129 }
130
131 return JVMFlag::SUCCESS;
132}
133
134JVMFlag::Error CompileThresholdConstraintFunc(intx value, bool verbose) {
135 if (value < 0 || value > INT_MAX >> InvocationCounter::count_shift) {
136 JVMFlag::printError(verbose,
137 "CompileThreshold (" INTX_FORMAT ") "
138 "must be between 0 and %d\n",
139 value,
140 INT_MAX >> InvocationCounter::count_shift);
141 return JVMFlag::VIOLATES_CONSTRAINT;
142 }
143
144 return JVMFlag::SUCCESS;
145}
146
147JVMFlag::Error OnStackReplacePercentageConstraintFunc(intx value, bool verbose) {
148 int64_t max_percentage_limit = INT_MAX;
149 if (!ProfileInterpreter) {
150 max_percentage_limit = (max_percentage_limit>>InvocationCounter::count_shift);
151 }
152 max_percentage_limit = CompileThreshold == 0 ? max_percentage_limit*100 : max_percentage_limit*100/CompileThreshold;
153
154 if (ProfileInterpreter) {
155 if (value < InterpreterProfilePercentage) {
156 JVMFlag::printError(verbose,
157 "OnStackReplacePercentage (" INTX_FORMAT ") must be "
158 "larger than InterpreterProfilePercentage (" INTX_FORMAT ")\n",
159 value, InterpreterProfilePercentage);
160 return JVMFlag::VIOLATES_CONSTRAINT;
161 }
162
163 max_percentage_limit += InterpreterProfilePercentage;
164 if (value > max_percentage_limit) {
165 JVMFlag::printError(verbose,
166 "OnStackReplacePercentage (" INTX_FORMAT ") must be between 0 and " INT64_FORMAT "\n",
167 value,
168 max_percentage_limit);
169 return JVMFlag::VIOLATES_CONSTRAINT;
170 }
171 } else {
172 if (value < 0) {
173 JVMFlag::printError(verbose,
174 "OnStackReplacePercentage (" INTX_FORMAT ") must be "
175 "non-negative\n", value);
176 return JVMFlag::VIOLATES_CONSTRAINT;
177 }
178
179 if (value > max_percentage_limit) {
180 JVMFlag::printError(verbose,
181 "OnStackReplacePercentage (" INTX_FORMAT ") must be between 0 and " INT64_FORMAT "\n",
182 value,
183 max_percentage_limit);
184 return JVMFlag::VIOLATES_CONSTRAINT;
185 }
186 }
187 return JVMFlag::SUCCESS;
188}
189
190JVMFlag::Error CodeCacheSegmentSizeConstraintFunc(uintx value, bool verbose) {
191 if (CodeCacheSegmentSize < (uintx)CodeEntryAlignment) {
192 JVMFlag::printError(verbose,
193 "CodeCacheSegmentSize (" UINTX_FORMAT ") must be "
194 "larger than or equal to CodeEntryAlignment (" INTX_FORMAT ") "
195 "to align entry points\n",
196 CodeCacheSegmentSize, CodeEntryAlignment);
197 return JVMFlag::VIOLATES_CONSTRAINT;
198 }
199
200 if (CodeCacheSegmentSize < sizeof(jdouble)) {
201 JVMFlag::printError(verbose,
202 "CodeCacheSegmentSize (" UINTX_FORMAT ") must be "
203 "at least " SIZE_FORMAT " to align constants\n",
204 CodeCacheSegmentSize, sizeof(jdouble));
205 return JVMFlag::VIOLATES_CONSTRAINT;
206 }
207
208#ifdef COMPILER2
209 if (CodeCacheSegmentSize < (uintx)OptoLoopAlignment) {
210 JVMFlag::printError(verbose,
211 "CodeCacheSegmentSize (" UINTX_FORMAT ") must be "
212 "larger than or equal to OptoLoopAlignment (" INTX_FORMAT ") "
213 "to align inner loops\n",
214 CodeCacheSegmentSize, OptoLoopAlignment);
215 return JVMFlag::VIOLATES_CONSTRAINT;
216 }
217#endif
218
219 return JVMFlag::SUCCESS;
220}
221
222JVMFlag::Error CompilerThreadPriorityConstraintFunc(intx value, bool verbose) {
223#ifdef SOLARIS
224 if ((value < MinimumPriority || value > MaximumPriority) &&
225 (value != -1) && (value != -FXCriticalPriority)) {
226 JVMFlag::printError(verbose,
227 "CompileThreadPriority (" INTX_FORMAT ") must be "
228 "between %d and %d inclusively or -1 (means no change) "
229 "or %d (special value for critical thread class/priority)\n",
230 value, MinimumPriority, MaximumPriority, -FXCriticalPriority);
231 return JVMFlag::VIOLATES_CONSTRAINT;
232 }
233#endif
234
235 return JVMFlag::SUCCESS;
236}
237
238JVMFlag::Error CodeEntryAlignmentConstraintFunc(intx value, bool verbose) {
239#ifdef SPARC
240 if (CodeEntryAlignment % relocInfo::addr_unit() != 0) {
241 JVMFlag::printError(verbose,
242 "CodeEntryAlignment (" INTX_FORMAT ") must be "
243 "multiple of NOP size\n", CodeEntryAlignment);
244 return JVMFlag::VIOLATES_CONSTRAINT;
245 }
246#endif
247
248 if (!is_power_of_2(value)) {
249 JVMFlag::printError(verbose,
250 "CodeEntryAlignment (" INTX_FORMAT ") must be "
251 "a power of two\n", CodeEntryAlignment);
252 return JVMFlag::VIOLATES_CONSTRAINT;
253 }
254
255 if (CodeEntryAlignment < 16) {
256 JVMFlag::printError(verbose,
257 "CodeEntryAlignment (" INTX_FORMAT ") must be "
258 "greater than or equal to %d\n",
259 CodeEntryAlignment, 16);
260 return JVMFlag::VIOLATES_CONSTRAINT;
261 }
262
263 return JVMFlag::SUCCESS;
264}
265
266JVMFlag::Error OptoLoopAlignmentConstraintFunc(intx value, bool verbose) {
267 if (!is_power_of_2(value)) {
268 JVMFlag::printError(verbose,
269 "OptoLoopAlignment (" INTX_FORMAT ") "
270 "must be a power of two\n",
271 value);
272 return JVMFlag::VIOLATES_CONSTRAINT;
273 }
274
275 // Relevant on ppc, s390, sparc. Will be optimized where
276 // addr_unit() == 1.
277 if (OptoLoopAlignment % relocInfo::addr_unit() != 0) {
278 JVMFlag::printError(verbose,
279 "OptoLoopAlignment (" INTX_FORMAT ") must be "
280 "multiple of NOP size (%d)\n",
281 value, relocInfo::addr_unit());
282 return JVMFlag::VIOLATES_CONSTRAINT;
283 }
284
285 return JVMFlag::SUCCESS;
286}
287
288JVMFlag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
289 if (value >= 4032) {
290 JVMFlag::printError(verbose,
291 "ArraycopyDstPrefetchDistance (" UINTX_FORMAT ") must be"
292 "between 0 and 4031\n", value);
293 return JVMFlag::VIOLATES_CONSTRAINT;
294 }
295
296 return JVMFlag::SUCCESS;
297}
298
299JVMFlag::Error ArraycopySrcPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
300 if (value >= 4032) {
301 JVMFlag::printError(verbose,
302 "ArraycopySrcPrefetchDistance (" UINTX_FORMAT ") must be"
303 "between 0 and 4031\n", value);
304 return JVMFlag::VIOLATES_CONSTRAINT;
305 }
306
307 return JVMFlag::SUCCESS;
308}
309
310JVMFlag::Error TypeProfileLevelConstraintFunc(uintx value, bool verbose) {
311 for (int i = 0; i < 3; i++) {
312 if (value % 10 > 2) {
313 JVMFlag::printError(verbose,
314 "Invalid value (" UINTX_FORMAT ") "
315 "in TypeProfileLevel at position %d\n", value, i);
316 return JVMFlag::VIOLATES_CONSTRAINT;
317 }
318 value = value / 10;
319 }
320
321 return JVMFlag::SUCCESS;
322}
323
324JVMFlag::Error InitArrayShortSizeConstraintFunc(intx value, bool verbose) {
325 if (value % BytesPerLong != 0) {
326 return JVMFlag::VIOLATES_CONSTRAINT;
327 } else {
328 return JVMFlag::SUCCESS;
329 }
330}
331
332#ifdef COMPILER2
333JVMFlag::Error InteriorEntryAlignmentConstraintFunc(intx value, bool verbose) {
334 if (InteriorEntryAlignment > CodeEntryAlignment) {
335 JVMFlag::printError(verbose,
336 "InteriorEntryAlignment (" INTX_FORMAT ") must be "
337 "less than or equal to CodeEntryAlignment (" INTX_FORMAT ")\n",
338 InteriorEntryAlignment, CodeEntryAlignment);
339 return JVMFlag::VIOLATES_CONSTRAINT;
340 }
341
342#ifdef SPARC
343 if (InteriorEntryAlignment % relocInfo::addr_unit() != 0) {
344 JVMFlag::printError(verbose,
345 "InteriorEntryAlignment (" INTX_FORMAT ") must be "
346 "multiple of NOP size\n");
347 return JVMFlag::VIOLATES_CONSTRAINT;
348 }
349#endif
350
351 if (!is_power_of_2(value)) {
352 JVMFlag::printError(verbose,
353 "InteriorEntryAlignment (" INTX_FORMAT ") must be "
354 "a power of two\n", InteriorEntryAlignment);
355 return JVMFlag::VIOLATES_CONSTRAINT;
356 }
357
358 int minimum_alignment = 16;
359#if defined(SPARC) || (defined(X86) && !defined(AMD64))
360 minimum_alignment = 4;
361#elif defined(S390)
362 minimum_alignment = 2;
363#endif
364
365 if (InteriorEntryAlignment < minimum_alignment) {
366 JVMFlag::printError(verbose,
367 "InteriorEntryAlignment (" INTX_FORMAT ") must be "
368 "greater than or equal to %d\n",
369 InteriorEntryAlignment, minimum_alignment);
370 return JVMFlag::VIOLATES_CONSTRAINT;
371 }
372
373 return JVMFlag::SUCCESS;
374}
375
376JVMFlag::Error NodeLimitFudgeFactorConstraintFunc(intx value, bool verbose) {
377 if (value < MaxNodeLimit * 2 / 100 || value > MaxNodeLimit * 40 / 100) {
378 JVMFlag::printError(verbose,
379 "NodeLimitFudgeFactor must be between 2%% and 40%% "
380 "of MaxNodeLimit (" INTX_FORMAT ")\n",
381 MaxNodeLimit);
382 return JVMFlag::VIOLATES_CONSTRAINT;
383 }
384
385 return JVMFlag::SUCCESS;
386}
387#endif // COMPILER2
388
389JVMFlag::Error RTMTotalCountIncrRateConstraintFunc(int value, bool verbose) {
390#if INCLUDE_RTM_OPT
391 if (UseRTMLocking && !is_power_of_2(RTMTotalCountIncrRate)) {
392 JVMFlag::printError(verbose,
393 "RTMTotalCountIncrRate (%d) must be "
394 "a power of 2, resetting it to 64\n",
395 RTMTotalCountIncrRate);
396 FLAG_SET_DEFAULT(RTMTotalCountIncrRate, 64);
397 }
398#endif
399
400 return JVMFlag::SUCCESS;
401}
402