зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322093 followup - Make idempotent ICs handle unshadowed DOM proxies to fix Dromaeo regressions. r=evilpie on IRC
--HG-- extra : rebase_source : 593e4f4e25fcf63cfa391a93ac088c1bce1f3c2f extra : source : 981fd29c57012c7e8a28168ca0941e00be560462
This commit is contained in:
Родитель
55da96bdab
Коммит
2555852e40
|
@ -45,12 +45,40 @@ EmitLoadSlotResult(CacheIRWriter& writer, ObjOperandId holderOp, NativeObject* h
|
|||
}
|
||||
}
|
||||
|
||||
enum class ProxyStubType {
|
||||
None,
|
||||
DOMShadowed,
|
||||
DOMUnshadowed,
|
||||
Generic
|
||||
};
|
||||
|
||||
static ProxyStubType
|
||||
GetProxyStubType(JSContext* cx, HandleObject obj, HandleId id)
|
||||
{
|
||||
if (!obj->is<ProxyObject>())
|
||||
return ProxyStubType::None;
|
||||
|
||||
if (!IsCacheableDOMProxy(obj))
|
||||
return ProxyStubType::Generic;
|
||||
|
||||
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
|
||||
if (shadows == ShadowCheckFailed) {
|
||||
cx->clearPendingException();
|
||||
return ProxyStubType::None;
|
||||
}
|
||||
|
||||
if (DOMProxyIsShadowing(shadows))
|
||||
return ProxyStubType::DOMShadowed;
|
||||
|
||||
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
|
||||
return ProxyStubType::DOMUnshadowed;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropIRGenerator::tryAttachStub()
|
||||
{
|
||||
// pc_ should only be null for idempotent ICs, and idempotent ICs should
|
||||
// call tryAttachIdempotentStub instead.
|
||||
MOZ_ASSERT(pc_);
|
||||
// Idempotent ICs should call tryAttachIdempotentStub instead.
|
||||
MOZ_ASSERT(!idempotent());
|
||||
|
||||
AutoAssertNoPendingException aanpe(cx_);
|
||||
|
||||
|
@ -140,16 +168,21 @@ GetPropIRGenerator::tryAttachIdempotentStub()
|
|||
// of (2), we don't support for instance missing properties or array
|
||||
// lengths, as TI does not account for these cases.
|
||||
|
||||
// No pc if idempotent, as there can be multiple bytecode locations
|
||||
// due to GVN.
|
||||
MOZ_ASSERT(!pc_);
|
||||
MOZ_ASSERT(idempotent());
|
||||
|
||||
RootedObject obj(cx_, &val_.toObject());
|
||||
RootedId id(cx_, NameToId(idVal_.toString()->asAtom().asPropertyName()));
|
||||
|
||||
ValOperandId valId(writer.setInputOperandId(0));
|
||||
ObjOperandId objId = writer.guardIsObject(valId);
|
||||
return tryAttachNative(obj, objId, id);
|
||||
if (tryAttachNative(obj, objId, id))
|
||||
return true;
|
||||
|
||||
// Also support native data properties on DOMProxy prototypes.
|
||||
if (GetProxyStubType(cx_, obj, id) == ProxyStubType::DOMUnshadowed)
|
||||
return tryAttachDOMProxyUnshadowed(obj, objId, id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -202,11 +235,16 @@ CanAttachNativeGetProp(JSContext* cx, HandleObject obj, HandleId id,
|
|||
holder.set(&baseHolder->as<NativeObject>());
|
||||
}
|
||||
|
||||
if (IsCacheableGetPropReadSlotForIonOrCacheIR(obj, holder, shape) ||
|
||||
IsCacheableNoProperty(cx, obj, holder, shape, id, pc))
|
||||
{
|
||||
if (IsCacheableGetPropReadSlotForIonOrCacheIR(obj, holder, shape))
|
||||
return CanAttachReadSlot;
|
||||
|
||||
// Idempotent ICs only support plain data properties, see
|
||||
// tryAttachIdempotentStub.
|
||||
if (!pc)
|
||||
return CanAttachNone;
|
||||
|
||||
if (IsCacheableNoProperty(cx, obj, holder, shape, id, pc))
|
||||
return CanAttachReadSlot;
|
||||
}
|
||||
|
||||
if (IsCacheableGetPropCallScripted(obj, holder, shape, isTemporarilyUnoptimizable)) {
|
||||
// See bug 1226816.
|
||||
|
@ -381,13 +419,8 @@ GetPropIRGenerator::tryAttachNative(HandleObject obj, ObjOperandId objId, Handle
|
|||
|
||||
NativeGetPropCacheability type = CanAttachNativeGetProp(cx_, obj, id, &holder, &shape, pc_,
|
||||
engine_, isTemporarilyUnoptimizable_);
|
||||
if (!pc_) {
|
||||
// Idempotent ICs only support plain data properties.
|
||||
if (type != CanAttachReadSlot)
|
||||
return false;
|
||||
MOZ_ASSERT(holder);
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(idempotent(),
|
||||
type == CanAttachNone || (type == CanAttachReadSlot && holder));
|
||||
switch (type) {
|
||||
case CanAttachNone:
|
||||
return false;
|
||||
|
@ -546,6 +579,8 @@ GetPropIRGenerator::tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId o
|
|||
NativeGetPropCacheability canCache = CanAttachNativeGetProp(cx_, checkObj, id, &holder, &shape,
|
||||
pc_, engine_,
|
||||
isTemporarilyUnoptimizable_);
|
||||
MOZ_ASSERT_IF(idempotent(),
|
||||
canCache == CanAttachNone || (canCache == CanAttachReadSlot && holder));
|
||||
if (canCache == CanAttachNone)
|
||||
return false;
|
||||
|
||||
|
@ -588,24 +623,18 @@ GetPropIRGenerator::tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId o
|
|||
bool
|
||||
GetPropIRGenerator::tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleId id)
|
||||
{
|
||||
if (!obj->is<ProxyObject>())
|
||||
switch (GetProxyStubType(cx_, obj, id)) {
|
||||
case ProxyStubType::None:
|
||||
return false;
|
||||
|
||||
// Skim off DOM proxies.
|
||||
if (IsCacheableDOMProxy(obj)) {
|
||||
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx_, obj, id);
|
||||
if (shadows == ShadowCheckFailed) {
|
||||
cx_->clearPendingException();
|
||||
return false;
|
||||
}
|
||||
if (DOMProxyIsShadowing(shadows))
|
||||
return tryAttachDOMProxyShadowed(obj, objId, id);
|
||||
|
||||
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
|
||||
case ProxyStubType::DOMShadowed:
|
||||
return tryAttachDOMProxyShadowed(obj, objId, id);
|
||||
case ProxyStubType::DOMUnshadowed:
|
||||
return tryAttachDOMProxyUnshadowed(obj, objId, id);
|
||||
case ProxyStubType::Generic:
|
||||
return tryAttachGenericProxy(obj, objId, id);
|
||||
}
|
||||
|
||||
return tryAttachGenericProxy(obj, objId, id);
|
||||
MOZ_CRASH("Unexpected ProxyStubType");
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -717,6 +717,10 @@ class MOZ_RAII GetPropIRGenerator
|
|||
return ValOperandId(1);
|
||||
}
|
||||
|
||||
// No pc if idempotent, as there can be multiple bytecode locations
|
||||
// due to GVN.
|
||||
bool idempotent() const { return pc_ == nullptr; }
|
||||
|
||||
// If this is a GetElem cache, emit instructions to guard the incoming Value
|
||||
// matches |id|.
|
||||
void maybeEmitIdGuard(jsid id);
|
||||
|
|
Загрузка…
Ссылка в новой задаче