Bug 851053 - Remove MRecompileCheck. r=bhackett

This commit is contained in:
Jan de Mooij 2013-03-19 12:23:51 +01:00
parent deb7ce6621
commit 15cc97f0a6
24 changed files with 10 additions and 217 deletions

View File

@ -315,8 +315,6 @@ ConvertFrames(JSContext *cx, IonActivation *activation, IonBailoutIterator &it)
return BAILOUT_RETURN_TYPE_BARRIER;
case Bailout_Monitor:
return BAILOUT_RETURN_MONITOR;
case Bailout_RecompileCheck:
return BAILOUT_RETURN_RECOMPILE_CHECK;
case Bailout_BoundsCheck:
return BAILOUT_RETURN_BOUNDS_CHECK;
case Bailout_ShapeGuard:
@ -471,25 +469,6 @@ ion::ReflowTypeInfo(uint32_t bailoutResult)
return true;
}
uint32_t
ion::RecompileForInlining()
{
JSContext *cx = GetIonContext()->cx;
RawScript script = cx->fp()->script();
IonSpew(IonSpew_Inlining, "Recompiling script to inline calls %s:%d", script->filename(),
script->lineno);
// Invalidate the script to force a recompile.
if (!Invalidate(cx, script, /* resetUses */ false))
return BAILOUT_RETURN_FATAL_ERROR;
// Invalidation should not reset the use count.
JS_ASSERT(script->getUseCount() >= js_IonOptions.usesBeforeInlining());
return true;
}
// Initialize the decl env Object and the call object of the current frame.
bool
ion::EnsureHasScopeObjects(JSContext *cx, StackFrame *fp)

View File

@ -104,11 +104,10 @@ static const uint32_t BAILOUT_RETURN_FATAL_ERROR = 1;
static const uint32_t BAILOUT_RETURN_ARGUMENT_CHECK = 2;
static const uint32_t BAILOUT_RETURN_TYPE_BARRIER = 3;
static const uint32_t BAILOUT_RETURN_MONITOR = 4;
static const uint32_t BAILOUT_RETURN_RECOMPILE_CHECK = 5;
static const uint32_t BAILOUT_RETURN_BOUNDS_CHECK = 6;
static const uint32_t BAILOUT_RETURN_SHAPE_GUARD = 7;
static const uint32_t BAILOUT_RETURN_OVERRECURSED = 8;
static const uint32_t BAILOUT_RETURN_CACHED_SHAPE_GUARD = 9;
static const uint32_t BAILOUT_RETURN_BOUNDS_CHECK = 5;
static const uint32_t BAILOUT_RETURN_SHAPE_GUARD = 6;
static const uint32_t BAILOUT_RETURN_OVERRECURSED = 7;
static const uint32_t BAILOUT_RETURN_CACHED_SHAPE_GUARD = 8;
// Attached to the compartment for easy passing through from ::Bailout to
// ::ThunkToInterpreter.
@ -218,8 +217,6 @@ uint32_t ThunkToInterpreter(Value *vp);
uint32_t ReflowTypeInfo(uint32_t bailoutResult);
uint32_t RecompileForInlining();
uint32_t BoundsCheckFailure();
uint32_t ShapeGuardFailure();

View File

@ -338,9 +338,6 @@ IonBuilder::build()
ins->setResumePoint(current->entryResumePoint());
}
// Recompile to inline calls if this function is hot.
insertRecompileCheck();
if (script()->argumentsHasVarBinding()) {
lazyArguments_ = MConstant::New(MagicValue(JS_OPTIMIZED_ARGUMENTS));
current->add(lazyArguments_);
@ -763,12 +760,9 @@ IonBuilder::inspectOpcode(JSOp op)
return true;
switch (op) {
case JSOP_LOOPENTRY:
insertRecompileCheck();
return true;
case JSOP_NOP:
case JSOP_LINENO:
case JSOP_LOOPENTRY:
return true;
case JSOP_LABEL:
@ -4975,29 +4969,6 @@ IonBuilder::maybeInsertResume()
return resumeAfter(ins);
}
void
IonBuilder::insertRecompileCheck()
{
if (!inliningEnabled())
return;
if (inliningDepth_ > 0)
return;
// Don't recompile if we are already inlining.
if (script()->getUseCount() >= js_IonOptions.usesBeforeInlining())
return;
// Don't recompile if the oracle cannot provide inlining information
// or if the script has no calls.
if (!oracle->canInlineCalls())
return;
uint32_t minUses = UsesBeforeIonRecompile(script(), pc);
MRecompileCheck *check = MRecompileCheck::New(minUses);
current->add(check);
}
static inline bool
TestSingletonProperty(JSContext *cx, HandleObject obj, HandleId id, bool *isKnownConstant)
{

View File

@ -271,8 +271,6 @@ class IonBuilder : public MIRGenerator
bool resumeAfter(MInstruction *ins);
bool maybeInsertResume();
void insertRecompileCheck();
bool initParameters();
void rewriteParameters();
bool initScopeChain();

View File

@ -655,7 +655,6 @@ MacroAssembler::generateBailoutTail(Register scratch)
Label interpret;
Label exception;
Label osr;
Label recompile;
Label boundscheck;
Label overrecursed;
Label invalidate;
@ -666,17 +665,15 @@ MacroAssembler::generateBailoutTail(Register scratch)
// - 0x2: reflow args
// - 0x3: reflow barrier
// - 0x4: monitor types
// - 0x5: recompile to inline calls
// - 0x6: bounds check failure
// - 0x7: force invalidation
// - 0x8: overrecursed
// - 0x9: cached shape guard failure
// - 0x5: bounds check failure
// - 0x6: force invalidation
// - 0x7: overrecursed
// - 0x8: cached shape guard failure
branch32(LessThan, ReturnReg, Imm32(BAILOUT_RETURN_FATAL_ERROR), &interpret);
branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_FATAL_ERROR), &exception);
branch32(LessThan, ReturnReg, Imm32(BAILOUT_RETURN_RECOMPILE_CHECK), &reflow);
branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_RECOMPILE_CHECK), &recompile);
branch32(LessThan, ReturnReg, Imm32(BAILOUT_RETURN_BOUNDS_CHECK), &reflow);
branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_BOUNDS_CHECK), &boundscheck);
branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_OVERRECURSED), &overrecursed);
@ -711,16 +708,6 @@ MacroAssembler::generateBailoutTail(Register scratch)
jump(&interpret);
}
// Recompile to inline calls.
bind(&recompile);
{
setupUnalignedABICall(0, scratch);
callWithABI(JS_FUNC_TO_DATA_PTR(void *, RecompileForInlining));
branchTest32(Zero, ReturnReg, ReturnReg, &exception);
jump(&interpret);
}
// Reflow types.
bind(&reflow);
{

View File

@ -37,9 +37,6 @@ enum BailoutKind
// A bailout required to monitor the result of a VM call.
Bailout_Monitor,
// A bailout to trigger recompilation to inline calls when the script is hot.
Bailout_RecompileCheck,
// A bailout triggered by a bounds-check failure.
Bailout_BoundsCheck,

View File

@ -36,7 +36,6 @@
_(InitProp) \
_(CheckOverRecursed) \
_(ParCheckOverRecursed) \
_(RecompileCheck) \
_(DefVar) \
_(DefFun) \
_(CallKnown) \

View File

@ -3475,32 +3475,6 @@ class MParCheckInterrupt : public MUnaryInstruction
}
};
// Check the script's use count and trigger recompilation to inline
// calls when the script becomes hot.
class MRecompileCheck : public MNullaryInstruction
{
uint32_t minUses_;
MRecompileCheck(uint32_t minUses)
: minUses_(minUses)
{
setGuard();
}
public:
INSTRUCTION_HEADER(RecompileCheck)
uint32_t minUses() const {
return minUses_;
}
static MRecompileCheck *New(uint32_t minUses) {
return new MRecompileCheck(minUses);
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
};
// Check whether we need to fire the interrupt handler.
class MInterruptCheck : public MNullaryInstruction
{

View File

@ -27,7 +27,6 @@ namespace ion {
_(OsrScopeChain) \
_(ReturnFromCtor) \
_(CheckOverRecursed) \
_(RecompileCheck) \
_(DefVar) \
_(DefFun) \
_(CreateThis) \

View File

@ -131,7 +131,6 @@ class ParallelArrayVisitor : public MInstructionVisitor
UNSAFE_OP(OsrScopeChain)
UNSAFE_OP(ReturnFromCtor)
CUSTOM_OP(CheckOverRecursed)
DROP_OP(RecompileCheck)
UNSAFE_OP(DefVar)
UNSAFE_OP(DefFun)
UNSAFE_OP(CreateThis)

View File

@ -528,12 +528,6 @@ TypeInferenceOracle::arrayResultShouldHaveDoubleConversion(RawScript script, jsb
return conversion == types::StackTypeSet::AlwaysConvertToDoubles;
}
bool
TypeInferenceOracle::canInlineCalls()
{
return script()->analysis()->hasFunctionCalls();
}
bool
TypeInferenceOracle::propertyWriteCanSpecialize(RawScript script, jsbytecode *pc)
{

View File

@ -144,9 +144,6 @@ class TypeOracle
virtual MIRType elementWrite(RawScript script, jsbytecode *pc) {
return MIRType_None;
}
virtual bool canInlineCalls() {
return false;
}
/* |pc| must be a |JSOP_CALL|. */
virtual types::StackTypeSet *getCallTarget(RawScript caller, uint32_t argc, jsbytecode *pc) {
@ -274,7 +271,6 @@ class TypeInferenceOracle : public TypeOracle
bool propertyWriteNeedsBarrier(RawScript script, jsbytecode *pc, RawId id);
bool elementWriteNeedsBarrier(RawScript script, jsbytecode *pc);
MIRType elementWrite(RawScript script, jsbytecode *pc);
bool canInlineCalls();
bool canInlineCall(HandleScript caller, jsbytecode *pc);
types::TypeBarrier *callArgsBarrier(HandleScript caller, jsbytecode *pc);
bool canEnterInlinedFunction(RawScript caller, jsbytecode *pc, RawFunction callee);

View File

@ -1556,26 +1556,6 @@ CodeGeneratorARM::visitImplicitThis(LImplicitThis *lir)
return true;
}
bool
CodeGeneratorARM::visitRecompileCheck(LRecompileCheck *lir)
{
Register tmp = ToRegister(lir->tempInt());
size_t *addr = gen->info().script()->addressOfUseCount();
// Bump the script's use count. Note that it's safe to bake in this pointer
// since scripts are never nursery allocated and jitcode will be purged before
// doing a compacting GC.
masm.load32(AbsoluteAddress(addr), tmp);
masm.ma_add(Imm32(1), tmp);
masm.store32(tmp, AbsoluteAddress(addr));
// Bailout if the script is hot.
masm.ma_cmp(tmp, Imm32(lir->mir()->minUses()));
if (!bailoutIf(Assembler::AboveOrEqual, lir->snapshot()))
return false;
return true;
}
typedef bool (*InterruptCheckFn)(JSContext *);
static const VMFunction InterruptCheckInfo = FunctionInfo<InterruptCheckFn>(InterruptCheck);

View File

@ -139,7 +139,6 @@ class CodeGeneratorARM : public CodeGeneratorShared
bool visitGuardClass(LGuardClass *guard);
bool visitImplicitThis(LImplicitThis *lir);
bool visitRecompileCheck(LRecompileCheck *lir);
bool visitInterruptCheck(LInterruptCheck *lir);
bool generateInvalidateEpilogue();

View File

@ -278,22 +278,6 @@ class LGuardShape : public LInstructionHelper<0, 1, 1>
}
};
class LRecompileCheck : public LInstructionHelper<0, 0, 1>
{
public:
LIR_HEADER(RecompileCheck);
LRecompileCheck(const LDefinition &temp) {
setTemp(0, temp);
}
const LAllocation *tempInt() {
return getTemp(0)->output();
}
const MRecompileCheck *mir() const {
return mir_->toRecompileCheck();
}
};
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
{
public:

View File

@ -316,13 +316,6 @@ LIRGeneratorARM::visitGuardShape(MGuardShape *ins)
return redefine(ins, ins->obj());
}
bool
LIRGeneratorARM::visitRecompileCheck(MRecompileCheck *ins)
{
LRecompileCheck *lir = new LRecompileCheck(temp(LDefinition::GENERAL));
return assignSnapshot(lir, Bailout_RecompileCheck) && add(lir, ins);
}
bool
LIRGeneratorARM::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
{

View File

@ -60,7 +60,6 @@ class LIRGeneratorARM : public LIRGeneratorShared
bool visitReturn(MReturn *ret);
bool lowerPhi(MPhi *phi);
bool visitGuardShape(MGuardShape *ins);
bool visitRecompileCheck(MRecompileCheck *ins);
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
bool visitInterruptCheck(MInterruptCheck *ins);
};

View File

@ -188,16 +188,6 @@ class LGuardShape : public LInstructionHelper<0, 1, 0>
}
};
class LRecompileCheck : public LInstructionHelper<0, 0, 0>
{
public:
LIR_HEADER(RecompileCheck)
const MRecompileCheck *mir() const {
return mir_->toRecompileCheck();
}
};
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
{
public:

View File

@ -25,13 +25,6 @@ LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch *tableswitch)
return new LTableSwitchV(temp(), tempFloat(), temp(), tableswitch);
}
bool
LIRGeneratorX86Shared::visitRecompileCheck(MRecompileCheck *ins)
{
LRecompileCheck *lir = new LRecompileCheck();
return assignSnapshot(lir, Bailout_RecompileCheck) && add(lir, ins);
}
bool
LIRGeneratorX86Shared::visitInterruptCheck(MInterruptCheck *ins)
{

View File

@ -24,7 +24,6 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared
MTableSwitch *ins);
LTableSwitchV *newLTableSwitchV(MTableSwitch *ins);
bool visitRecompileCheck(MRecompileCheck *ins);
bool visitInterruptCheck(MInterruptCheck *ins);
bool visitGuardShape(MGuardShape *ins);
bool visitPowHalf(MPowHalf *ins);

View File

@ -285,23 +285,6 @@ CodeGeneratorX64::visitImplicitThis(LImplicitThis *lir)
return true;
}
bool
CodeGeneratorX64::visitRecompileCheck(LRecompileCheck *lir)
{
// Bump the script's use count and bailout if the script is hot. Note that
// it's safe to bake in this pointer since scripts are never nursery
// allocated and jitcode will be purged before doing a compacting GC.
const uint32_t *useCount = gen->info().script()->addressOfUseCount();
masm.movq(ImmWord(useCount), ScratchReg);
Operand addr(ScratchReg, 0);
masm.addl(Imm32(1), addr);
masm.cmpl(addr, Imm32(lir->mir()->minUses()));
if (!bailoutIf(Assembler::AboveOrEqual, lir->snapshot()))
return false;
return true;
}
typedef bool (*InterruptCheckFn)(JSContext *);
static const VMFunction InterruptCheckInfo = FunctionInfo<InterruptCheckFn>(InterruptCheck);

View File

@ -46,7 +46,6 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared
bool visitStoreSlotT(LStoreSlotT *store);
bool visitLoadElementT(LLoadElementT *load);
bool visitImplicitThis(LImplicitThis *lir);
bool visitRecompileCheck(LRecompileCheck *lir);
bool visitInterruptCheck(LInterruptCheck *lir);
bool visitCompareB(LCompareB *lir);
bool visitCompareBAndBranch(LCompareBAndBranch *lir);

View File

@ -262,21 +262,6 @@ CodeGeneratorX86::visitImplicitThis(LImplicitThis *lir)
return true;
}
bool
CodeGeneratorX86::visitRecompileCheck(LRecompileCheck *lir)
{
// Bump the script's use count and bailout if the script is hot. Note that
// it's safe to bake in this pointer since scripts are never nursery
// allocated and jitcode will be purged before doing a compacting GC.
// Without this assumption we'd need a temp register here.
Operand addr(gen->info().script()->addressOfUseCount());
masm.addl(Imm32(1), addr);
masm.cmpl(addr, Imm32(lir->mir()->minUses()));
if (!bailoutIf(Assembler::AboveOrEqual, lir->snapshot()))
return false;
return true;
}
typedef bool (*InterruptCheckFn)(JSContext *);
static const VMFunction InterruptCheckInfo = FunctionInfo<InterruptCheckFn>(InterruptCheck);

View File

@ -45,7 +45,6 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared
bool visitStoreSlotT(LStoreSlotT *store);
bool visitLoadElementT(LLoadElementT *load);
bool visitImplicitThis(LImplicitThis *lir);
bool visitRecompileCheck(LRecompileCheck *lir);
bool visitInterruptCheck(LInterruptCheck *lir);
bool visitCompareB(LCompareB *lir);
bool visitCompareBAndBranch(LCompareBAndBranch *lir);