Bug 1319437 part 2 - Port code for GETPROP on shadowing DOM proxies to CacheIR. r=nbp

This commit is contained in:
Jan de Mooij 2016-11-26 21:19:23 +01:00
Родитель 3cba9f4a2a
Коммит dad5fb18d0
7 изменённых файлов: 37 добавлений и 177 удалений

Просмотреть файл

@ -705,7 +705,6 @@ RecompileBaselineScriptForDebugMode(JSContext* cx, JSScript* script,
_(GetProp_CallNativeGlobal) \
_(GetProp_CallDOMProxyNative) \
_(GetProp_CallDOMProxyWithGenerationNative) \
_(GetProp_DOMProxyShadowed) \
_(GetProp_Generic) \
_(SetProp_CallScripted) \
_(SetProp_CallNative)

Просмотреть файл

@ -1021,7 +1021,6 @@ BaselineInspector::expectedPropertyAccessInputType(jsbytecode* pc)
case ICStub::GetProp_CallDOMProxyNative:
case ICStub::GetProp_CallDOMProxyWithGenerationNative:
case ICStub::GetProp_DOMProxyShadowed:
case ICStub::GetElem_NativeSlotName:
case ICStub::GetElem_NativeSlotSymbol:
case ICStub::GetElem_NativePrototypeSlotName:

Просмотреть файл

@ -403,6 +403,25 @@ GetPropIRGenerator::tryAttachGenericProxy(CacheIRWriter& writer, HandleObject ob
return true;
}
bool
GetPropIRGenerator::tryAttachDOMProxyShadowed(CacheIRWriter& writer, HandleObject obj,
ObjOperandId objId)
{
MOZ_ASSERT(!emitted_);
MOZ_ASSERT(IsCacheableDOMProxy(obj));
emitted_ = true;
writer.guardShape(objId, obj->maybeShape());
// No need for more guards: we know this is a DOM proxy, since the shape
// guard enforces a given JSClass, so just go ahead and emit the call to
// ProxyGet.
writer.callProxyGetResult(objId, NameToId(name_));
writer.typeMonitorResult();
return true;
}
bool
GetPropIRGenerator::tryAttachProxy(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
{
@ -411,6 +430,20 @@ GetPropIRGenerator::tryAttachProxy(CacheIRWriter& writer, HandleObject obj, ObjO
if (!obj->is<ProxyObject>())
return true;
// Skim off DOM proxies.
if (IsCacheableDOMProxy(obj)) {
RootedId id(cx_, NameToId(name_));
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx_, obj, id);
if (shadows == ShadowCheckFailed) {
cx_->clearPendingException();
return false;
}
if (DOMProxyIsShadowing(shadows))
return tryAttachDOMProxyShadowed(writer, obj, objId);
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
}
return tryAttachGenericProxy(writer, obj, objId);
}

Просмотреть файл

@ -465,6 +465,8 @@ class MOZ_RAII GetPropIRGenerator
MOZ_MUST_USE bool tryAttachGenericProxy(CacheIRWriter& writer, HandleObject obj,
ObjOperandId objId);
MOZ_MUST_USE bool tryAttachDOMProxyShadowed(CacheIRWriter& writer, HandleObject obj,
ObjOperandId objId);
MOZ_MUST_USE bool tryAttachProxy(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
MOZ_MUST_USE bool tryAttachPrimitive(CacheIRWriter& writer, ValOperandId valId);

Просмотреть файл

@ -187,7 +187,6 @@ ICStub::NonCacheIRStubMakesGCCalls(Kind kind)
case GetProp_CallNativeGlobal:
case GetProp_CallDOMProxyNative:
case GetProp_CallDOMProxyWithGenerationNative:
case GetProp_DOMProxyShadowed:
case GetProp_Generic:
case SetProp_CallScripted:
case SetProp_CallNative:
@ -480,12 +479,6 @@ ICStub::trace(JSTracer* trc)
TraceEdge(trc, &propStub->getter(), "baseline-getproplistbasenative-stub-getter");
break;
}
case ICStub::GetProp_DOMProxyShadowed: {
ICGetProp_DOMProxyShadowed* propStub = toGetProp_DOMProxyShadowed();
TraceEdge(trc, &propStub->shape(), "baseline-getproplistbaseshadowed-stub-shape");
TraceEdge(trc, &propStub->name(), "baseline-getproplistbaseshadowed-stub-name");
break;
}
case ICStub::GetProp_CallNativeGlobal: {
ICGetProp_CallNativeGlobal* callStub = toGetProp_CallNativeGlobal();
callStub->receiverGuard().trace(trc);
@ -2464,21 +2457,8 @@ TryAttachNativeGetAccessorPropStub(JSContext* cx, SharedStubInfo* info,
isTemporarilyUnoptimizable,
isDOMProxy);
// If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult)) {
MOZ_ASSERT(obj == holder);
JitSpew(JitSpew_BaselineIC, " Generating GetProp(DOMProxyProxy) stub");
Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
ICGetProp_DOMProxyShadowed::Compiler compiler(cx, info->engine(), monitorStub, proxy, name,
info->pcOffset());
ICStub* newStub = compiler.getStub(compiler.getStubSpace(info->outerScript(cx)));
if (!newStub)
return false;
stub->addNewStub(newStub);
*attached = true;
return true;
}
if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult))
return true; // This case is handled by CacheIR.
// Try handling JSNative getters.
if (!cacheableCall || isScripted)
@ -3256,76 +3236,6 @@ ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace* space)
pcOffset_);
}
ICStub*
ICGetProp_DOMProxyShadowed::Compiler::getStub(ICStubSpace* space)
{
RootedShape shape(cx, proxy_->maybeShape());
return New<ICGetProp_DOMProxyShadowed>(cx, space, getStubCode(), firstMonitorStub_, shape,
proxy_->handler(), name_, pcOffset_);
}
static bool
ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp)
{
RootedValue receiver(cx, ObjectValue(*proxy));
RootedId id(cx, NameToId(name));
return Proxy::get(cx, proxy, receiver, id, vp);
}
typedef bool (*ProxyGetFn)(JSContext* cx, HandleObject proxy, HandlePropertyName name,
MutableHandleValue vp);
static const VMFunction ProxyGetInfo = FunctionInfo<ProxyGetFn>(ProxyGet, "ProxyGet");
bool
ICGetProp_DOMProxyShadowed::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
// Need to reserve a scratch register, but the scratch register should not be
// ICTailCallReg, because it's used for |enterStubFrame| which needs a
// non-ICTailCallReg scratch reg.
Register scratch = regs.takeAnyExcluding(ICTailCallReg);
// Guard input is an object.
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
// Unbox.
Register objReg = masm.extractObject(R0, ExtractTemp0);
// Shape guard.
masm.loadPtr(Address(ICStubReg, ICGetProp_DOMProxyShadowed::offsetOfShape()), scratch);
masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure);
// No need to do any more guards; it's safe to call ProxyGet even
// if we've since stopped shadowing.
// Call ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp);
// Push a stub frame so that we can perform a non-tail call.
enterStubFrame(masm, scratch);
// Push property name and proxy object.
masm.loadPtr(Address(ICStubReg, ICGetProp_DOMProxyShadowed::offsetOfName()), scratch);
masm.Push(scratch);
masm.Push(objReg);
// Don't have to preserve R0 anymore.
regs.add(R0);
if (!callVM(ProxyGetInfo, masm))
return false;
leaveStubFrame(masm);
// Enter type monitor IC to type-check result.
EmitEnterTypeMonitorIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
bool
ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler& masm)
{
@ -3575,28 +3485,6 @@ ICGetProp_CallDOMProxyWithGenerationNative::Clone(JSContext* cx,
other.pcOffset_);
}
ICGetProp_DOMProxyShadowed::ICGetProp_DOMProxyShadowed(JitCode* stubCode,
ICStub* firstMonitorStub,
Shape* shape,
const BaseProxyHandler* proxyHandler,
PropertyName* name,
uint32_t pcOffset)
: ICMonitoredStub(ICStub::GetProp_DOMProxyShadowed, stubCode, firstMonitorStub),
shape_(shape),
proxyHandler_(proxyHandler),
name_(name),
pcOffset_(pcOffset)
{ }
/* static */ ICGetProp_DOMProxyShadowed*
ICGetProp_DOMProxyShadowed::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
ICGetProp_DOMProxyShadowed& other)
{
return New<ICGetProp_DOMProxyShadowed>(cx, space, other.jitCode(), firstMonitorStub,
other.shape_, other.proxyHandler_, other.name_,
other.pcOffset_);
}
//
// TypeMonitor_Fallback
//

Просмотреть файл

@ -2792,66 +2792,6 @@ class ICGetPropCallDOMProxyNativeCompiler : public ICStubCompiler {
ICStub* getStub(ICStubSpace* space);
};
class ICGetProp_DOMProxyShadowed : public ICMonitoredStub
{
friend class ICStubSpace;
protected:
GCPtrShape shape_;
const BaseProxyHandler* proxyHandler_;
GCPtrPropertyName name_;
uint32_t pcOffset_;
ICGetProp_DOMProxyShadowed(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
const BaseProxyHandler* proxyHandler, PropertyName* name,
uint32_t pcOffset);
public:
static ICGetProp_DOMProxyShadowed* Clone(JSContext* cx, ICStubSpace* space,
ICStub* firstMonitorStub,
ICGetProp_DOMProxyShadowed& other);
GCPtrShape& shape() {
return shape_;
}
GCPtrPropertyName& name() {
return name_;
}
static size_t offsetOfShape() {
return offsetof(ICGetProp_DOMProxyShadowed, shape_);
}
static size_t offsetOfProxyHandler() {
return offsetof(ICGetProp_DOMProxyShadowed, proxyHandler_);
}
static size_t offsetOfName() {
return offsetof(ICGetProp_DOMProxyShadowed, name_);
}
static size_t offsetOfPCOffset() {
return offsetof(ICGetProp_DOMProxyShadowed, pcOffset_);
}
class Compiler : public ICStubCompiler {
ICStub* firstMonitorStub_;
Rooted<ProxyObject*> proxy_;
RootedPropertyName name_;
uint32_t pcOffset_;
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
public:
Compiler(JSContext* cx, Engine engine, ICStub* firstMonitorStub, Handle<ProxyObject*> proxy,
HandlePropertyName name, uint32_t pcOffset)
: ICStubCompiler(cx, ICStub::GetProp_DOMProxyShadowed, engine),
firstMonitorStub_(firstMonitorStub),
proxy_(cx, proxy),
name_(cx, name),
pcOffset_(pcOffset)
{}
ICStub* getStub(ICStubSpace* space);
};
};
class ICGetProp_ArgumentsLength : public ICStub
{
friend class ICStubSpace;

Просмотреть файл

@ -39,7 +39,6 @@ namespace jit {
_(GetProp_CallNativeGlobal) \
_(GetProp_CallDOMProxyNative) \
_(GetProp_CallDOMProxyWithGenerationNative) \
_(GetProp_DOMProxyShadowed) \
_(GetProp_ArgumentsLength) \
_(GetProp_ArgumentsCallee) \
_(GetProp_Generic) \