зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1338828 part 3 - Add CacheIR SetProp/SetElem stubs for unshadowed setter calls on DOM proxies. r=h4writer
This commit is contained in:
Родитель
26b0ba2897
Коммит
cb50efb0c8
|
@ -2165,9 +2165,36 @@ SetPropIRGenerator::trackNotAttached()
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
CanAttachSetter(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleId id,
|
||||
MutableHandleObject holder, MutableHandleShape propShape,
|
||||
bool* isTemporarilyUnoptimizable)
|
||||
{
|
||||
// Don't attach a setter stub for ops like JSOP_INITELEM.
|
||||
if (IsPropertyInitOp(JSOp(*pc)))
|
||||
return false;
|
||||
MOZ_ASSERT(IsPropertySetOp(JSOp(*pc)));
|
||||
|
||||
PropertyResult prop;
|
||||
if (!LookupPropertyPure(cx, obj, id, holder.address(), &prop))
|
||||
return false;
|
||||
|
||||
if (prop.isNonNativeProperty())
|
||||
return false;
|
||||
|
||||
propShape.set(prop.maybeShape());
|
||||
if (!IsCacheableSetPropCallScripted(obj, holder, propShape, isTemporarilyUnoptimizable) &&
|
||||
!IsCacheableSetPropCallNative(obj, holder, propShape))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
EmitCallSetterResultNoGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
|
||||
Shape* shape, ObjOperandId objId, ValOperandId rhsId)
|
||||
EmitCallSetterNoGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
|
||||
Shape* shape, ObjOperandId objId, ValOperandId rhsId)
|
||||
{
|
||||
if (IsCacheableSetPropCallNative(obj, holder, shape)) {
|
||||
JSFunction* target = &shape->setterValue().toObject().as<JSFunction>();
|
||||
|
@ -2189,30 +2216,15 @@ bool
|
|||
SetPropIRGenerator::tryAttachSetter(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId)
|
||||
{
|
||||
// Don't attach a setter stub for ops like JSOP_INITELEM.
|
||||
if (IsPropertyInitOp(JSOp(*pc_)))
|
||||
RootedObject holder(cx_);
|
||||
RootedShape propShape(cx_);
|
||||
if (!CanAttachSetter(cx_, pc_, obj, id, &holder, &propShape, isTemporarilyUnoptimizable_))
|
||||
return false;
|
||||
MOZ_ASSERT(IsPropertySetOp(JSOp(*pc_)));
|
||||
|
||||
PropertyResult prop;
|
||||
JSObject* holder;
|
||||
if (!LookupPropertyPure(cx_, obj, id, &holder, &prop))
|
||||
return false;
|
||||
|
||||
if (prop.isNonNativeProperty())
|
||||
return false;
|
||||
|
||||
Shape* shape = prop.maybeShape();
|
||||
if (!IsCacheableSetPropCallScripted(obj, holder, shape, isTemporarilyUnoptimizable_) &&
|
||||
!IsCacheableSetPropCallNative(obj, holder, shape))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
maybeEmitIdGuard(id);
|
||||
|
||||
Maybe<ObjOperandId> expandoId;
|
||||
TestMatchingReceiver(writer, obj, shape, objId, &expandoId);
|
||||
TestMatchingReceiver(writer, obj, propShape, objId, &expandoId);
|
||||
|
||||
if (obj != holder) {
|
||||
GeneratePrototypeGuards(writer, obj, holder, objId);
|
||||
|
@ -2222,7 +2234,7 @@ SetPropIRGenerator::tryAttachSetter(HandleObject obj, ObjOperandId objId, Handle
|
|||
writer.guardShape(holderId, holder->as<NativeObject>().lastProperty());
|
||||
}
|
||||
|
||||
EmitCallSetterResultNoGuards(writer, obj, holder, shape, objId, rhsId);
|
||||
EmitCallSetterNoGuards(writer, obj, holder, propShape, objId, rhsId);
|
||||
|
||||
trackAttached("Setter");
|
||||
return true;
|
||||
|
@ -2512,15 +2524,19 @@ SetPropIRGenerator::tryAttachSetUnboxedArrayElementHole(HandleObject obj, ObjOpe
|
|||
|
||||
bool
|
||||
SetPropIRGenerator::tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId)
|
||||
ValOperandId rhsId, bool handleDOMProxies)
|
||||
{
|
||||
MOZ_ASSERT(obj->is<ProxyObject>());
|
||||
|
||||
writer.guardIsProxy(objId);
|
||||
|
||||
// Ensure that the incoming object is not a DOM proxy, so that we can get to
|
||||
// the specialized stubs
|
||||
writer.guardNotDOMProxy(objId);
|
||||
if (!handleDOMProxies) {
|
||||
// Ensure that the incoming object is not a DOM proxy, so that we can
|
||||
// get to the specialized stubs. If handleDOMProxies is true, we were
|
||||
// unable to attach a specialized DOM stub, so we just handle all
|
||||
// proxies here.
|
||||
writer.guardNotDOMProxy(objId);
|
||||
}
|
||||
|
||||
if (cacheKind_ == CacheKind::SetProp) {
|
||||
writer.callProxySet(objId, id, rhsId, IsStrictSetPC(pc_));
|
||||
|
@ -2557,6 +2573,42 @@ SetPropIRGenerator::tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId obj
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropIRGenerator::tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId)
|
||||
{
|
||||
MOZ_ASSERT(IsCacheableDOMProxy(obj));
|
||||
|
||||
RootedObject proto(cx_, obj->staticPrototype());
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
RootedObject holder(cx_);
|
||||
RootedShape propShape(cx_);
|
||||
if (!CanAttachSetter(cx_, pc_, proto, id, &holder, &propShape, isTemporarilyUnoptimizable_))
|
||||
return false;
|
||||
|
||||
maybeEmitIdGuard(id);
|
||||
writer.guardShape(objId, obj->maybeShape());
|
||||
|
||||
// Guard that our expando object hasn't started shadowing this property.
|
||||
CheckDOMProxyExpandoDoesNotShadow(writer, obj, id, objId);
|
||||
|
||||
GeneratePrototypeGuards(writer, obj, holder, objId);
|
||||
|
||||
// Guard on the holder of the property.
|
||||
ObjOperandId holderId = writer.loadObject(holder);
|
||||
writer.guardShape(holderId, holder->as<NativeObject>().lastProperty());
|
||||
|
||||
// EmitCallSetterNoGuards expects |obj| to be the object the property is
|
||||
// on to do some checks. Since we actually looked at proto, and no extra
|
||||
// guards will be generated, we can just pass that instead.
|
||||
EmitCallSetterNoGuards(writer, proto, holder, propShape, objId, rhsId);
|
||||
|
||||
trackAttached("DOMProxyUnshadowed");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropIRGenerator::tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId)
|
||||
|
@ -2568,8 +2620,11 @@ SetPropIRGenerator::tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleI
|
|||
case ProxyStubType::DOMShadowed:
|
||||
return tryAttachDOMProxyShadowed(obj, objId, id, rhsId);
|
||||
case ProxyStubType::DOMUnshadowed:
|
||||
if (tryAttachDOMProxyUnshadowed(obj, objId, id, rhsId))
|
||||
return true;
|
||||
return tryAttachGenericProxy(obj, objId, id, rhsId, /* handleDOMProxies = */ true);
|
||||
case ProxyStubType::Generic:
|
||||
return tryAttachGenericProxy(obj, objId, id, rhsId);
|
||||
return tryAttachGenericProxy(obj, objId, id, rhsId, /* handleDOMProxies = */ false);
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unexpected ProxyStubType");
|
||||
|
|
|
@ -1092,9 +1092,11 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator
|
|||
Int32OperandId indexId, ValOperandId rhsId);
|
||||
|
||||
bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
ValOperandId rhsId, bool handleDOMProxies);
|
||||
bool tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId, ValOperandId rhsId);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче