Bug 1541404 part 32 - Add shell flags for the baseline interpreter. r=tcampbell

This also has some minor changes to allow enabling the Baseline Interpreter without
the Baseline JIT.

After this is enabled by default we want to make the Interpreter a hard dependency
for Baseline (similar to how Ion requires Baseline to be enabled) and then we can
simplify some code, but of course we can't do that yet.

Differential Revision: https://phabricator.services.mozilla.com/D31038

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-07-08 08:18:30 +00:00
parent 11acdc3897
commit 8d5c5fc6da
15 changed files with 88 additions and 25 deletions

View File

@ -1,4 +1,4 @@
// |jit-test| --no-ion; --no-baseline; skip-if: !('gcstate' in this && 'oomAfterAllocations' in this)
// |jit-test| --no-ion; --no-baseline; --no-blinterp; skip-if: !('gcstate' in this && 'oomAfterAllocations' in this)
gczeal(0);

View File

@ -1,4 +1,4 @@
// |jit-test| --no-ion; --no-baseline; skip-if: !('oomAtAllocation' in this)
// |jit-test| --no-ion; --no-baseline; --no-blinterp; skip-if: !('oomAtAllocation' in this)
// This shouldn't assert (bug 1516514).
//
// Disabled for ion and baseline because those introduce OOMs at some point that

View File

@ -1,4 +1,4 @@
// |jit-test| --no-ion; --no-baseline; skip-if: !('oomAfterAllocations' in this)
// |jit-test| --no-ion; --no-baseline; --no-blinterp; skip-if: !('oomAfterAllocations' in this)
// Don't crash on OOM in ReadableStreamDefaultReader.prototype.read().
for (let n = 1; n < 1000; n++) {

View File

@ -1,4 +1,4 @@
// |jit-test| --no-baseline
// |jit-test| --no-baseline; --no-blinterp
// Turn off baseline and since it messes up the GC finalization assertions by
// adding spurious edges to the GC graph.

View File

@ -1,4 +1,4 @@
// |jit-test| --no-baseline
// |jit-test| --no-baseline; --no-blinterp
// Turn off baseline and since it messes up the GC finalization assertions by
// adding spurious edges to the GC graph.

View File

@ -159,7 +159,7 @@ class MOZ_RAII FallbackStubAllocator {
bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx,
JSScript* script) {
MOZ_ASSERT(cx->realm()->jitRealm());
MOZ_ASSERT(jit::IsBaselineEnabled(cx));
MOZ_ASSERT(jit::IsBaselineInterpreterOrJitEnabled(cx));
MOZ_ASSERT(numICEntries() == script->numICEntries());

View File

@ -85,7 +85,7 @@ static JitExecStatus EnterBaseline(JSContext* cx, EnterJitData& data) {
nogc.emplace(cx);
#endif
MOZ_ASSERT(jit::IsBaselineEnabled(cx));
MOZ_ASSERT(IsBaselineInterpreterOrJitEnabled(cx));
MOZ_ASSERT(CheckFrame(data.osrFrame));
EnterJitCode enter = cx->runtime()->jitRuntime()->enterJit();
@ -240,13 +240,16 @@ MethodStatus jit::BaselineCompile(JSContext* cx, JSScript* script,
static MethodStatus CanEnterBaselineJIT(JSContext* cx, HandleScript script,
AbstractFramePtr osrSourceFrame) {
MOZ_ASSERT(jit::IsBaselineEnabled(cx));
// Skip if the script has been disabled.
if (!script->canBaselineCompile()) {
return Method_Skipped;
}
if (!IsBaselineEnabled(cx)) {
script->setBaselineScript(cx->runtime(), BASELINE_DISABLED_SCRIPT);
return Method_CantCompile;
}
// This check is needed in the following corner case. Consider a function h,
//
// function h(x) {
@ -273,10 +276,12 @@ static MethodStatus CanEnterBaselineJIT(JSContext* cx, HandleScript script,
}
if (script->length() > BaselineMaxScriptLength) {
script->setBaselineScript(cx->runtime(), BASELINE_DISABLED_SCRIPT);
return Method_CantCompile;
}
if (script->nslots() > BaselineMaxScriptSlots) {
script->setBaselineScript(cx->runtime(), BASELINE_DISABLED_SCRIPT);
return Method_CantCompile;
}
@ -300,6 +305,7 @@ static MethodStatus CanEnterBaselineJIT(JSContext* cx, HandleScript script,
}
if (script->hasForceInterpreterOp()) {
script->setBaselineScript(cx->runtime(), BASELINE_DISABLED_SCRIPT);
return Method_CantCompile;
}
@ -313,7 +319,6 @@ static MethodStatus CanEnterBaselineJIT(JSContext* cx, HandleScript script,
static MethodStatus CanEnterBaselineInterpreter(JSContext* cx,
HandleScript script) {
MOZ_ASSERT(jit::IsBaselineEnabled(cx));
MOZ_ASSERT(JitOptions.baselineInterpreter);
if (script->jitScript()) {

View File

@ -535,6 +535,10 @@ inline bool IsBaselineEnabled(JSContext* cx) {
#endif
}
inline bool IsBaselineInterpreterOrJitEnabled(JSContext* cx) {
return IsBaselineEnabled(cx) || JitOptions.baselineInterpreter;
}
enum class BaselineTier { Interpreter, Compiler };
template <BaselineTier Tier>

View File

@ -25,7 +25,7 @@ static EnterJitStatus JS_HAZ_JSNATIVE_CALLER EnterJit(JSContext* cx,
MOZ_ASSERT(code);
MOZ_ASSERT(code != cx->runtime()->jitRuntime()->interpreterStub().value);
MOZ_ASSERT(IsBaselineEnabled(cx));
MOZ_ASSERT(IsBaselineInterpreterOrJitEnabled(cx));
if (!CheckRecursionLimit(cx)) {
return EnterJitStatus::Error;
@ -175,17 +175,18 @@ EnterJitStatus js::jit::MaybeEnterJit(JSContext* cx, RunState& state) {
code = script->jitCodeRaw();
break;
}
}
if (JitOptions.baselineInterpreter) {
jit::MethodStatus status =
jit::CanEnterBaselineMethod<BaselineTier::Interpreter>(cx, state);
if (status == jit::Method_Error) {
return EnterJitStatus::Error;
}
if (status == jit::Method_Compiled) {
code = script->jitCodeRaw();
break;
}
// Try to enter the Baseline Interpreter.
if (JitOptions.baselineInterpreter) {
jit::MethodStatus status =
jit::CanEnterBaselineMethod<BaselineTier::Interpreter>(cx, state);
if (status == jit::Method_Error) {
return EnterJitStatus::Error;
}
if (status == jit::Method_Compiled) {
code = script->jitCodeRaw();
break;
}
}

View File

@ -5243,6 +5243,13 @@ JS_PUBLIC_API void JS_SetGlobalJitCompilerOption(JSContext* cx,
uint32_t value) {
JSRuntime* rt = cx->runtime();
switch (opt) {
case JSJITCOMPILER_BASELINE_INTERPRETER_WARMUP_TRIGGER:
if (value == uint32_t(-1)) {
jit::DefaultJitOptions defaultValues;
value = defaultValues.baselineInterpreterWarmUpThreshold;
}
jit::JitOptions.baselineInterpreterWarmUpThreshold = value;
break;
case JSJITCOMPILER_BASELINE_WARMUP_TRIGGER:
if (value == uint32_t(-1)) {
jit::DefaultJitOptions defaultValues;
@ -5311,6 +5318,14 @@ JS_PUBLIC_API void JS_SetGlobalJitCompilerOption(JSContext* cx,
}
jit::JitOptions.frequentBailoutThreshold = value;
break;
case JSJITCOMPILER_BASELINE_INTERPRETER_ENABLE:
if (value == 1) {
jit::JitOptions.baselineInterpreter = true;
} else if (value == 0) {
ReleaseAllJITCode(rt->defaultFreeOp());
jit::JitOptions.baselineInterpreter = false;
}
break;
case JSJITCOMPILER_BASELINE_ENABLE:
if (value == 1) {
JS::ContextOptionsRef(cx).setBaseline(true);
@ -5382,6 +5397,9 @@ JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx,
#ifndef JS_CODEGEN_NONE
JSRuntime* rt = cx->runtime();
switch (opt) {
case JSJITCOMPILER_BASELINE_INTERPRETER_WARMUP_TRIGGER:
*valueOut = jit::JitOptions.baselineInterpreterWarmUpThreshold;
break;
case JSJITCOMPILER_BASELINE_WARMUP_TRIGGER:
*valueOut = jit::JitOptions.baselineWarmUpThreshold;
break;
@ -5403,6 +5421,9 @@ JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx,
case JSJITCOMPILER_ION_FREQUENT_BAILOUT_THRESHOLD:
*valueOut = jit::JitOptions.frequentBailoutThreshold;
break;
case JSJITCOMPILER_BASELINE_INTERPRETER_ENABLE:
*valueOut = jit::JitOptions.baselineInterpreter;
break;
case JSJITCOMPILER_BASELINE_ENABLE:
*valueOut = JS::ContextOptionsRef(cx).baseline();
break;

View File

@ -2852,6 +2852,7 @@ extern JS_PUBLIC_API void JS_SetOffthreadIonCompilationEnabled(JSContext* cx,
// clang-format off
#define JIT_COMPILER_OPTIONS(Register) \
Register(BASELINE_INTERPRETER_WARMUP_TRIGGER, "blinterp.warmup.trigger") \
Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
Register(ION_NORMAL_WARMUP_TRIGGER, "ion.warmup.trigger") \
Register(ION_FULL_WARMUP_TRIGGER, "ion.full.warmup.trigger") \
@ -2860,6 +2861,7 @@ extern JS_PUBLIC_API void JS_SetOffthreadIonCompilationEnabled(JSContext* cx,
Register(ION_ENABLE, "ion.enable") \
Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
Register(ION_FREQUENT_BAILOUT_THRESHOLD, "ion.frequent-bailout-threshold") \
Register(BASELINE_INTERPRETER_ENABLE, "blinterp.enable") \
Register(BASELINE_ENABLE, "baseline.enable") \
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
Register(FULL_DEBUG_CHECKS, "jit.full-debug-checks") \

View File

@ -10417,9 +10417,27 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
}
if (op.getBoolOption("baseline-eager")) {
jit::JitOptions.baselineInterpreterWarmUpThreshold = 0;
jit::JitOptions.baselineWarmUpThreshold = 0;
}
if (op.getBoolOption("blinterp")) {
jit::JitOptions.baselineInterpreter = true;
}
if (op.getBoolOption("no-blinterp")) {
jit::JitOptions.baselineInterpreter = false;
}
warmUpThreshold = op.getIntOption("blinterp-warmup-threshold");
if (warmUpThreshold >= 0) {
jit::JitOptions.baselineInterpreterWarmUpThreshold = warmUpThreshold;
}
if (op.getBoolOption("blinterp-eager")) {
jit::JitOptions.baselineInterpreterWarmUpThreshold = 0;
}
if (const char* str = op.getStringOption("ion-regalloc")) {
jit::JitOptions.forcedRegisterAllocator = jit::LookupRegisterAllocator(str);
if (!jit::JitOptions.forcedRegisterAllocator.isSome()) {
@ -11039,6 +11057,16 @@ int main(int argc, char** argv, char** envp) {
"Wait for COUNT calls or iterations before baseline-compiling "
"(default: 10)",
-1) ||
!op.addBoolOption('\0', "blinterp", "Enable Baseline Interpreter") ||
!op.addBoolOption('\0', "no-blinterp",
"Disable Baseline Interpreter (default)") ||
!op.addBoolOption('\0', "blinterp-eager",
"Always Baseline-interpret scripts") ||
!op.addIntOption(
'\0', "blinterp-warmup-threshold", "COUNT",
"Wait for COUNT calls or iterations before Baseline-interpreting "
"(default: 10)",
-1) ||
!op.addBoolOption(
'\0', "non-writable-jitcode",
"(NOP for fuzzers) Allocate JIT code as non-writable memory.") ||

View File

@ -102,6 +102,7 @@ class XULInfoTester:
# crashes when running code here. In particular, msan will
# error out if the jit is active.
'--no-baseline',
'--no-blinterp',
'-e', self.js_prologue,
'-e', 'print(!!({}))'.format(cond)
]

View File

@ -17,7 +17,7 @@ JITFLAGS = {
['--ion-eager', '--ion-offthread-compile=off',
'--ion-check-range-analysis', '--ion-extra-checks', '--no-sse3', '--no-threads'],
['--baseline-eager'],
['--no-baseline', '--no-ion', '--more-compartments'],
['--no-blinterp', '--no-baseline', '--no-ion', '--more-compartments'],
],
# used by jit_test.py
'ion': [
@ -36,14 +36,15 @@ JITFLAGS = {
'tsan': [
[],
['--ion-eager', '--ion-check-range-analysis', '--ion-extra-checks', '--no-sse3'],
['--no-baseline', '--no-ion'],
['--no-blinterp', '--no-baseline', '--no-ion'],
],
'baseline': [
['--no-ion'],
],
# Interpreter-only, for tools that cannot handle binary code generation.
'interp': [
['--no-baseline', '--no-asmjs', '--wasm-compiler=none', '--no-native-regexp']
['--no-blinterp', '--no-baseline', '--no-asmjs', '--wasm-compiler=none',
'--no-native-regexp']
],
'none': [
[] # no flags, normal baseline and ion

View File

@ -1972,7 +1972,7 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_CALLER bool Interpret(JSContext* cx,
CASE(JSOP_LOOPENTRY) {
COUNT_COVERAGE();
// Attempt on-stack replacement with Baseline code.
if (jit::IsBaselineEnabled(cx)) {
if (jit::IsBaselineInterpreterOrJitEnabled(cx)) {
script->incWarmUpCounter();
using Tier = jit::BaselineTier;