Bug 985130 - IonMonkey: Omit over-recursion checks in leaf functions. r=luke

This commit is contained in:
Dan Gohman 2014-04-08 16:00:29 -07:00
parent 59b8c545c2
commit fd6e1e6d15
5 changed files with 33 additions and 0 deletions

View File

@ -2693,9 +2693,24 @@ class CheckOverRecursedFailure : public OutOfLineCodeBase<CodeGenerator>
}
};
bool
CodeGenerator::omitOverRecursedCheck() const
{
// If the current function makes no calls (which means it isn't recursive)
// and it uses only a small amount of stack space, it doesn't need a
// stack overflow check. Note that the actual number here is somewhat
// arbitrary, and codegen actually uses small bounded amounts of
// additional stack space in some cases too.
return frameSize() < 64 && !gen->performsCall();
}
bool
CodeGenerator::visitCheckOverRecursed(LCheckOverRecursed *lir)
{
// If we don't push anything on the stack, skip the check.
if (omitOverRecursedCheck())
return true;
// Ensure that this frame will not cross the stack limit.
// This is a weak check, justified by Ion using the C stack: we must always
// be some distance away from the actual limit, since if the limit is
@ -8198,6 +8213,10 @@ CodeGenerator::visitAsmJSVoidReturn(LAsmJSVoidReturn *lir)
bool
CodeGenerator::visitAsmJSCheckOverRecursed(LAsmJSCheckOverRecursed *lir)
{
// If we don't push anything on the stack, skip the check.
if (omitOverRecursedCheck())
return true;
masm.branchPtr(Assembler::AboveOrEqual,
AsmJSAbsoluteAddress(AsmJSImm_StackLimit),
StackPointer,

View File

@ -443,6 +443,8 @@ class CodeGenerator : public CodeGeneratorSpecific
bool emitAssertRangeI(const Range *r, Register input);
bool emitAssertRangeD(const Range *r, FloatRegister input, FloatRegister temp);
bool omitOverRecursedCheck() const;
Vector<CodeOffsetLabel, 0, IonAllocPolicy> ionScriptLabels_;
#ifdef DEBUG
bool branchIfInvalidated(Register temp, Label *invalidated);

View File

@ -3586,6 +3586,9 @@ LIRGenerator::visitInstruction(MInstruction *ins)
if (!ins->accept(this))
return false;
if (ins->isCall())
gen->setPerformsCall();
if (ins->resumePoint())
updateResumeState(ins);

View File

@ -105,8 +105,15 @@ class MIRGenerator
JS_ASSERT(compilingAsmJS());
maxAsmJSStackArgBytes_ = n;
}
void setPerformsCall() {
performsCall_ = true;
}
bool performsCall() const {
return performsCall_;
}
void setPerformsAsmJSCall() {
JS_ASSERT(compilingAsmJS());
setPerformsCall();
performsAsmJSCall_ = true;
}
bool performsAsmJSCall() const {
@ -150,6 +157,7 @@ class MIRGenerator
mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_;
uint32_t maxAsmJSStackArgBytes_;
bool performsCall_;
bool performsAsmJSCall_;
AsmJSHeapAccessVector asmJSHeapAccesses_;
AsmJSGlobalAccessVector asmJSGlobalAccesses_;

View File

@ -27,6 +27,7 @@ MIRGenerator::MIRGenerator(CompileCompartment *compartment, const JitCompileOpti
error_(false),
cancelBuild_(false),
maxAsmJSStackArgBytes_(0),
performsCall_(false),
performsAsmJSCall_(false),
asmJSHeapAccesses_(*alloc),
asmJSGlobalAccesses_(*alloc),