Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
3
* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "jit/JitOptions.h"
8
#include "mozilla/TypeTraits.h"
9
10
#include <cstdlib>
11
12
#include "vm/JSFunction.h"
13
14
using namespace js;
15
using namespace js::jit;
16
17
using mozilla::Maybe;
18
19
namespace js {
20
namespace jit {
21
22
DefaultJitOptions JitOptions;
23
24
static void Warn(const char* env, const char* value) {
25
fprintf(stderr, "Warning: I didn't understand %s=\"%s\"\n", env, value);
26
}
27
28
template <typename T>
29
struct IsBool : mozilla::FalseType {};
30
template <>
31
struct IsBool<bool> : mozilla::TrueType {};
32
33
static Maybe<int> ParseInt(const char* str) {
34
char* endp;
35
int retval = strtol(str, &endp, 0);
36
if (*endp == '\0') {
37
return mozilla::Some(retval);
38
}
39
return mozilla::Nothing();
40
}
41
42
template <typename T>
43
T overrideDefault(const char* param, T dflt) {
44
char* str = getenv(param);
45
if (!str) {
46
return dflt;
47
}
48
if (IsBool<T>::value) {
49
if (strcmp(str, "true") == 0 || strcmp(str, "yes") == 0) {
50
return true;
51
}
52
if (strcmp(str, "false") == 0 || strcmp(str, "no") == 0) {
53
return false;
54
}
55
Warn(param, str);
56
} else {
57
Maybe<int> value = ParseInt(str);
58
if (value.isSome()) {
59
return value.ref();
60
}
61
Warn(param, str);
62
}
63
return dflt;
64
}
65
66
#define SET_DEFAULT(var, dflt) var = overrideDefault("JIT_OPTION_" #var, dflt)
67
DefaultJitOptions::DefaultJitOptions() {
68
// Whether to perform expensive graph-consistency DEBUG-only assertions.
69
// It can be useful to disable this to reduce DEBUG-compile time of large
70
// wasm programs.
71
SET_DEFAULT(checkGraphConsistency, true);
72
73
#ifdef CHECK_OSIPOINT_REGISTERS
74
// Emit extra code to verify live regs at the start of a VM call
75
// are not modified before its OsiPoint.
76
SET_DEFAULT(checkOsiPointRegisters, false);
77
#endif
78
79
// Whether to enable extra code to perform dynamic validation of
80
// RangeAnalysis results.
81
SET_DEFAULT(checkRangeAnalysis, false);
82
83
// Toggles whether IonBuilder fallbacks to a call if we fail to inline.
84
SET_DEFAULT(disableInlineBacktracking, false);
85
86
// Toggles whether Alignment Mask Analysis is globally disabled.
87
SET_DEFAULT(disableAma, false);
88
89
// Toggles whether Effective Address Analysis is globally disabled.
90
SET_DEFAULT(disableEaa, false);
91
92
// Toggles whether Edge Case Analysis is gobally disabled.
93
SET_DEFAULT(disableEdgeCaseAnalysis, false);
94
95
// Toggle whether global value numbering is globally disabled.
96
SET_DEFAULT(disableGvn, false);
97
98
// Toggles whether inlining is globally disabled.
99
SET_DEFAULT(disableInlining, false);
100
101
// Toggles whether loop invariant code motion is globally disabled.
102
SET_DEFAULT(disableLicm, false);
103
104
// Toggles wheter optimization tracking is globally disabled.
105
SET_DEFAULT(disableOptimizationTracking, true);
106
107
// Toggle whether Profile Guided Optimization is globally disabled.
108
SET_DEFAULT(disablePgo, false);
109
110
// Toggles whether instruction reordering is globally disabled.
111
SET_DEFAULT(disableInstructionReordering, false);
112
113
// Toggles whether Range Analysis is globally disabled.
114
SET_DEFAULT(disableRangeAnalysis, false);
115
116
// Toggles wheter Recover instructions is globally disabled.
117
SET_DEFAULT(disableRecoverIns, false);
118
119
// Toggle whether eager scalar replacement is globally disabled.
120
SET_DEFAULT(disableScalarReplacement, false);
121
122
// Toggles whether CacheIR stubs are used.
123
SET_DEFAULT(disableCacheIR, false);
124
125
// Toggles whether sink code motion is globally disabled.
126
SET_DEFAULT(disableSink, true);
127
128
// Toggles whether the use of multiple Ion optimization levels is globally
129
// disabled.
130
SET_DEFAULT(disableOptimizationLevels, false);
131
132
// Whether the Baseline Interpreter is enabled.
133
SET_DEFAULT(baselineInterpreter, true);
134
135
// Whether the Baseline JIT is enabled.
136
SET_DEFAULT(baselineJit, true);
137
138
// Whether the IonMonkey JIT is enabled.
139
SET_DEFAULT(ion, true);
140
141
// Whether the RegExp JIT is enabled.
142
SET_DEFAULT(nativeRegExp, true);
143
144
// Whether IonBuilder should prefer IC generation above specialized MIR.
145
SET_DEFAULT(forceInlineCaches, false);
146
147
// Toggles whether large scripts are rejected.
148
SET_DEFAULT(limitScriptSize, true);
149
150
// Toggles whether functions may be entered at loop headers.
151
SET_DEFAULT(osr, true);
152
153
// Whether to enable extra code to perform dynamic validations.
154
SET_DEFAULT(runExtraChecks, false);
155
156
// How many invocations or loop iterations are needed before functions
157
// enter the Baseline Interpreter.
158
SET_DEFAULT(baselineInterpreterWarmUpThreshold, 10);
159
160
// How many invocations or loop iterations are needed before functions
161
// are compiled with the baseline compiler.
162
// Duplicated in all.js - ensure both match.
163
SET_DEFAULT(baselineWarmUpThreshold, 50);
164
165
// How many invocations or loop iterations are needed before functions
166
// are compiled with the Ion compiler at OptimizationLevel::Normal.
167
// Duplicated in all.js - ensure both match.
168
SET_DEFAULT(normalIonWarmUpThreshold, 1000);
169
170
// How many invocations or loop iterations are needed before functions
171
// are compiled with the Ion compiler at OptimizationLevel::Full.
172
// Duplicated in all.js - ensure both match.
173
SET_DEFAULT(fullIonWarmUpThreshold, 100'000);
174
175
// Number of exception bailouts (resuming into catch/finally block) before
176
// we invalidate and forbid Ion compilation.
177
SET_DEFAULT(exceptionBailoutThreshold, 10);
178
179
// Number of bailouts without invalidation before we set
180
// JSScript::hadFrequentBailouts and invalidate.
181
// Duplicated in all.js - ensure both match.
182
SET_DEFAULT(frequentBailoutThreshold, 10);
183
184
// Whether to run all debug checks in debug builds.
185
// Disabling might make it more enjoyable to run JS in debug builds.
186
SET_DEFAULT(fullDebugChecks, true);
187
188
// How many actual arguments are accepted on the C stack.
189
SET_DEFAULT(maxStackArgs, 4096);
190
191
// How many times we will try to enter a script via OSR before
192
// invalidating the script.
193
SET_DEFAULT(osrPcMismatchesBeforeRecompile, 6000);
194
195
// The bytecode length limit for small function.
196
SET_DEFAULT(smallFunctionMaxBytecodeLength_, 130);
197
198
// An artificial testing limit for the maximum supported offset of
199
// pc-relative jump and call instructions.
200
SET_DEFAULT(jumpThreshold, UINT32_MAX);
201
202
// Branch pruning heuristic is based on a scoring system, which is look at
203
// different metrics and provide a score. The score is computed as a
204
// projection where each factor defines the weight of each metric. Then this
205
// score is compared against a threshold to prevent a branch from being
206
// removed.
207
SET_DEFAULT(branchPruningHitCountFactor, 1);
208
SET_DEFAULT(branchPruningInstFactor, 10);
209
SET_DEFAULT(branchPruningBlockSpanFactor, 100);
210
SET_DEFAULT(branchPruningEffectfulInstFactor, 3500);
211
SET_DEFAULT(branchPruningThreshold, 4000);
212
213
// Limits on bytecode length and number of locals/arguments for Ion
214
// compilation. There are different (lower) limits for when off-thread Ion
215
// compilation isn't available.
216
SET_DEFAULT(ionMaxScriptSize, 100 * 1000);
217
SET_DEFAULT(ionMaxScriptSizeMainThread, 2 * 1000);
218
SET_DEFAULT(ionMaxLocalsAndArgs, 10 * 1000);
219
SET_DEFAULT(ionMaxLocalsAndArgsMainThread, 256);
220
221
// Force the used register allocator instead of letting the optimization
222
// pass decide.
223
const char* forcedRegisterAllocatorEnv = "JIT_OPTION_forcedRegisterAllocator";
224
if (const char* env = getenv(forcedRegisterAllocatorEnv)) {
225
forcedRegisterAllocator = LookupRegisterAllocator(env);
226
if (!forcedRegisterAllocator.isSome()) {
227
Warn(forcedRegisterAllocatorEnv, env);
228
}
229
}
230
231
#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
232
SET_DEFAULT(spectreIndexMasking, false);
233
SET_DEFAULT(spectreObjectMitigationsBarriers, false);
234
SET_DEFAULT(spectreObjectMitigationsMisc, false);
235
SET_DEFAULT(spectreStringMitigations, false);
236
SET_DEFAULT(spectreValueMasking, false);
237
SET_DEFAULT(spectreJitToCxxCalls, false);
238
#else
239
SET_DEFAULT(spectreIndexMasking, true);
240
SET_DEFAULT(spectreObjectMitigationsBarriers, true);
241
SET_DEFAULT(spectreObjectMitigationsMisc, true);
242
SET_DEFAULT(spectreStringMitigations, true);
243
SET_DEFAULT(spectreValueMasking, true);
244
SET_DEFAULT(spectreJitToCxxCalls, true);
245
#endif
246
247
// These are set to their actual values in InitializeJit.
248
SET_DEFAULT(supportsFloatingPoint, false);
249
SET_DEFAULT(supportsUnalignedAccesses, false);
250
251
// Toggles the optimization whereby offsets are folded into loads and not
252
// included in the bounds check.
253
SET_DEFAULT(wasmFoldOffsets, true);
254
255
// Controls whether two-tiered compilation should be requested when
256
// compiling a new wasm module, independently of other heuristics, and
257
// should be delayed to test both baseline and ion paths in compiled code,
258
// as well as the transition from one tier to the other.
259
SET_DEFAULT(wasmDelayTier2, false);
260
261
// Until which wasm bytecode size should we accumulate functions, in order
262
// to compile efficiently on helper threads. Baseline code compiles much
263
// faster than Ion code so use scaled thresholds (see also bug 1320374).
264
SET_DEFAULT(wasmBatchBaselineThreshold, 10000);
265
SET_DEFAULT(wasmBatchIonThreshold, 1100);
266
267
#ifdef JS_TRACE_LOGGING
268
// Toggles whether the traceLogger should be on or off. In either case,
269
// some data structures will always be created and initialized such as
270
// the traceLoggerState. However, unless this option is set to true
271
// the traceLogger will not be recording any events.
272
SET_DEFAULT(enableTraceLogger, false);
273
#endif
274
275
SET_DEFAULT(enableWasmJitExit, true);
276
SET_DEFAULT(enableWasmJitEntry, true);
277
SET_DEFAULT(enableWasmIonFastCalls, true);
278
#ifdef WASM_CODEGEN_DEBUG
279
SET_DEFAULT(enableWasmImportCallSpew, false);
280
SET_DEFAULT(enableWasmFuncCallSpew, false);
281
#endif
282
}
283
284
bool DefaultJitOptions::isSmallFunction(JSScript* script) const {
285
return script->length() <= smallFunctionMaxBytecodeLength_;
286
}
287
288
void DefaultJitOptions::enableGvn(bool enable) { disableGvn = !enable; }
289
290
void DefaultJitOptions::setEagerIonCompilation() {
291
baselineWarmUpThreshold = 0;
292
normalIonWarmUpThreshold = 0;
293
fullIonWarmUpThreshold = 0;
294
}
295
296
void DefaultJitOptions::setNormalIonWarmUpThreshold(uint32_t warmUpThreshold) {
297
normalIonWarmUpThreshold = warmUpThreshold;
298
299
if (fullIonWarmUpThreshold < normalIonWarmUpThreshold) {
300
fullIonWarmUpThreshold = normalIonWarmUpThreshold;
301
}
302
}
303
304
void DefaultJitOptions::setFullIonWarmUpThreshold(uint32_t warmUpThreshold) {
305
fullIonWarmUpThreshold = warmUpThreshold;
306
307
if (normalIonWarmUpThreshold > fullIonWarmUpThreshold) {
308
setNormalIonWarmUpThreshold(fullIonWarmUpThreshold);
309
}
310
}
311
312
void DefaultJitOptions::resetNormalIonWarmUpThreshold() {
313
jit::DefaultJitOptions defaultValues;
314
setNormalIonWarmUpThreshold(defaultValues.normalIonWarmUpThreshold);
315
}
316
317
void DefaultJitOptions::resetFullIonWarmUpThreshold() {
318
jit::DefaultJitOptions defaultValues;
319
setFullIonWarmUpThreshold(defaultValues.fullIonWarmUpThreshold);
320
}
321
322
} // namespace jit
323
} // namespace js