зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1682767 part 48 - Remove Ion optimization levels. r=iain
Warp doesn't use this and there's a lot of complexity to support recompiling an IonScript while continuing to use the current one. It might make sense to add a similar hot tier to Warp at some point, but because Warp uses trial inlining the implementation would likely be pretty different: we could invalidate, flag the JitScript as supporting different inlining thresholds, and go back to Baseline to gather information. Differential Revision: https://phabricator.services.mozilla.com/D101457
This commit is contained in:
Родитель
7f3824e456
Коммит
3e48042164
|
@ -33,7 +33,6 @@ var Opts_BaselineEager =
|
|||
{
|
||||
'ion.enable': 1,
|
||||
'ion.warmup.trigger': 100,
|
||||
'ion.full.warmup.trigger': 100,
|
||||
'baseline.enable': 1,
|
||||
'baseline.warmup.trigger': 0,
|
||||
'offthread-compilation.enable': 1
|
||||
|
@ -47,7 +46,6 @@ var Opts_IonEagerNoOffthreadCompilation =
|
|||
{
|
||||
'ion.enable': 1,
|
||||
'ion.warmup.trigger': 0,
|
||||
'ion.full.warmup.trigger': 0,
|
||||
'baseline.enable': 1,
|
||||
'baseline.warmup.trigger': 0,
|
||||
'offthread-compilation.enable': 0,
|
||||
|
@ -57,7 +55,6 @@ var Opts_Ion2NoOffthreadCompilation =
|
|||
{
|
||||
'ion.enable': 1,
|
||||
'ion.warmup.trigger': 3,
|
||||
'ion.full.warmup.trigger': 3,
|
||||
'baseline.enable': 1,
|
||||
'baseline.warmup.trigger': 1,
|
||||
'offthread-compilation.enable': 0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
load(libdir + "asm.js");
|
||||
|
||||
setJitCompilerOption("ion.full.warmup.trigger", 0);
|
||||
setJitCompilerOption("ion.warmup.trigger", 0);
|
||||
setJitCompilerOption("baseline.warmup.trigger", 0);
|
||||
setJitCompilerOption("offthread-compilation.enable", 0);
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
setJitCompilerOption("baseline.warmup.trigger", 9);
|
||||
setJitCompilerOption("ion.warmup.trigger", 20);
|
||||
setJitCompilerOption("ion.full.warmup.trigger", 20);
|
||||
var i;
|
||||
|
||||
var warp = true;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
setJitCompilerOption("baseline.warmup.trigger", 9);
|
||||
setJitCompilerOption("ion.warmup.trigger", 20);
|
||||
setJitCompilerOption("ion.full.warmup.trigger", 20);
|
||||
|
||||
// Prevent the GC from cancelling Ion compilations, when we expect them to succeed
|
||||
gczeal(0);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
var max = 40;
|
||||
setJitCompilerOption("ion.warmup.trigger", max - 10);
|
||||
setJitCompilerOption("ion.full.warmup.trigger", max - 10);
|
||||
|
||||
// Prevent the GC from cancelling Ion compilations, when we expect them to succeed
|
||||
gczeal(0);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "jit/CalleeToken.h"
|
||||
#include "jit/FixedList.h"
|
||||
#include "jit/IonAnalysis.h"
|
||||
#include "jit/IonOptimizationLevels.h"
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/JitRuntime.h"
|
||||
|
@ -1316,7 +1317,7 @@ bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() {
|
|||
Label done;
|
||||
|
||||
const OptimizationInfo* info =
|
||||
IonOptimizations.get(IonOptimizations.firstLevel());
|
||||
IonOptimizations.get(OptimizationLevel::Normal);
|
||||
uint32_t warmUpThreshold = info->compilerWarmUpThreshold(script, pc);
|
||||
masm.branch32(Assembler::LessThan, countReg, Imm32(warmUpThreshold), &done);
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "jit/InlineScriptTree.h"
|
||||
#include "jit/Invalidation.h"
|
||||
#include "jit/IonIC.h"
|
||||
#include "jit/IonOptimizationLevels.h"
|
||||
#include "jit/IonScript.h"
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "jit/JitFrames.h"
|
||||
|
@ -11913,22 +11912,13 @@ bool CodeGenerator::link(JSContext* cx, const WarpSnapshot* snapshot) {
|
|||
JS::AutoAssertNoGC nogc(cx);
|
||||
|
||||
RootedScript script(cx, gen->outerInfo().script());
|
||||
OptimizationLevel optimizationLevel = gen->optimizationInfo().level();
|
||||
MOZ_ASSERT(!script->hasIonScript());
|
||||
|
||||
// Perform any read barriers which were skipped while compiling the
|
||||
// script, which may have happened off-thread.
|
||||
const JitRealm* jr = gen->realm->jitRealm();
|
||||
jr->performStubReadBarriers(realmStubsToReadBarrier_);
|
||||
|
||||
// We finished the new IonScript. Invalidate the current active IonScript,
|
||||
// so we can replace it with this new (probably higher optimized) version.
|
||||
if (script->hasIonScript()) {
|
||||
MOZ_ASSERT(script->ionScript()->isRecompiling());
|
||||
// Do a normal invalidate, except don't cancel offThread compilations,
|
||||
// since that will cancel this compilation too.
|
||||
Invalidate(cx, script, /* resetUses */ false, /* cancelOffThread*/ false);
|
||||
}
|
||||
|
||||
if (scriptCounts_ && !script->hasScriptCounts() &&
|
||||
!script->initScriptCounts(cx)) {
|
||||
return false;
|
||||
|
@ -11985,7 +11975,7 @@ bool CodeGenerator::link(JSContext* cx, const WarpSnapshot* snapshot) {
|
|||
snapshots_.listSize(), snapshots_.RVATableSize(), recovers_.size(),
|
||||
bailouts_.length(), graph.numConstants(), numNurseryObjects,
|
||||
safepointIndices_.length(), osiIndices_.length(), icList_.length(),
|
||||
runtimeData_.length(), safepoints_.size(), optimizationLevel);
|
||||
runtimeData_.length(), safepoints_.size());
|
||||
if (!ionScript) {
|
||||
return false;
|
||||
}
|
||||
|
@ -14827,51 +14817,6 @@ void CodeGenerator::visitIncrementWarmUpCounter(LIncrementWarmUpCounter* ins) {
|
|||
incrementWarmUpCounter(warmUpCount, ins->mir()->script(), tmp);
|
||||
}
|
||||
|
||||
void CodeGenerator::visitRecompileCheck(LRecompileCheck* ins) {
|
||||
Label done;
|
||||
Register tmp = ToRegister(ins->scratch());
|
||||
|
||||
OutOfLineCode* ool = nullptr;
|
||||
if (ins->mir()->checkCounter()) {
|
||||
using Fn = bool (*)(JSContext*);
|
||||
if (ins->mir()->forceInvalidation()) {
|
||||
ool =
|
||||
oolCallVM<Fn, IonForcedInvalidation>(ins, ArgList(), StoreNothing());
|
||||
} else if (ins->mir()->forceRecompilation()) {
|
||||
ool = oolCallVM<Fn, IonForcedRecompile>(ins, ArgList(), StoreNothing());
|
||||
} else {
|
||||
ool = oolCallVM<Fn, IonRecompile>(ins, ArgList(), StoreNothing());
|
||||
}
|
||||
}
|
||||
|
||||
AbsoluteAddress warmUpCount =
|
||||
AbsoluteAddress(ins->mir()->script()->jitScript())
|
||||
.offset(JitScript::offsetOfWarmUpCount());
|
||||
if (ins->mir()->increaseWarmUpCounter()) {
|
||||
incrementWarmUpCounter(warmUpCount, ins->mir()->script(), tmp);
|
||||
|
||||
// Check if warm-up counter is high enough.
|
||||
if (ins->mir()->checkCounter()) {
|
||||
masm.branch32(Assembler::BelowOrEqual, warmUpCount,
|
||||
Imm32(ins->mir()->recompileThreshold()), &done);
|
||||
}
|
||||
} else {
|
||||
masm.branch32(Assembler::BelowOrEqual, warmUpCount,
|
||||
Imm32(ins->mir()->recompileThreshold()), &done);
|
||||
}
|
||||
|
||||
// Check if not yet recompiling.
|
||||
if (ins->mir()->checkCounter()) {
|
||||
CodeOffset label = masm.movWithPatch(ImmWord(uintptr_t(-1)), tmp);
|
||||
masm.propagateOOM(ionScriptLabels_.append(label));
|
||||
masm.branch32(Assembler::Equal,
|
||||
Address(tmp, IonScript::offsetOfRecompiling()), Imm32(0),
|
||||
ool->entry());
|
||||
masm.bind(ool->rejoin());
|
||||
masm.bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::visitLexicalCheck(LLexicalCheck* ins) {
|
||||
ValueOperand inputValue = ToValue(ins, LLexicalCheck::Input);
|
||||
Label bail;
|
||||
|
|
|
@ -689,13 +689,11 @@ void JitCode::finalize(JSFreeOp* fop) {
|
|||
}
|
||||
|
||||
IonScript::IonScript(IonCompilationId compilationId, uint32_t frameSlots,
|
||||
uint32_t argumentSlots, uint32_t frameSize,
|
||||
OptimizationLevel optimizationLevel)
|
||||
uint32_t argumentSlots, uint32_t frameSize)
|
||||
: frameSlots_(frameSlots),
|
||||
argumentSlots_(argumentSlots),
|
||||
frameSize_(frameSize),
|
||||
compilationId_(compilationId),
|
||||
optimizationLevel_(optimizationLevel) {}
|
||||
compilationId_(compilationId) {}
|
||||
|
||||
IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId,
|
||||
uint32_t frameSlots, uint32_t argumentSlots,
|
||||
|
@ -704,8 +702,7 @@ IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId,
|
|||
size_t bailoutEntries, size_t constants,
|
||||
size_t nurseryObjects, size_t safepointIndices,
|
||||
size_t osiIndices, size_t icEntries,
|
||||
size_t runtimeSize, size_t safepointsSize,
|
||||
OptimizationLevel optimizationLevel) {
|
||||
size_t runtimeSize, size_t safepointsSize) {
|
||||
if (snapshotsListSize >= MAX_BUFFER_SIZE ||
|
||||
(bailoutEntries >= MAX_BUFFER_SIZE / sizeof(uint32_t))) {
|
||||
ReportOutOfMemory(cx);
|
||||
|
@ -743,8 +740,8 @@ IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId,
|
|||
if (!raw) {
|
||||
return nullptr;
|
||||
}
|
||||
IonScript* script = new (raw) IonScript(
|
||||
compilationId, frameSlots, argumentSlots, frameSize, optimizationLevel);
|
||||
IonScript* script =
|
||||
new (raw) IonScript(compilationId, frameSlots, argumentSlots, frameSize);
|
||||
|
||||
Offset offsetCursor = sizeof(IonScript);
|
||||
|
||||
|
@ -1627,10 +1624,7 @@ static AbortReasonOr<WarpSnapshot*> CreateWarpSnapshot(JSContext* cx,
|
|||
}
|
||||
|
||||
static AbortReason IonCompile(JSContext* cx, HandleScript script,
|
||||
BaselineFrame* baselineFrame,
|
||||
uint32_t baselineFrameSize, jsbytecode* osrPc,
|
||||
bool recompile,
|
||||
OptimizationLevel optimizationLevel) {
|
||||
jsbytecode* osrPc) {
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
TraceLoggerEvent event(TraceLogger_AnnotateScripts, script);
|
||||
AutoTraceLog logScript(logger, event);
|
||||
|
@ -1678,7 +1672,7 @@ static AbortReason IonCompile(JSContext* cx, HandleScript script,
|
|||
}
|
||||
|
||||
const OptimizationInfo* optimizationInfo =
|
||||
IonOptimizations.get(optimizationLevel);
|
||||
IonOptimizations.get(OptimizationLevel::Normal);
|
||||
const JitCompileOptions options(cx);
|
||||
|
||||
MIRGenerator* mirGen =
|
||||
|
@ -1688,15 +1682,10 @@ static AbortReason IonCompile(JSContext* cx, HandleScript script,
|
|||
return AbortReason::Alloc;
|
||||
}
|
||||
|
||||
const bool scriptHasIonScript = script->hasIonScript();
|
||||
|
||||
MOZ_ASSERT(recompile == script->hasIonScript());
|
||||
MOZ_ASSERT(!script->baselineScript()->hasPendingIonCompileTask());
|
||||
MOZ_ASSERT(!script->hasIonScript());
|
||||
MOZ_ASSERT(script->canIonCompile());
|
||||
|
||||
if (recompile) {
|
||||
script->ionScript()->setRecompiling();
|
||||
}
|
||||
|
||||
if (osrPc) {
|
||||
script->jitScript()->setHadIonOSR();
|
||||
}
|
||||
|
@ -1714,8 +1703,7 @@ static AbortReason IonCompile(JSContext* cx, HandleScript script,
|
|||
". (Compiled on background thread.)",
|
||||
script->filename(), script->lineno(), script->column());
|
||||
|
||||
IonCompileTask* task =
|
||||
alloc->new_<IonCompileTask>(*mirGen, scriptHasIonScript, snapshot);
|
||||
IonCompileTask* task = alloc->new_<IonCompileTask>(*mirGen, snapshot);
|
||||
if (!task) {
|
||||
return AbortReason::Alloc;
|
||||
}
|
||||
|
@ -1727,9 +1715,7 @@ static AbortReason IonCompile(JSContext* cx, HandleScript script,
|
|||
return AbortReason::Alloc;
|
||||
}
|
||||
|
||||
if (!recompile) {
|
||||
script->jitScript()->setIsIonCompilingOffThread(script);
|
||||
}
|
||||
script->jitScript()->setIsIonCompilingOffThread(script);
|
||||
|
||||
// The allocator and associated data will be destroyed after being
|
||||
// processed in the finishedOffThreadCompilations list.
|
||||
|
@ -1888,25 +1874,19 @@ bool CanIonInlineScript(JSScript* script) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static OptimizationLevel GetOptimizationLevel(HandleScript script,
|
||||
jsbytecode* pc) {
|
||||
return IonOptimizations.levelForScript(script, pc);
|
||||
}
|
||||
|
||||
static MethodStatus Compile(JSContext* cx, HandleScript script,
|
||||
BaselineFrame* osrFrame, uint32_t osrFrameSize,
|
||||
jsbytecode* osrPc, bool forceRecompile = false) {
|
||||
BaselineFrame* osrFrame, jsbytecode* osrPc) {
|
||||
MOZ_ASSERT(jit::IsIonEnabled(cx));
|
||||
MOZ_ASSERT(jit::IsBaselineJitEnabled(cx));
|
||||
|
||||
MOZ_ASSERT(script->hasBaselineScript());
|
||||
MOZ_ASSERT(!script->baselineScript()->hasPendingIonCompileTask());
|
||||
MOZ_ASSERT(!script->hasIonScript());
|
||||
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Ion script compilation",
|
||||
JS::ProfilingCategoryPair::JS_IonCompilation);
|
||||
|
||||
if (!script->hasBaselineScript()) {
|
||||
return Method_Skipped;
|
||||
}
|
||||
|
||||
if (script->isDebuggee() || (osrFrame && osrFrame->isDebuggee())) {
|
||||
TrackAndSpewIonAbort(cx, script, "debugging");
|
||||
return Method_Skipped;
|
||||
|
@ -1918,48 +1898,22 @@ static MethodStatus Compile(JSContext* cx, HandleScript script,
|
|||
return Method_CantCompile;
|
||||
}
|
||||
|
||||
bool recompile = false;
|
||||
OptimizationLevel optimizationLevel = GetOptimizationLevel(script, osrPc);
|
||||
OptimizationLevel optimizationLevel =
|
||||
IonOptimizations.levelForScript(script, osrPc);
|
||||
if (optimizationLevel == OptimizationLevel::DontCompile) {
|
||||
return Method_Skipped;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(optimizationLevel == OptimizationLevel::Normal);
|
||||
|
||||
if (!CanLikelyAllocateMoreExecutableMemory()) {
|
||||
script->resetWarmUpCounterToDelayIonCompilation();
|
||||
return Method_Skipped;
|
||||
}
|
||||
|
||||
if (script->baselineScript()->hasPendingIonCompileTask()) {
|
||||
LinkIonScript(cx, script);
|
||||
}
|
||||
MOZ_ASSERT(!script->hasIonScript());
|
||||
|
||||
if (script->hasIonScript()) {
|
||||
IonScript* scriptIon = script->ionScript();
|
||||
if (!scriptIon->method()) {
|
||||
return Method_CantCompile;
|
||||
}
|
||||
|
||||
// Don't recompile/overwrite higher optimized code,
|
||||
// with a lower optimization level.
|
||||
if (optimizationLevel <= scriptIon->optimizationLevel() &&
|
||||
!forceRecompile) {
|
||||
return Method_Compiled;
|
||||
}
|
||||
|
||||
// Don't start compiling if already compiling
|
||||
if (scriptIon->isRecompiling()) {
|
||||
return Method_Compiled;
|
||||
}
|
||||
|
||||
if (osrPc) {
|
||||
scriptIon->resetOsrPcMismatchCounter();
|
||||
}
|
||||
|
||||
recompile = true;
|
||||
}
|
||||
|
||||
AbortReason reason = IonCompile(cx, script, osrFrame, osrFrameSize, osrPc,
|
||||
recompile, optimizationLevel);
|
||||
AbortReason reason = IonCompile(cx, script, osrPc);
|
||||
if (reason == AbortReason::Error) {
|
||||
MOZ_ASSERT(cx->isExceptionPending());
|
||||
return Method_Error;
|
||||
|
@ -1999,6 +1953,7 @@ MethodStatus jit::CanEnterIon(JSContext* cx, RunState& state) {
|
|||
MOZ_ASSERT(jit::IsIonEnabled(cx));
|
||||
|
||||
HandleScript script = state.script();
|
||||
MOZ_ASSERT(!script->hasIonScript());
|
||||
|
||||
// Skip if the script has been disabled.
|
||||
if (!script->canIonCompile()) {
|
||||
|
@ -2041,13 +1996,16 @@ MethodStatus jit::CanEnterIon(JSContext* cx, RunState& state) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!script->hasBaselineScript()) {
|
||||
return Method_Skipped;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!script->isIonCompilingOffThread());
|
||||
MOZ_ASSERT(script->canIonCompile());
|
||||
|
||||
// Attempt compilation. Returns Method_Compiled if already compiled.
|
||||
MethodStatus status =
|
||||
Compile(cx, script, /* osrFrame = */ nullptr, /* osrFrameSize = */ 0,
|
||||
/* osrPc = */ nullptr);
|
||||
MethodStatus status = Compile(cx, script, /* osrFrame = */ nullptr,
|
||||
/* osrPc = */ nullptr);
|
||||
if (status != Method_Compiled) {
|
||||
if (status == Method_CantCompile) {
|
||||
ForbidCompilation(cx, script);
|
||||
|
@ -2066,8 +2024,7 @@ MethodStatus jit::CanEnterIon(JSContext* cx, RunState& state) {
|
|||
}
|
||||
|
||||
static MethodStatus BaselineCanEnterAtEntry(JSContext* cx, HandleScript script,
|
||||
BaselineFrame* frame,
|
||||
uint32_t frameSize) {
|
||||
BaselineFrame* frame) {
|
||||
MOZ_ASSERT(jit::IsIonEnabled(cx));
|
||||
MOZ_ASSERT(script->canIonCompile());
|
||||
MOZ_ASSERT(!script->isIonCompilingOffThread());
|
||||
|
@ -2080,8 +2037,15 @@ static MethodStatus BaselineCanEnterAtEntry(JSContext* cx, HandleScript script,
|
|||
return Method_CantCompile;
|
||||
}
|
||||
|
||||
if (script->baselineScript()->hasPendingIonCompileTask()) {
|
||||
LinkIonScript(cx, script);
|
||||
if (script->hasIonScript()) {
|
||||
return Method_Compiled;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt compilation. Returns Method_Compiled if already compiled.
|
||||
MethodStatus status = Compile(cx, script, frame, frameSize, nullptr);
|
||||
MethodStatus status = Compile(cx, script, frame, nullptr);
|
||||
if (status != Method_Compiled) {
|
||||
if (status == Method_CantCompile) {
|
||||
ForbidCompilation(cx, script);
|
||||
|
@ -2096,7 +2060,6 @@ static MethodStatus BaselineCanEnterAtEntry(JSContext* cx, HandleScript script,
|
|||
// May compile or recompile the target JSScript.
|
||||
static MethodStatus BaselineCanEnterAtBranch(JSContext* cx, HandleScript script,
|
||||
BaselineFrame* osrFrame,
|
||||
uint32_t osrFrameSize,
|
||||
jsbytecode* pc) {
|
||||
MOZ_ASSERT(jit::IsIonEnabled(cx));
|
||||
MOZ_ASSERT((JSOp)*pc == JSOp::LoopHead);
|
||||
|
@ -2130,15 +2093,19 @@ static MethodStatus BaselineCanEnterAtBranch(JSContext* cx, HandleScript script,
|
|||
|
||||
// By default a recompilation doesn't happen on osr mismatch.
|
||||
// Decide if we want to force a recompilation if this happens too much.
|
||||
bool force = false;
|
||||
if (script->hasIonScript() && pc != script->ionScript()->osrPc()) {
|
||||
if (script->hasIonScript()) {
|
||||
if (pc == script->ionScript()->osrPc()) {
|
||||
return Method_Compiled;
|
||||
}
|
||||
|
||||
uint32_t count = script->ionScript()->incrOsrPcMismatchCounter();
|
||||
if (count <= JitOptions.osrPcMismatchesBeforeRecompile &&
|
||||
!JitOptions.eagerIonCompilation()) {
|
||||
return Method_Skipped;
|
||||
}
|
||||
|
||||
JitSpew(JitSpew_IonScripts, "Forcing OSR Mismatch Compilation");
|
||||
force = true;
|
||||
Invalidate(cx, script);
|
||||
}
|
||||
|
||||
// Attempt compilation.
|
||||
|
@ -2147,7 +2114,7 @@ static MethodStatus BaselineCanEnterAtBranch(JSContext* cx, HandleScript script,
|
|||
// - Returns Method_Skipped if pc doesn't match
|
||||
// (This means a background thread compilation with that pc could have
|
||||
// started or not.)
|
||||
MethodStatus status = Compile(cx, script, osrFrame, osrFrameSize, pc, force);
|
||||
MethodStatus status = Compile(cx, script, osrFrame, pc);
|
||||
if (status != Method_Compiled) {
|
||||
if (status == Method_CantCompile) {
|
||||
ForbidCompilation(cx, script);
|
||||
|
@ -2167,9 +2134,8 @@ static MethodStatus BaselineCanEnterAtBranch(JSContext* cx, HandleScript script,
|
|||
}
|
||||
|
||||
static bool IonCompileScriptForBaseline(JSContext* cx, BaselineFrame* frame,
|
||||
uint32_t frameSize, jsbytecode* pc) {
|
||||
jsbytecode* pc) {
|
||||
MOZ_ASSERT(IsIonEnabled(cx));
|
||||
MOZ_ASSERT(frame->debugFrameSize() == frameSize);
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
bool isLoopHead = JSOp(*pc) == JSOp::LoopHead;
|
||||
|
@ -2199,11 +2165,11 @@ static bool IonCompileScriptForBaseline(JSContext* cx, BaselineFrame* frame,
|
|||
MethodStatus stat;
|
||||
if (isLoopHead) {
|
||||
JitSpew(JitSpew_BaselineOSR, " Compile at loop head!");
|
||||
stat = BaselineCanEnterAtBranch(cx, script, frame, frameSize, pc);
|
||||
stat = BaselineCanEnterAtBranch(cx, script, frame, pc);
|
||||
} else if (frame->isFunctionFrame()) {
|
||||
JitSpew(JitSpew_BaselineOSR,
|
||||
" Compile function from top for later entry!");
|
||||
stat = BaselineCanEnterAtEntry(cx, script, frame, frameSize);
|
||||
stat = BaselineCanEnterAtEntry(cx, script, frame);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -2230,9 +2196,7 @@ static bool IonCompileScriptForBaseline(JSContext* cx, BaselineFrame* frame,
|
|||
bool jit::IonCompileScriptForBaselineAtEntry(JSContext* cx,
|
||||
BaselineFrame* frame) {
|
||||
JSScript* script = frame->script();
|
||||
uint32_t frameSize =
|
||||
BaselineFrame::frameSizeForNumValueSlots(script->nfixed());
|
||||
return IonCompileScriptForBaseline(cx, frame, frameSize, script->code());
|
||||
return IonCompileScriptForBaseline(cx, frame, script->code());
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
|
@ -2313,7 +2277,7 @@ bool jit::IonCompileScriptForBaselineOSR(JSContext* cx, BaselineFrame* frame,
|
|||
MOZ_ASSERT(frame->debugFrameSize() == frameSize);
|
||||
MOZ_ASSERT(JSOp(*pc) == JSOp::LoopHead);
|
||||
|
||||
if (!IonCompileScriptForBaseline(cx, frame, frameSize, pc)) {
|
||||
if (!IonCompileScriptForBaseline(cx, frame, pc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2328,6 +2292,8 @@ bool jit::IonCompileScriptForBaselineOSR(JSContext* cx, BaselineFrame* frame,
|
|||
ion->hasProfilingInstrumentation());
|
||||
MOZ_ASSERT(ion->osrPc() == pc);
|
||||
|
||||
ion->resetOsrPcMismatchCounter();
|
||||
|
||||
JitSpew(JitSpew_BaselineOSR, " OSR possible!");
|
||||
void* jitcode = ion->method()->raw() + ion->osrEntryOffset();
|
||||
|
||||
|
@ -2343,27 +2309,6 @@ bool jit::IonCompileScriptForBaselineOSR(JSContext* cx, BaselineFrame* frame,
|
|||
return true;
|
||||
}
|
||||
|
||||
MethodStatus jit::Recompile(JSContext* cx, HandleScript script, bool force) {
|
||||
MOZ_ASSERT(script->hasIonScript());
|
||||
if (script->ionScript()->isRecompiling()) {
|
||||
return Method_Compiled;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!script->baselineScript()->hasPendingIonCompileTask());
|
||||
|
||||
MethodStatus status = Compile(cx, script, /* osrFrame = */ nullptr,
|
||||
/* osrFrameSize = */ 0,
|
||||
/* osrPc = */ nullptr, force);
|
||||
if (status != Method_Compiled) {
|
||||
if (status == Method_CantCompile) {
|
||||
ForbidCompilation(cx, script);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
return Method_Compiled;
|
||||
}
|
||||
|
||||
static void InvalidateActivation(JSFreeOp* fop,
|
||||
const JitActivationIterator& activations,
|
||||
bool invalidateAll) {
|
||||
|
|
|
@ -63,8 +63,6 @@ struct IonOsrTempData {
|
|||
|
||||
MethodStatus CanEnterIon(JSContext* cx, RunState& state);
|
||||
|
||||
MethodStatus Recompile(JSContext* cx, HandleScript script, bool force);
|
||||
|
||||
class MIRGenerator;
|
||||
class LIRGraph;
|
||||
class CodeGenerator;
|
||||
|
|
|
@ -64,11 +64,8 @@ void IonCompileTask::trace(JSTracer* trc) {
|
|||
snapshot_->trace(trc);
|
||||
}
|
||||
|
||||
IonCompileTask::IonCompileTask(MIRGenerator& mirGen, bool scriptHasIonScript,
|
||||
WarpSnapshot* snapshot)
|
||||
: mirGen_(mirGen),
|
||||
snapshot_(snapshot),
|
||||
scriptHasIonScript_(scriptHasIonScript) {}
|
||||
IonCompileTask::IonCompileTask(MIRGenerator& mirGen, WarpSnapshot* snapshot)
|
||||
: mirGen_(mirGen), snapshot_(snapshot) {}
|
||||
|
||||
size_t IonCompileTask::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
|
||||
// See js::jit::FreeIonCompileTask.
|
||||
|
@ -190,12 +187,6 @@ void jit::FinishOffThreadTask(JSRuntime* runtime, IonCompileTask* task,
|
|||
runtime->jitRuntime()->ionLazyLinkListRemove(runtime, task);
|
||||
}
|
||||
|
||||
// Clear the recompiling flag of the old ionScript, since we continue to
|
||||
// use the old ionScript if recompiling fails.
|
||||
if (script->hasIonScript()) {
|
||||
script->ionScript()->clearRecompiling();
|
||||
}
|
||||
|
||||
// Clean up if compilation did not succeed.
|
||||
if (script->isIonCompilingOffThread()) {
|
||||
script->jitScript()->clearIsIonCompilingOffThread(script);
|
||||
|
|
|
@ -33,18 +33,12 @@ class IonCompileTask final : public HelperThreadTask,
|
|||
|
||||
WarpSnapshot* snapshot_ = nullptr;
|
||||
|
||||
// script->hasIonScript() at the start of the compilation. Used to avoid
|
||||
// calling hasIonScript() from background compilation threads.
|
||||
bool scriptHasIonScript_;
|
||||
|
||||
public:
|
||||
explicit IonCompileTask(MIRGenerator& mirGen, bool scriptHasIonScript,
|
||||
WarpSnapshot* snapshot);
|
||||
explicit IonCompileTask(MIRGenerator& mirGen, WarpSnapshot* snapshot);
|
||||
|
||||
JSScript* script() { return mirGen_.outerInfo().script(); }
|
||||
MIRGenerator& mirGen() { return mirGen_; }
|
||||
TempAllocator& alloc() { return mirGen_.alloc(); }
|
||||
bool scriptHasIonScript() const { return scriptHasIonScript_; }
|
||||
WarpSnapshot* snapshot() { return snapshot_; }
|
||||
|
||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
||||
|
|
|
@ -36,28 +36,6 @@ void OptimizationInfo::initNormalOptimizationInfo() {
|
|||
sink_ = true;
|
||||
|
||||
registerAllocator_ = RegisterAllocator_Backtracking;
|
||||
|
||||
inlineMaxBytecodePerCallSiteMainThread_ = 200;
|
||||
inlineMaxBytecodePerCallSiteHelperThread_ = 400;
|
||||
inlineMaxCalleeInlinedBytecodeLength_ = 3550;
|
||||
inlineMaxTotalBytecodeLength_ = 85000;
|
||||
inliningMaxCallerBytecodeLength_ = 1600;
|
||||
maxInlineDepth_ = 0;
|
||||
smallFunctionMaxInlineDepth_ = 1;
|
||||
inliningWarmUpThresholdFactor_ = 0.5;
|
||||
inliningRecompileThresholdFactor_ = 4;
|
||||
}
|
||||
|
||||
void OptimizationInfo::initFullOptimizationInfo() {
|
||||
initNormalOptimizationInfo();
|
||||
|
||||
level_ = OptimizationLevel::Full;
|
||||
|
||||
inlineMaxBytecodePerCallSiteMainThread_ = 550;
|
||||
inlineMaxBytecodePerCallSiteHelperThread_ = 1100;
|
||||
maxInlineDepth_ = 3;
|
||||
smallFunctionMaxInlineDepth_ = 10;
|
||||
inliningWarmUpThresholdFactor_ = 0.125;
|
||||
}
|
||||
|
||||
void OptimizationInfo::initWasmOptimizationInfo() {
|
||||
|
@ -142,58 +120,17 @@ uint32_t OptimizationInfo::recompileWarmUpThreshold(JSScript* script,
|
|||
|
||||
OptimizationLevelInfo::OptimizationLevelInfo() {
|
||||
infos_[OptimizationLevel::Normal].initNormalOptimizationInfo();
|
||||
infos_[OptimizationLevel::Full].initFullOptimizationInfo();
|
||||
infos_[OptimizationLevel::Wasm].initWasmOptimizationInfo();
|
||||
|
||||
#ifdef DEBUG
|
||||
OptimizationLevel level = firstLevel();
|
||||
while (!isLastLevel(level)) {
|
||||
OptimizationLevel next = nextLevel(level);
|
||||
MOZ_ASSERT_IF(level != OptimizationLevel::DontCompile, level < next);
|
||||
level = next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
OptimizationLevel OptimizationLevelInfo::nextLevel(
|
||||
OptimizationLevel level) const {
|
||||
MOZ_ASSERT(!isLastLevel(level));
|
||||
switch (level) {
|
||||
case OptimizationLevel::DontCompile:
|
||||
return OptimizationLevel::Normal;
|
||||
case OptimizationLevel::Normal:
|
||||
return OptimizationLevel::Full;
|
||||
case OptimizationLevel::Full:
|
||||
case OptimizationLevel::Wasm:
|
||||
case OptimizationLevel::Count:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("Unknown optimization level.");
|
||||
}
|
||||
|
||||
OptimizationLevel OptimizationLevelInfo::firstLevel() const {
|
||||
return nextLevel(OptimizationLevel::DontCompile);
|
||||
}
|
||||
|
||||
bool OptimizationLevelInfo::isLastLevel(OptimizationLevel level) const {
|
||||
return level == OptimizationLevel::Full;
|
||||
}
|
||||
|
||||
OptimizationLevel OptimizationLevelInfo::levelForScript(JSScript* script,
|
||||
jsbytecode* pc) const {
|
||||
OptimizationLevel prev = OptimizationLevel::DontCompile;
|
||||
|
||||
while (!isLastLevel(prev)) {
|
||||
OptimizationLevel level = nextLevel(prev);
|
||||
const OptimizationInfo* info = get(level);
|
||||
if (script->getWarmUpCount() < info->compilerWarmUpThreshold(script, pc)) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
prev = level;
|
||||
const OptimizationInfo* info = get(OptimizationLevel::Normal);
|
||||
if (script->getWarmUpCount() < info->compilerWarmUpThreshold(script, pc)) {
|
||||
return OptimizationLevel::DontCompile;
|
||||
}
|
||||
|
||||
return prev;
|
||||
return OptimizationLevel::Normal;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
|
|
|
@ -17,31 +17,7 @@
|
|||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
// [SMDOC] Ion Optimization Levels
|
||||
//
|
||||
// Ion can do aggressive inlining, but inlining a lot of code will have a
|
||||
// negative effect on compilation time and memory usage. It also means we spend
|
||||
// more time in the slower Baseline code while compiling the Ion code
|
||||
// off-thread or after an invalidation.
|
||||
//
|
||||
// To address this, Ion consists of two tiers:
|
||||
//
|
||||
// * Normal: the first tier (warm-up threshold of 1,000) only inlines small
|
||||
// functions one level deep. This tier also has recompile checks to
|
||||
// recompile the script when it becomes very hot.
|
||||
//
|
||||
// * Full: the second tier (warm-up threshold of 100,000) is only used for very
|
||||
// hot code so we can afford inlining a lot more code.
|
||||
//
|
||||
// See MRecompileCheck::RecompileCheckType for more info.
|
||||
|
||||
enum class OptimizationLevel : uint8_t {
|
||||
Normal,
|
||||
Full,
|
||||
Wasm,
|
||||
Count,
|
||||
DontCompile
|
||||
};
|
||||
enum class OptimizationLevel : uint8_t { Normal, Wasm, Count, DontCompile };
|
||||
|
||||
#ifdef JS_JITSPEW
|
||||
inline const char* OptimizationLevelString(OptimizationLevel level) {
|
||||
|
@ -50,8 +26,6 @@ inline const char* OptimizationLevelString(OptimizationLevel level) {
|
|||
return "Optimization_DontCompile";
|
||||
case OptimizationLevel::Normal:
|
||||
return "Optimization_Normal";
|
||||
case OptimizationLevel::Full:
|
||||
return "Optimization_Full";
|
||||
case OptimizationLevel::Wasm:
|
||||
return "Optimization_Wasm";
|
||||
case OptimizationLevel::Count:;
|
||||
|
@ -100,66 +74,15 @@ class OptimizationInfo {
|
|||
// Toggles whether sink is used.
|
||||
bool sink_;
|
||||
|
||||
// Describes which register allocator to use.
|
||||
IonRegisterAllocator registerAllocator_;
|
||||
|
||||
// The maximum total bytecode size of an inline call site. We use a lower
|
||||
// value if off-thread compilation is not available, to avoid stalling the
|
||||
// main thread.
|
||||
uint32_t inlineMaxBytecodePerCallSiteHelperThread_;
|
||||
uint32_t inlineMaxBytecodePerCallSiteMainThread_;
|
||||
|
||||
// The maximum value we allow for baselineScript->inlinedBytecodeLength_
|
||||
// when inlining.
|
||||
uint16_t inlineMaxCalleeInlinedBytecodeLength_;
|
||||
|
||||
// The maximum bytecode length we'll inline in a single compilation.
|
||||
uint32_t inlineMaxTotalBytecodeLength_;
|
||||
|
||||
// The maximum bytecode length the caller may have,
|
||||
// before we stop inlining large functions in that caller.
|
||||
uint32_t inliningMaxCallerBytecodeLength_;
|
||||
|
||||
// The maximum inlining depth.
|
||||
uint32_t maxInlineDepth_;
|
||||
|
||||
// Toggles whether scalar replacement is used.
|
||||
bool scalarReplacement_;
|
||||
|
||||
// The maximum inlining depth for functions.
|
||||
//
|
||||
// Inlining small functions has almost no compiling overhead
|
||||
// and removes the otherwise needed call overhead.
|
||||
// The value is currently very low.
|
||||
// Actually it is only needed to make sure we don't blow out the stack.
|
||||
uint32_t smallFunctionMaxInlineDepth_;
|
||||
|
||||
// How many invocations or loop iterations are needed before calls
|
||||
// are inlined, as a fraction of compilerWarmUpThreshold.
|
||||
double inliningWarmUpThresholdFactor_;
|
||||
|
||||
// How many invocations or loop iterations are needed before a function
|
||||
// is hot enough to recompile the outerScript to inline that function,
|
||||
// as a multiplication of inliningWarmUpThreshold.
|
||||
uint32_t inliningRecompileThresholdFactor_;
|
||||
// Describes which register allocator to use.
|
||||
IonRegisterAllocator registerAllocator_;
|
||||
|
||||
uint32_t baseCompilerWarmUpThreshold() const {
|
||||
switch (level_) {
|
||||
case OptimizationLevel::Normal:
|
||||
return JitOptions.normalIonWarmUpThreshold;
|
||||
case OptimizationLevel::Full:
|
||||
if (!JitOptions.disableOptimizationLevels) {
|
||||
return JitOptions.fullIonWarmUpThreshold;
|
||||
}
|
||||
// Use the 'normal' threshold so Ion uses a single optimization level,
|
||||
// OptimizationLevel::Full.
|
||||
return JitOptions.normalIonWarmUpThreshold;
|
||||
case OptimizationLevel::DontCompile:
|
||||
case OptimizationLevel::Wasm:
|
||||
case OptimizationLevel::Count:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("Unexpected optimization level");
|
||||
MOZ_ASSERT(level_ == OptimizationLevel::Normal);
|
||||
return JitOptions.normalIonWarmUpThreshold;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -177,20 +100,10 @@ class OptimizationInfo {
|
|||
reordering_(false),
|
||||
autoTruncate_(false),
|
||||
sink_(false),
|
||||
registerAllocator_(RegisterAllocator_Backtracking),
|
||||
inlineMaxBytecodePerCallSiteHelperThread_(0),
|
||||
inlineMaxBytecodePerCallSiteMainThread_(0),
|
||||
inlineMaxCalleeInlinedBytecodeLength_(0),
|
||||
inlineMaxTotalBytecodeLength_(0),
|
||||
inliningMaxCallerBytecodeLength_(0),
|
||||
maxInlineDepth_(0),
|
||||
scalarReplacement_(false),
|
||||
smallFunctionMaxInlineDepth_(0),
|
||||
inliningWarmUpThresholdFactor_(0.0),
|
||||
inliningRecompileThresholdFactor_(0) {}
|
||||
registerAllocator_(RegisterAllocator_Backtracking) {}
|
||||
|
||||
void initNormalOptimizationInfo();
|
||||
void initFullOptimizationInfo();
|
||||
void initWasmOptimizationInfo();
|
||||
|
||||
OptimizationLevel level() const { return level_; }
|
||||
|
@ -245,38 +158,6 @@ class OptimizationInfo {
|
|||
bool scalarReplacementEnabled() const {
|
||||
return scalarReplacement_ && !JitOptions.disableScalarReplacement;
|
||||
}
|
||||
|
||||
uint32_t smallFunctionMaxInlineDepth() const {
|
||||
return smallFunctionMaxInlineDepth_;
|
||||
}
|
||||
|
||||
uint32_t maxInlineDepth() const { return maxInlineDepth_; }
|
||||
|
||||
uint32_t inlineMaxBytecodePerCallSite(bool offThread) const {
|
||||
return (offThread || !JitOptions.limitScriptSize)
|
||||
? inlineMaxBytecodePerCallSiteHelperThread_
|
||||
: inlineMaxBytecodePerCallSiteMainThread_;
|
||||
}
|
||||
|
||||
uint16_t inlineMaxCalleeInlinedBytecodeLength() const {
|
||||
return inlineMaxCalleeInlinedBytecodeLength_;
|
||||
}
|
||||
|
||||
uint32_t inlineMaxTotalBytecodeLength() const {
|
||||
return inlineMaxTotalBytecodeLength_;
|
||||
}
|
||||
|
||||
uint32_t inliningMaxCallerBytecodeLength() const {
|
||||
return inliningMaxCallerBytecodeLength_;
|
||||
}
|
||||
|
||||
uint32_t inliningWarmUpThreshold() const {
|
||||
return baseCompilerWarmUpThreshold() * inliningWarmUpThresholdFactor_;
|
||||
}
|
||||
|
||||
uint32_t inliningRecompileThreshold() const {
|
||||
return inliningWarmUpThreshold() * inliningRecompileThresholdFactor_;
|
||||
}
|
||||
};
|
||||
|
||||
class OptimizationLevelInfo {
|
||||
|
@ -292,9 +173,6 @@ class OptimizationLevelInfo {
|
|||
return &infos_[level];
|
||||
}
|
||||
|
||||
OptimizationLevel nextLevel(OptimizationLevel level) const;
|
||||
OptimizationLevel firstLevel() const;
|
||||
bool isLastLevel(OptimizationLevel level) const;
|
||||
OptimizationLevel levelForScript(JSScript* script,
|
||||
jsbytecode* pc = nullptr) const;
|
||||
};
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "gc/Barrier.h" // HeapPtr{JitCode,Object}, PreBarrieredValue
|
||||
#include "jit/IonOptimizationLevels.h" // OptimizationLevel
|
||||
#include "jit/IonTypes.h" // IonCompilationId
|
||||
#include "jit/JitCode.h" // JitCode
|
||||
#include "js/TypeDecls.h" // jsbytecode
|
||||
#include "util/TrailingArray.h" // TrailingArray
|
||||
#include "vm/TraceLogging.h" // TraceLoggerEvent
|
||||
#include "gc/Barrier.h" // HeapPtr{JitCode,Object}, PreBarrieredValue
|
||||
#include "jit/IonTypes.h" // IonCompilationId
|
||||
#include "jit/JitCode.h" // JitCode
|
||||
#include "jit/JitOptions.h" // JitOptions
|
||||
#include "js/TypeDecls.h" // jsbytecode
|
||||
#include "util/TrailingArray.h" // TrailingArray
|
||||
#include "vm/TraceLogging.h" // TraceLoggerEvent
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
@ -111,9 +111,6 @@ class alignas(8) IonScript final : public TrailingArray {
|
|||
// Flag set if IonScript was compiled with profiling enabled.
|
||||
bool hasProfilingInstrumentation_ = false;
|
||||
|
||||
// Flag for if this script is getting recompiled.
|
||||
uint32_t recompiling_ = 0;
|
||||
|
||||
// Number of bytes this function reserves on the stack.
|
||||
uint32_t frameSlots_ = 0;
|
||||
|
||||
|
@ -130,9 +127,6 @@ class alignas(8) IonScript final : public TrailingArray {
|
|||
// Identifier of the compilation which produced this code.
|
||||
IonCompilationId compilationId_;
|
||||
|
||||
// The optimization level this script was compiled in.
|
||||
OptimizationLevel optimizationLevel_;
|
||||
|
||||
// Number of times we tried to enter this script via OSR but failed due to
|
||||
// a LOOPENTRY pc other than osrPc_.
|
||||
uint32_t osrPcMismatchCounter_ = 0;
|
||||
|
@ -286,8 +280,7 @@ class alignas(8) IonScript final : public TrailingArray {
|
|||
|
||||
private:
|
||||
IonScript(IonCompilationId compilationId, uint32_t frameSlots,
|
||||
uint32_t argumentSlots, uint32_t frameSize,
|
||||
OptimizationLevel optimizationLevel);
|
||||
uint32_t argumentSlots, uint32_t frameSize);
|
||||
|
||||
public:
|
||||
static IonScript* New(JSContext* cx, IonCompilationId compilationId,
|
||||
|
@ -297,8 +290,7 @@ class alignas(8) IonScript final : public TrailingArray {
|
|||
size_t bailoutEntries, size_t constants,
|
||||
size_t nurseryObjects, size_t safepointIndices,
|
||||
size_t osiIndices, size_t icEntries, size_t runtimeSize,
|
||||
size_t safepointsSize,
|
||||
OptimizationLevel optimizationLevel);
|
||||
size_t safepointsSize);
|
||||
|
||||
static void Destroy(JSFreeOp* fop, IonScript* script);
|
||||
|
||||
|
@ -307,9 +299,6 @@ class alignas(8) IonScript final : public TrailingArray {
|
|||
static inline size_t offsetOfInvalidationCount() {
|
||||
return offsetof(IonScript, invalidationCount_);
|
||||
}
|
||||
static inline size_t offsetOfRecompiling() {
|
||||
return offsetof(IonScript, recompiling_);
|
||||
}
|
||||
|
||||
public:
|
||||
JitCode* method() const { return method_; }
|
||||
|
@ -442,16 +431,9 @@ class alignas(8) IonScript final : public TrailingArray {
|
|||
}
|
||||
}
|
||||
IonCompilationId compilationId() const { return compilationId_; }
|
||||
OptimizationLevel optimizationLevel() const { return optimizationLevel_; }
|
||||
uint32_t incrOsrPcMismatchCounter() { return ++osrPcMismatchCounter_; }
|
||||
void resetOsrPcMismatchCounter() { osrPcMismatchCounter_ = 0; }
|
||||
|
||||
void setRecompiling() { recompiling_ = true; }
|
||||
|
||||
bool isRecompiling() const { return recompiling_; }
|
||||
|
||||
void clearRecompiling() { recompiling_ = false; }
|
||||
|
||||
size_t allocBytes() const { return allocBytes_; }
|
||||
|
||||
static void preWriteBarrier(Zone* zone, IonScript* ionScript);
|
||||
|
|
|
@ -114,10 +114,6 @@ DefaultJitOptions::DefaultJitOptions() {
|
|||
// Toggles whether sink code motion is globally disabled.
|
||||
SET_DEFAULT(disableSink, true);
|
||||
|
||||
// Toggles whether the use of multiple Ion optimization levels is globally
|
||||
// disabled.
|
||||
SET_DEFAULT(disableOptimizationLevels, true);
|
||||
|
||||
// Whether the Baseline Interpreter is enabled.
|
||||
SET_DEFAULT(baselineInterpreter, true);
|
||||
|
||||
|
@ -181,11 +177,6 @@ DefaultJitOptions::DefaultJitOptions() {
|
|||
// Duplicated in all.js - ensure both match.
|
||||
SET_DEFAULT(normalIonWarmUpThreshold, 1500);
|
||||
|
||||
// How many invocations or loop iterations are needed before functions
|
||||
// are compiled with the Ion compiler at OptimizationLevel::Full.
|
||||
// Duplicated in all.js - ensure both match.
|
||||
SET_DEFAULT(fullIonWarmUpThreshold, 100'000);
|
||||
|
||||
// How many invocations are needed before regexps are compiled to
|
||||
// native code.
|
||||
SET_DEFAULT(regexpWarmUpThreshold, 10);
|
||||
|
@ -330,7 +321,6 @@ void DefaultJitOptions::setEagerBaselineCompilation() {
|
|||
void DefaultJitOptions::setEagerIonCompilation() {
|
||||
setEagerBaselineCompilation();
|
||||
normalIonWarmUpThreshold = 0;
|
||||
fullIonWarmUpThreshold = 0;
|
||||
}
|
||||
|
||||
void DefaultJitOptions::setFastWarmUp() {
|
||||
|
@ -339,7 +329,6 @@ void DefaultJitOptions::setFastWarmUp() {
|
|||
trialInliningWarmUpThreshold = 14;
|
||||
trialInliningInitialWarmUpCount = 12;
|
||||
normalIonWarmUpThreshold = 30;
|
||||
fullIonWarmUpThreshold = 65;
|
||||
|
||||
inliningEntryThreshold = 2;
|
||||
smallFunctionMaxBytecodeLength = 2000;
|
||||
|
@ -347,18 +336,6 @@ void DefaultJitOptions::setFastWarmUp() {
|
|||
|
||||
void DefaultJitOptions::setNormalIonWarmUpThreshold(uint32_t warmUpThreshold) {
|
||||
normalIonWarmUpThreshold = warmUpThreshold;
|
||||
|
||||
if (fullIonWarmUpThreshold < normalIonWarmUpThreshold) {
|
||||
fullIonWarmUpThreshold = normalIonWarmUpThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultJitOptions::setFullIonWarmUpThreshold(uint32_t warmUpThreshold) {
|
||||
fullIonWarmUpThreshold = warmUpThreshold;
|
||||
|
||||
if (normalIonWarmUpThreshold > fullIonWarmUpThreshold) {
|
||||
setNormalIonWarmUpThreshold(fullIonWarmUpThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultJitOptions::resetNormalIonWarmUpThreshold() {
|
||||
|
@ -366,10 +343,5 @@ void DefaultJitOptions::resetNormalIonWarmUpThreshold() {
|
|||
setNormalIonWarmUpThreshold(defaultValues.normalIonWarmUpThreshold);
|
||||
}
|
||||
|
||||
void DefaultJitOptions::resetFullIonWarmUpThreshold() {
|
||||
jit::DefaultJitOptions defaultValues;
|
||||
setFullIonWarmUpThreshold(defaultValues.fullIonWarmUpThreshold);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
|
|
@ -52,7 +52,6 @@ struct DefaultJitOptions {
|
|||
bool disableScalarReplacement;
|
||||
bool disableCacheIR;
|
||||
bool disableSink;
|
||||
bool disableOptimizationLevels;
|
||||
bool baselineInterpreter;
|
||||
bool baselineJit;
|
||||
bool ion;
|
||||
|
@ -85,7 +84,6 @@ struct DefaultJitOptions {
|
|||
uint32_t trialInliningWarmUpThreshold;
|
||||
uint32_t trialInliningInitialWarmUpCount;
|
||||
uint32_t normalIonWarmUpThreshold;
|
||||
uint32_t fullIonWarmUpThreshold;
|
||||
uint32_t regexpWarmUpThreshold;
|
||||
uint32_t exceptionBailoutThreshold;
|
||||
uint32_t frequentBailoutThreshold;
|
||||
|
@ -126,9 +124,7 @@ struct DefaultJitOptions {
|
|||
void setEagerBaselineCompilation();
|
||||
void setEagerIonCompilation();
|
||||
void setNormalIonWarmUpThreshold(uint32_t warmUpThreshold);
|
||||
void setFullIonWarmUpThreshold(uint32_t warmUpThreshold);
|
||||
void resetNormalIonWarmUpThreshold();
|
||||
void resetFullIonWarmUpThreshold();
|
||||
void enableGvn(bool val);
|
||||
void setFastWarmUp();
|
||||
|
||||
|
|
|
@ -5288,12 +5288,6 @@ void LIRGenerator::visitIncrementWarmUpCounter(MIncrementWarmUpCounter* ins) {
|
|||
add(lir, ins);
|
||||
}
|
||||
|
||||
void LIRGenerator::visitRecompileCheck(MRecompileCheck* ins) {
|
||||
LRecompileCheck* lir = new (alloc()) LRecompileCheck(temp());
|
||||
add(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
void LIRGenerator::visitLexicalCheck(MLexicalCheck* ins) {
|
||||
MDefinition* input = ins->input();
|
||||
MOZ_ASSERT(input->type() == MIRType::Value);
|
||||
|
|
|
@ -11958,79 +11958,6 @@ class MIncrementWarmUpCounter : public MNullaryInstruction {
|
|||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
||||
};
|
||||
|
||||
// Increase the warm-up counter of the provided script upon execution and test
|
||||
// if the warm-up counter surpasses the threshold. Upon hit it will recompile
|
||||
// the outermost script (i.e. not the inlined script).
|
||||
class MRecompileCheck : public MNullaryInstruction {
|
||||
public:
|
||||
enum class RecompileCheckType : uint8_t {
|
||||
// If we're not at the highest optimization level, keep incrementing the
|
||||
// warm-up counter for the outermost script on entry. The warmup check will
|
||||
// trigger recompilation to tier up. The lazy link mechanism will be used to
|
||||
// tier up once recompilation is done.
|
||||
OptimizationLevel,
|
||||
|
||||
// If we're not at the highest optimization level, keep incrementing the
|
||||
// warm-up counter at loop edges. This check will trigger invalidation for
|
||||
// very long-running loops to ensure we still tier up even if we don't
|
||||
// invoke the lazy link stub.
|
||||
OptimizationLevelOSR,
|
||||
|
||||
// If we're not at the highest optimization level, keep incrementing the
|
||||
// warm-up counter for inlined scripts. This check does not trigger any
|
||||
// recompilation or invalidation, it exists to ensure inlined scripts have
|
||||
// an accurate warm-up count.
|
||||
OptimizationLevelInlined,
|
||||
|
||||
// Used at the last optimization level for callees that weren't hot enough
|
||||
// to be inlined. If a callee becomes hot enough we force recompilation of
|
||||
// the caller's Ion script.
|
||||
Inlining
|
||||
};
|
||||
|
||||
private:
|
||||
JSScript* script_;
|
||||
uint32_t recompileThreshold_;
|
||||
RecompileCheckType type_;
|
||||
|
||||
MRecompileCheck(JSScript* script, uint32_t recompileThreshold,
|
||||
RecompileCheckType type)
|
||||
: MNullaryInstruction(classOpcode),
|
||||
script_(script),
|
||||
recompileThreshold_(recompileThreshold),
|
||||
type_(type) {
|
||||
setGuard();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(RecompileCheck)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
|
||||
JSScript* script() const { return script_; }
|
||||
|
||||
uint32_t recompileThreshold() const { return recompileThreshold_; }
|
||||
|
||||
bool forceInvalidation() const {
|
||||
return type_ == RecompileCheckType::OptimizationLevelOSR;
|
||||
}
|
||||
|
||||
bool forceRecompilation() const {
|
||||
return type_ == RecompileCheckType::Inlining;
|
||||
}
|
||||
|
||||
bool checkCounter() const {
|
||||
return type_ != RecompileCheckType::OptimizationLevelInlined;
|
||||
}
|
||||
|
||||
bool increaseWarmUpCounter() const {
|
||||
return (type_ == RecompileCheckType::OptimizationLevel ||
|
||||
type_ == RecompileCheckType::OptimizationLevelInlined ||
|
||||
type_ == RecompileCheckType::OptimizationLevelOSR);
|
||||
}
|
||||
|
||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
||||
};
|
||||
|
||||
class MAtomicIsLockFree : public MUnaryInstruction,
|
||||
public ConvertToInt32Policy<0>::Data {
|
||||
explicit MAtomicIsLockFree(MDefinition* value)
|
||||
|
|
|
@ -153,8 +153,6 @@ namespace jit {
|
|||
_(IonCompileScriptForBaselineAtEntry, \
|
||||
js::jit::IonCompileScriptForBaselineAtEntry) \
|
||||
_(IonCompileScriptForBaselineOSR, js::jit::IonCompileScriptForBaselineOSR) \
|
||||
_(IonForcedInvalidation, js::jit::IonForcedInvalidation) \
|
||||
_(IonForcedRecompile, js::jit::IonForcedRecompile) \
|
||||
_(IonGetIteratorICUpdate, js::jit::IonGetIteratorIC::update) \
|
||||
_(IonGetNameICUpdate, js::jit::IonGetNameIC::update) \
|
||||
_(IonGetPropSuperICUpdate, js::jit::IonGetPropSuperIC::update) \
|
||||
|
@ -163,7 +161,6 @@ namespace jit {
|
|||
_(IonInICUpdate, js::jit::IonInIC::update) \
|
||||
_(IonInstanceOfICUpdate, js::jit::IonInstanceOfIC::update) \
|
||||
_(IonOptimizeSpreadCallICUpdate, js::jit::IonOptimizeSpreadCallIC::update) \
|
||||
_(IonRecompile, js::jit::IonRecompile) \
|
||||
_(IonSetPropertyICUpdate, js::jit::IonSetPropertyIC::update) \
|
||||
_(IonToPropertyKeyICUpdate, js::jit::IonToPropertyKeyIC::update) \
|
||||
_(IonUnaryArithICUpdate, js::jit::IonUnaryArithIC::update) \
|
||||
|
|
|
@ -1609,58 +1609,6 @@ JSString* StringReplace(JSContext* cx, HandleString string,
|
|||
return str_replace_string_raw(cx, string, pattern, repl);
|
||||
}
|
||||
|
||||
bool RecompileImpl(JSContext* cx, bool force) {
|
||||
MOZ_ASSERT(cx->currentlyRunningInJit());
|
||||
JitActivationIterator activations(cx);
|
||||
JSJitFrameIter frame(activations->asJit());
|
||||
|
||||
MOZ_ASSERT(frame.type() == FrameType::Exit);
|
||||
++frame;
|
||||
|
||||
RootedScript script(cx, frame.script());
|
||||
MOZ_ASSERT(script->hasIonScript());
|
||||
|
||||
if (!IsIonEnabled(cx)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MethodStatus status = Recompile(cx, script, force);
|
||||
if (status == Method_Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IonForcedRecompile(JSContext* cx) {
|
||||
return RecompileImpl(cx, /* force = */ true);
|
||||
}
|
||||
|
||||
bool IonRecompile(JSContext* cx) {
|
||||
return RecompileImpl(cx, /* force = */ false);
|
||||
}
|
||||
|
||||
bool IonForcedInvalidation(JSContext* cx) {
|
||||
MOZ_ASSERT(cx->currentlyRunningInJit());
|
||||
JitActivationIterator activations(cx);
|
||||
JSJitFrameIter frame(activations->asJit());
|
||||
|
||||
MOZ_ASSERT(frame.type() == FrameType::Exit);
|
||||
++frame;
|
||||
|
||||
RootedScript script(cx, frame.script());
|
||||
MOZ_ASSERT(script->hasIonScript());
|
||||
|
||||
if (script->baselineScript()->hasPendingIonCompileTask()) {
|
||||
LinkIonScript(cx, script);
|
||||
return true;
|
||||
}
|
||||
|
||||
Invalidate(cx, script, /* resetUses = */ false,
|
||||
/* cancelOffThread = */ false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetDenseElement(JSContext* cx, HandleNativeObject obj, int32_t index,
|
||||
HandleValue value, bool strict) {
|
||||
// This function is called from Ion code for StoreElementHole's OOL path.
|
||||
|
|
|
@ -509,10 +509,6 @@ JSObject* InitRestParameter(JSContext* cx, uint32_t length, Value* rest,
|
|||
InterpreterFrame* interpFrame,
|
||||
uint32_t numStackValues);
|
||||
|
||||
[[nodiscard]] bool IonRecompile(JSContext* cx);
|
||||
[[nodiscard]] bool IonForcedRecompile(JSContext* cx);
|
||||
[[nodiscard]] bool IonForcedInvalidation(JSContext* cx);
|
||||
|
||||
JSString* StringReplace(JSContext* cx, HandleString string,
|
||||
HandleString pattern, HandleString repl);
|
||||
|
||||
|
|
|
@ -128,12 +128,10 @@ AbortReasonOr<WarpSnapshot*> WarpOracle::createSnapshot() {
|
|||
mode = "Compiling";
|
||||
}
|
||||
JitSpew(JitSpew_IonScripts,
|
||||
"Warp %s script %s:%u:%u (%p) (warmup-counter=%" PRIu32
|
||||
", level=%s%s%s)",
|
||||
"Warp %s script %s:%u:%u (%p) (warmup-counter=%" PRIu32 ",%s%s)",
|
||||
mode, outerScript_->filename(), outerScript_->lineno(),
|
||||
outerScript_->column(), static_cast<JSScript*>(outerScript_),
|
||||
outerScript_->getWarmUpCount(),
|
||||
OptimizationLevelString(mirGen_.optimizationInfo().level()),
|
||||
outerScript_->isGenerator() ? " isGenerator" : "",
|
||||
outerScript_->isAsync() ? " isAsync" : "");
|
||||
#endif
|
||||
|
|
|
@ -8092,19 +8092,6 @@ class LIncrementWarmUpCounter : public LInstructionHelper<0, 0, 1> {
|
|||
MIncrementWarmUpCounter* mir() { return mir_->toIncrementWarmUpCounter(); }
|
||||
};
|
||||
|
||||
class LRecompileCheck : public LInstructionHelper<0, 0, 1> {
|
||||
public:
|
||||
LIR_HEADER(RecompileCheck)
|
||||
|
||||
explicit LRecompileCheck(const LDefinition& scratch)
|
||||
: LInstructionHelper(classOpcode) {
|
||||
setTemp(0, scratch);
|
||||
}
|
||||
|
||||
const LDefinition* scratch() { return getTemp(0); }
|
||||
MRecompileCheck* mir() { return mir_->toRecompileCheck(); }
|
||||
};
|
||||
|
||||
class LLexicalCheck : public LInstructionHelper<0, BOX_PIECES, 0> {
|
||||
public:
|
||||
LIR_HEADER(LexicalCheck)
|
||||
|
|
|
@ -5217,13 +5217,6 @@ JS_PUBLIC_API void JS_SetGlobalJitCompilerOption(JSContext* cx,
|
|||
}
|
||||
jit::JitOptions.setNormalIonWarmUpThreshold(value);
|
||||
break;
|
||||
case JSJITCOMPILER_ION_FULL_WARMUP_TRIGGER:
|
||||
if (value == uint32_t(-1)) {
|
||||
jit::JitOptions.resetFullIonWarmUpThreshold();
|
||||
break;
|
||||
}
|
||||
jit::JitOptions.setFullIonWarmUpThreshold(value);
|
||||
break;
|
||||
case JSJITCOMPILER_ION_GVN_ENABLE:
|
||||
if (value == 0) {
|
||||
jit::JitOptions.enableGvn(false);
|
||||
|
@ -5382,9 +5375,6 @@ JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx,
|
|||
case JSJITCOMPILER_ION_NORMAL_WARMUP_TRIGGER:
|
||||
*valueOut = jit::JitOptions.normalIonWarmUpThreshold;
|
||||
break;
|
||||
case JSJITCOMPILER_ION_FULL_WARMUP_TRIGGER:
|
||||
*valueOut = jit::JitOptions.fullIonWarmUpThreshold;
|
||||
break;
|
||||
case JSJITCOMPILER_ION_FORCE_IC:
|
||||
*valueOut = jit::JitOptions.forceInlineCaches;
|
||||
break;
|
||||
|
|
|
@ -2632,7 +2632,6 @@ extern JS_PUBLIC_API void JS_SetOffthreadIonCompilationEnabled(JSContext* cx,
|
|||
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") \
|
||||
Register(ION_GVN_ENABLE, "ion.gvn.enable") \
|
||||
Register(ION_FORCE_IC, "ion.forceinlineCaches") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
|
|
|
@ -37,14 +37,6 @@
|
|||
--ion-warmup-threshold=0
|
||||
--ion-warmup-threshold=10
|
||||
--ion-warmup-threshold=100
|
||||
--ion-full-warmup-threshold=0
|
||||
--ion-full-warmup-threshold=10
|
||||
--ion-full-warmup-threshold=100
|
||||
--ion-full-warmup-threshold=1000
|
||||
--ion-full-warmup-threshold=1500
|
||||
--ion-full-warmup-threshold=5000
|
||||
--ion-optimization-levels=off
|
||||
--ion-optimization-levels=on
|
||||
--no-native-regexp
|
||||
--nursery-strings=off
|
||||
--nursery-strings=on
|
||||
|
|
|
@ -10643,16 +10643,6 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
|
|||
}
|
||||
}
|
||||
|
||||
if (const char* str = op.getStringOption("ion-optimization-levels")) {
|
||||
if (strcmp(str, "on") == 0) {
|
||||
jit::JitOptions.disableOptimizationLevels = false;
|
||||
} else if (strcmp(str, "off") == 0) {
|
||||
jit::JitOptions.disableOptimizationLevels = true;
|
||||
} else {
|
||||
return OptionFailure("ion-optimization-levels", str);
|
||||
}
|
||||
}
|
||||
|
||||
if (const char* str = op.getStringOption("ion-instruction-reordering")) {
|
||||
if (strcmp(str, "on") == 0) {
|
||||
jit::JitOptions.disableInstructionReordering = false;
|
||||
|
@ -10706,11 +10696,6 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
|
|||
jit::JitOptions.setNormalIonWarmUpThreshold(warmUpThreshold);
|
||||
}
|
||||
|
||||
warmUpThreshold = op.getIntOption("ion-full-warmup-threshold");
|
||||
if (warmUpThreshold >= 0) {
|
||||
jit::JitOptions.setFullIonWarmUpThreshold(warmUpThreshold);
|
||||
}
|
||||
|
||||
warmUpThreshold = op.getIntOption("baseline-warmup-threshold");
|
||||
if (warmUpThreshold >= 0) {
|
||||
jit::JitOptions.baselineJitWarmUpThreshold = warmUpThreshold;
|
||||
|
@ -11528,8 +11513,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
!op.addStringOption('\0', "ion-sink", "on/off",
|
||||
"Sink code motion (default: off, on to enable)") ||
|
||||
!op.addStringOption('\0', "ion-optimization-levels", "on/off",
|
||||
"Use multiple Ion optimization levels (default: on, "
|
||||
"off to disable)") ||
|
||||
"No-op for fuzzing") ||
|
||||
!op.addStringOption('\0', "ion-loop-unrolling", "on/off",
|
||||
"(NOP for fuzzers)") ||
|
||||
!op.addStringOption(
|
||||
|
@ -11553,9 +11537,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
"at the normal optimization level (default: 1000)",
|
||||
-1) ||
|
||||
!op.addIntOption('\0', "ion-full-warmup-threshold", "COUNT",
|
||||
"Wait for COUNT calls or iterations before compiling "
|
||||
"at the 'full' optimization level (default: 100,000)",
|
||||
-1) ||
|
||||
"No-op for fuzzing", -1) ||
|
||||
!op.addStringOption(
|
||||
'\0', "ion-regalloc", "[mode]",
|
||||
"Specify Ion register allocation:\n"
|
||||
|
|
|
@ -1776,20 +1776,6 @@ static bool IonCompileTaskHasHigherPriority(jit::IonCompileTask* first,
|
|||
// This method can return whatever it wants, though it really ought to be a
|
||||
// total order. The ordering is allowed to race (change on the fly), however.
|
||||
|
||||
// A lower optimization level indicates a higher priority.
|
||||
jit::OptimizationLevel firstLevel =
|
||||
first->mirGen().optimizationInfo().level();
|
||||
jit::OptimizationLevel secondLevel =
|
||||
second->mirGen().optimizationInfo().level();
|
||||
if (firstLevel != secondLevel) {
|
||||
return firstLevel < secondLevel;
|
||||
}
|
||||
|
||||
// A script without an IonScript has precedence on one with.
|
||||
if (first->scriptHasIonScript() != second->scriptHasIonScript()) {
|
||||
return !first->scriptHasIonScript();
|
||||
}
|
||||
|
||||
// A higher warm-up counter indicates a higher priority.
|
||||
jit::JitScript* firstJitScript = first->script()->jitScript();
|
||||
jit::JitScript* secondJitScript = second->script()->jitScript();
|
||||
|
|
|
@ -859,8 +859,6 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
|
|||
Preferences::GetInt(JS_OPTIONS_DOT_STR "baselinejit.threshold", -1);
|
||||
int32_t normalIonThreshold =
|
||||
Preferences::GetInt(JS_OPTIONS_DOT_STR "ion.threshold", -1);
|
||||
int32_t fullIonThreshold =
|
||||
Preferences::GetInt(JS_OPTIONS_DOT_STR "ion.full.threshold", -1);
|
||||
int32_t ionFrequentBailoutThreshold = Preferences::GetInt(
|
||||
JS_OPTIONS_DOT_STR "ion.frequent_bailout_threshold", -1);
|
||||
|
||||
|
@ -914,8 +912,6 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
|
|||
useBaselineEager ? 0 : baselineThreshold);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_NORMAL_WARMUP_TRIGGER,
|
||||
useIonEager ? 0 : normalIonThreshold);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_FULL_WARMUP_TRIGGER,
|
||||
useIonEager ? 0 : fullIonThreshold);
|
||||
JS_SetGlobalJitCompilerOption(cx,
|
||||
JSJITCOMPILER_ION_FREQUENT_BAILOUT_THRESHOLD,
|
||||
ionFrequentBailoutThreshold);
|
||||
|
|
|
@ -1090,7 +1090,6 @@ pref("javascript.options.baselinejit.threshold", 100);
|
|||
pref("javascript.options.ion", true);
|
||||
// Duplicated in JitOptions - ensure both match.
|
||||
pref("javascript.options.ion.threshold", 1500);
|
||||
pref("javascript.options.ion.full.threshold", 100000);
|
||||
// Duplicated in JitOptions - ensure both match.
|
||||
pref("javascript.options.ion.frequent_bailout_threshold", 10);
|
||||
pref("javascript.options.asmjs", true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче