Bug 1049840 - Add generic GetProp stub to baseline to replace optimized stub chain, if MAX_OPTIMIZED_STUBS is reached. r=djvj

This commit is contained in:
Johannes Schulte 2014-08-06 20:16:15 +02:00
parent bf7ddd9c43
commit f361fba452
2 changed files with 86 additions and 2 deletions

View File

@ -6560,6 +6560,9 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_
JS_ASSERT(op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH || op == JSOP_GETXPROP);
// After the Genericstub was added, we should never reach the Fallbackstub again.
JS_ASSERT(!stub->hasStub(ICStub::GetProp_Generic));
RootedPropertyName name(cx, frame->script()->getName(pc));
if (!ComputeGetPropResult(cx, frame, op, name, val, res))
return false;
@ -6575,7 +6578,14 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_
return false;
if (stub->numOptimizedStubs() >= ICGetProp_Fallback::MAX_OPTIMIZED_STUBS) {
// TODO: Discard all stubs in this IC and replace with generic getprop stub.
// Discard all stubs in this IC and replace with generic getprop stub.
for(ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++)
iter.unlink(cx);
ICGetProp_Generic::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub());
ICStub *newStub = compiler.getStub(compiler.getStubSpace(frame->script()));
if (!newStub)
return false;
stub->addNewStub(newStub);
return true;
}
@ -7437,6 +7447,45 @@ ICGetProp_ArgumentsCallee::Compiler::generateStubCode(MacroAssembler &masm)
return true;
}
static bool
DoGetPropGeneric(JSContext *cx, BaselineFrame *frame, ICGetProp_Generic *stub, MutableHandleValue val, MutableHandleValue res)
{
jsbytecode *pc = stub->getChainFallback()->icEntry()->pc(frame->script());
JSOp op = JSOp(*pc);
RootedPropertyName name(cx, frame->script()->getName(pc));
return ComputeGetPropResult(cx, frame, op, name, val, res);
}
typedef bool (*DoGetPropGenericFn)(JSContext *, BaselineFrame *, ICGetProp_Generic *, MutableHandleValue, MutableHandleValue);
static const VMFunction DoGetPropGenericInfo = FunctionInfo<DoGetPropGenericFn>(DoGetPropGeneric);
bool
ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler &masm)
{
GeneralRegisterSet regs(availableGeneralRegs(1));
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
// Sync for the decompiler.
EmitStowICValues(masm, 1);
enterStubFrame(masm, scratch);
// Push arguments.
masm.pushValue(R0);
masm.push(BaselineStubReg);
masm.loadPtr(Address(BaselineFrameReg, 0), R0.scratchReg());
masm.pushBaselineFramePtr(R0.scratchReg(), R0.scratchReg());
if(!callVM(DoGetPropGenericInfo, masm))
return false;
leaveStubFrame(masm);
EmitUnstowICValues(masm, 1, /* discard = */ true);
EmitEnterTypeMonitorIC(masm);
return true;
}
void
BaselineScript::noteAccessedGetter(uint32_t pcOffset)
{

View File

@ -422,6 +422,7 @@ class ICEntry
_(GetProp_DOMProxyShadowed) \
_(GetProp_ArgumentsLength) \
_(GetProp_ArgumentsCallee) \
_(GetProp_Generic) \
\
_(SetProp_Fallback) \
_(SetProp_Native) \
@ -800,6 +801,7 @@ class ICStub
case GetProp_CallDOMProxyNative:
case GetProp_CallDOMProxyWithGenerationNative:
case GetProp_DOMProxyShadowed:
case GetProp_Generic:
case SetProp_CallScripted:
case SetProp_CallNative:
case RetSub_Fallback:
@ -4091,7 +4093,7 @@ class ICGetProp_Fallback : public ICMonitoredFallbackStub
{ }
public:
static const uint32_t MAX_OPTIMIZED_STUBS = 8;
static const uint32_t MAX_OPTIMIZED_STUBS = 16;
static inline ICGetProp_Fallback *New(ICStubSpace *space, JitCode *code) {
if (!code)
@ -4136,6 +4138,39 @@ class ICGetProp_Fallback : public ICMonitoredFallbackStub
};
};
// Stub for sites, which are too polymorphic (i.e. MAX_OPTIMIZED_STUBS was reached)
class ICGetProp_Generic : public ICMonitoredStub
{
friend class ICStubSpace;
protected:
explicit ICGetProp_Generic(JitCode *stubCode, ICStub *firstMonitorStub)
: ICMonitoredStub(ICStub::GetProp_Generic, stubCode, firstMonitorStub) {}
public:
static inline ICGetProp_Generic *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub)
{
if(!code)
return nullptr;
return space->allocate<ICGetProp_Generic>(code, firstMonitorStub);
}
class Compiler : public ICStubCompiler {
protected:
bool generateStubCode(MacroAssembler &masm);
ICStub *firstMonitorStub_;
public:
explicit Compiler(JSContext *cx, ICStub *firstMonitorStub)
: ICStubCompiler(cx, ICStub::GetProp_Generic),
firstMonitorStub_(firstMonitorStub)
{}
ICStub *getStub(ICStubSpace *space) {
return ICGetProp_Generic::New(space, getStubCode(), firstMonitorStub_);
}
};
};
// Stub for accessing a dense array's length.
class ICGetProp_ArrayLength : public ICStub
{