summaryrefslogtreecommitdiffstats
path: root/js/src/jit/JitOptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/JitOptions.cpp')
-rw-r--r--js/src/jit/JitOptions.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp
new file mode 100644
index 000000000..eb5a6c1c2
--- /dev/null
+++ b/js/src/jit/JitOptions.cpp
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "jit/JitOptions.h"
+#include "mozilla/TypeTraits.h"
+
+#include <cstdlib>
+#include "jsfun.h"
+using namespace js;
+using namespace js::jit;
+
+using mozilla::Maybe;
+
+namespace js {
+namespace jit {
+
+DefaultJitOptions JitOptions;
+
+static void Warn(const char* env, const char* value)
+{
+ fprintf(stderr, "Warning: I didn't understand %s=\"%s\"\n", env, value);
+}
+
+template<typename T> struct IsBool : mozilla::FalseType {};
+template<> struct IsBool<bool> : mozilla::TrueType {};
+
+static Maybe<int>
+ParseInt(const char* str)
+{
+ char* endp;
+ int retval = strtol(str, &endp, 0);
+ if (*endp == '\0')
+ return mozilla::Some(retval);
+ return mozilla::Nothing();
+}
+
+template<typename T>
+T overrideDefault(const char* param, T dflt) {
+ char* str = getenv(param);
+ if (!str)
+ return dflt;
+ if (IsBool<T>::value) {
+ if (strcmp(str, "true") == 0 || strcmp(str, "yes") == 0)
+ return true;
+ if (strcmp(str, "false") == 0 || strcmp(str, "no") == 0)
+ return false;
+ Warn(param, str);
+ } else {
+ Maybe<int> value = ParseInt(str);
+ if (value.isSome())
+ return value.ref();
+ Warn(param, str);
+ }
+ return dflt;
+}
+
+#define SET_DEFAULT(var, dflt) var = overrideDefault("JIT_OPTION_" #var, dflt)
+DefaultJitOptions::DefaultJitOptions()
+{
+ // Whether to perform expensive graph-consistency DEBUG-only assertions.
+ // It can be useful to disable this to reduce DEBUG-compile time of large
+ // wasm programs.
+ SET_DEFAULT(checkGraphConsistency, true);
+
+#ifdef CHECK_OSIPOINT_REGISTERS
+ // Emit extra code to verify live regs at the start of a VM call
+ // are not modified before its OsiPoint.
+ SET_DEFAULT(checkOsiPointRegisters, false);
+#endif
+
+ // Whether to enable extra code to perform dynamic validation of
+ // RangeAnalysis results.
+ SET_DEFAULT(checkRangeAnalysis, false);
+
+ // Toggles whether IonBuilder fallbacks to a call if we fail to inline.
+ SET_DEFAULT(disableInlineBacktracking, true);
+
+ // Toggles whether Alignment Mask Analysis is globally disabled.
+ SET_DEFAULT(disableAma, false);
+
+ // Toggles whether Effective Address Analysis is globally disabled.
+ SET_DEFAULT(disableEaa, false);
+
+ // Toggle whether eager simd unboxing is globally disabled.
+ SET_DEFAULT(disableEagerSimdUnbox, false);
+
+ // Toggles whether Edge Case Analysis is gobally disabled.
+ SET_DEFAULT(disableEdgeCaseAnalysis, false);
+
+ // Toggles whether to use flow sensitive Alias Analysis.
+ SET_DEFAULT(disableFlowAA, true);
+
+ // Toggle whether global value numbering is globally disabled.
+ SET_DEFAULT(disableGvn, false);
+
+ // Toggles whether inlining is globally disabled.
+ SET_DEFAULT(disableInlining, false);
+
+ // Toggles whether loop invariant code motion is globally disabled.
+ SET_DEFAULT(disableLicm, false);
+
+ // Toggles whether Loop Unrolling is globally disabled.
+ SET_DEFAULT(disableLoopUnrolling, true);
+
+ // Toggle whether Profile Guided Optimization is globally disabled.
+ SET_DEFAULT(disablePgo, false);
+
+ // Toggles whether instruction reordering is globally disabled.
+ SET_DEFAULT(disableInstructionReordering, false);
+
+ // Toggles whether Range Analysis is globally disabled.
+ SET_DEFAULT(disableRangeAnalysis, false);
+
+ // Toggles wheter Recover instructions is globally disabled.
+ SET_DEFAULT(disableRecoverIns, false);
+
+ // Toggle whether eager scalar replacement is globally disabled.
+ SET_DEFAULT(disableScalarReplacement, false);
+
+ // Toggles whether CacheIR stubs are used.
+ SET_DEFAULT(disableCacheIR, false);
+
+ // Toggles whether shared stubs are used in Ionmonkey.
+ SET_DEFAULT(disableSharedStubs, false);
+
+ // Toggles whether sincos optimization is globally disabled.
+ // See bug984018: The MacOS is the only one that has the sincos fast.
+ #if defined(XP_MACOSX)
+ SET_DEFAULT(disableSincos, false);
+ #else
+ SET_DEFAULT(disableSincos, true);
+ #endif
+
+ // Toggles whether sink code motion is globally disabled.
+ SET_DEFAULT(disableSink, true);
+
+ // Whether functions are compiled immediately.
+ SET_DEFAULT(eagerCompilation, false);
+
+ // Whether IonBuilder should prefer IC generation above specialized MIR.
+ SET_DEFAULT(forceInlineCaches, false);
+
+ // Toggles whether large scripts are rejected.
+ SET_DEFAULT(limitScriptSize, true);
+
+ // Toggles whether functions may be entered at loop headers.
+ SET_DEFAULT(osr, true);
+
+ // Whether to enable extra code to perform dynamic validations.
+ SET_DEFAULT(runExtraChecks, false);
+
+ // How many invocations or loop iterations are needed before functions
+ // are compiled with the baseline compiler.
+ SET_DEFAULT(baselineWarmUpThreshold, 10);
+
+ // Number of exception bailouts (resuming into catch/finally block) before
+ // we invalidate and forbid Ion compilation.
+ SET_DEFAULT(exceptionBailoutThreshold, 10);
+
+ // Number of bailouts without invalidation before we set
+ // JSScript::hadFrequentBailouts and invalidate.
+ SET_DEFAULT(frequentBailoutThreshold, 10);
+
+ // How many actual arguments are accepted on the C stack.
+ SET_DEFAULT(maxStackArgs, 4096);
+
+ // How many times we will try to enter a script via OSR before
+ // invalidating the script.
+ SET_DEFAULT(osrPcMismatchesBeforeRecompile, 6000);
+
+ // The bytecode length limit for small function.
+ SET_DEFAULT(smallFunctionMaxBytecodeLength_, 130);
+
+ // An artificial testing limit for the maximum supported offset of
+ // pc-relative jump and call instructions.
+ SET_DEFAULT(jumpThreshold, UINT32_MAX);
+
+ // Branch pruning heuristic is based on a scoring system, which is look at
+ // different metrics and provide a score. The score is computed as a
+ // projection where each factor defines the weight of each metric. Then this
+ // score is compared against a threshold to prevent a branch from being
+ // removed.
+ SET_DEFAULT(branchPruningHitCountFactor, 1);
+ SET_DEFAULT(branchPruningInstFactor, 10);
+ SET_DEFAULT(branchPruningBlockSpanFactor, 100);
+ SET_DEFAULT(branchPruningEffectfulInstFactor, 3500);
+ SET_DEFAULT(branchPruningThreshold, 4000);
+
+ // Force how many invocation or loop iterations are needed before compiling
+ // a function with the highest ionmonkey optimization level.
+ // (i.e. OptimizationLevel_Normal)
+ const char* forcedDefaultIonWarmUpThresholdEnv = "JIT_OPTION_forcedDefaultIonWarmUpThreshold";
+ if (const char* env = getenv(forcedDefaultIonWarmUpThresholdEnv)) {
+ Maybe<int> value = ParseInt(env);
+ if (value.isSome())
+ forcedDefaultIonWarmUpThreshold.emplace(value.ref());
+ else
+ Warn(forcedDefaultIonWarmUpThresholdEnv, env);
+ }
+
+ // Same but for compiling small functions.
+ const char* forcedDefaultIonSmallFunctionWarmUpThresholdEnv =
+ "JIT_OPTION_forcedDefaultIonSmallFunctionWarmUpThreshold";
+ if (const char* env = getenv(forcedDefaultIonSmallFunctionWarmUpThresholdEnv)) {
+ Maybe<int> value = ParseInt(env);
+ if (value.isSome())
+ forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(value.ref());
+ else
+ Warn(forcedDefaultIonSmallFunctionWarmUpThresholdEnv, env);
+ }
+
+ // Force the used register allocator instead of letting the optimization
+ // pass decide.
+ const char* forcedRegisterAllocatorEnv = "JIT_OPTION_forcedRegisterAllocator";
+ if (const char* env = getenv(forcedRegisterAllocatorEnv)) {
+ forcedRegisterAllocator = LookupRegisterAllocator(env);
+ if (!forcedRegisterAllocator.isSome())
+ Warn(forcedRegisterAllocatorEnv, env);
+ }
+
+ // Toggles whether unboxed plain objects can be created by the VM.
+ SET_DEFAULT(disableUnboxedObjects, false);
+
+ // Test whether Atomics are allowed in asm.js code.
+ SET_DEFAULT(asmJSAtomicsEnable, false);
+
+ // Test whether wasm int64 / double NaN bits testing is enabled.
+ SET_DEFAULT(wasmTestMode, false);
+
+ // Test whether wasm bounds check should always be generated.
+ SET_DEFAULT(wasmAlwaysCheckBounds, false);
+
+ // Toggles the optimization whereby offsets are folded into loads and not
+ // included in the bounds check.
+ SET_DEFAULT(wasmFoldOffsets, true);
+
+ // Determines whether we suppress using signal handlers
+ // for interrupting jit-ed code. This is used only for testing.
+ SET_DEFAULT(ionInterruptWithoutSignals, false);
+}
+
+bool
+DefaultJitOptions::isSmallFunction(JSScript* script) const
+{
+ return script->length() <= smallFunctionMaxBytecodeLength_;
+}
+
+void
+DefaultJitOptions::enableGvn(bool enable)
+{
+ disableGvn = !enable;
+}
+
+void
+DefaultJitOptions::setEagerCompilation()
+{
+ eagerCompilation = true;
+ baselineWarmUpThreshold = 0;
+ forcedDefaultIonWarmUpThreshold.reset();
+ forcedDefaultIonWarmUpThreshold.emplace(0);
+ forcedDefaultIonSmallFunctionWarmUpThreshold.reset();
+ forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(0);
+}
+
+void
+DefaultJitOptions::setCompilerWarmUpThreshold(uint32_t warmUpThreshold)
+{
+ forcedDefaultIonWarmUpThreshold.reset();
+ forcedDefaultIonWarmUpThreshold.emplace(warmUpThreshold);
+ forcedDefaultIonSmallFunctionWarmUpThreshold.reset();
+ forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(warmUpThreshold);
+
+ // Undo eager compilation
+ if (eagerCompilation && warmUpThreshold != 0) {
+ jit::DefaultJitOptions defaultValues;
+ eagerCompilation = false;
+ baselineWarmUpThreshold = defaultValues.baselineWarmUpThreshold;
+ }
+}
+
+void
+DefaultJitOptions::resetCompilerWarmUpThreshold()
+{
+ forcedDefaultIonWarmUpThreshold.reset();
+
+ // Undo eager compilation
+ if (eagerCompilation) {
+ jit::DefaultJitOptions defaultValues;
+ eagerCompilation = false;
+ baselineWarmUpThreshold = defaultValues.baselineWarmUpThreshold;
+ }
+}
+
+} // namespace jit
+} // namespace js