mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1180990 - Add checks for nursery objects when building MIR. r=jandem
CLOSED TREE
This commit is contained in:
parent
26efda25bf
commit
42223df470
@ -8154,7 +8154,7 @@ IonBuilder::getElemTryDense(bool* emitted, MDefinition* obj, MDefinition* index)
|
||||
|
||||
// Don't generate a fast path if there have been bounds check failures
|
||||
// and this access might be on a sparse property.
|
||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj) && failedBoundsCheck_) {
|
||||
if (ElementAccessHasExtraIndexedProperty(this, obj) && failedBoundsCheck_) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return true;
|
||||
}
|
||||
@ -8188,7 +8188,7 @@ IonBuilder::getStaticTypedArrayObject(MDefinition* obj, MDefinition* index)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj)) {
|
||||
if (ElementAccessHasExtraIndexedProperty(this, obj)) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return nullptr;
|
||||
}
|
||||
@ -8536,7 +8536,7 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType
|
||||
// cannot hit another indexed property on the object or its prototypes.
|
||||
bool readOutOfBounds =
|
||||
types->hasType(TypeSet::UndefinedType()) &&
|
||||
!ElementAccessHasExtraIndexedProperty(constraints(), obj);
|
||||
!ElementAccessHasExtraIndexedProperty(this, obj);
|
||||
|
||||
MIRType knownType = MIRType_Value;
|
||||
if (unboxedType == JSVAL_TYPE_MAGIC && barrier == BarrierKind::NoBarrier)
|
||||
@ -9097,7 +9097,7 @@ IonBuilder::setElemTryDense(bool* emitted, MDefinition* object,
|
||||
|
||||
// Don't generate a fast path if there have been bounds check failures
|
||||
// and this access might be on a sparse property.
|
||||
if (ElementAccessHasExtraIndexedProperty(constraints(), object) && failedBoundsCheck_) {
|
||||
if (ElementAccessHasExtraIndexedProperty(this, object) && failedBoundsCheck_) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return true;
|
||||
}
|
||||
@ -9163,7 +9163,7 @@ IonBuilder::setElemTryCache(bool* emitted, MDefinition* object,
|
||||
// from them. If TI can guard that there are no indexed properties on the prototype
|
||||
// chain, we know that we anen't missing any setters by overwriting the hole with
|
||||
// another value.
|
||||
bool guardHoles = ElementAccessHasExtraIndexedProperty(constraints(), object);
|
||||
bool guardHoles = ElementAccessHasExtraIndexedProperty(this, object);
|
||||
|
||||
// Make sure the object being written to doesn't have copy on write elements.
|
||||
const Class* clasp = object->resultTypeSet() ? object->resultTypeSet()->getKnownClass(constraints()) : nullptr;
|
||||
@ -9199,7 +9199,7 @@ IonBuilder::jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion,
|
||||
|
||||
// Writes which are on holes in the object do not have to bail out if they
|
||||
// cannot hit another indexed property on the object or its prototypes.
|
||||
bool writeOutOfBounds = !ElementAccessHasExtraIndexedProperty(constraints(), obj);
|
||||
bool writeOutOfBounds = !ElementAccessHasExtraIndexedProperty(this, obj);
|
||||
|
||||
if (NeedsPostBarrier(info(), value))
|
||||
current->add(MPostWriteBarrier::New(alloc(), obj, value));
|
||||
@ -11068,7 +11068,7 @@ IonBuilder::getPropTryCache(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||
// reflect such possible values.
|
||||
if (barrier != BarrierKind::TypeSet) {
|
||||
BarrierKind protoBarrier =
|
||||
PropertyReadOnPrototypeNeedsTypeBarrier(this, constraints(), obj, name, types);
|
||||
PropertyReadOnPrototypeNeedsTypeBarrier(this, obj, name, types);
|
||||
if (protoBarrier != BarrierKind::NoBarrier) {
|
||||
MOZ_ASSERT(barrier <= protoBarrier);
|
||||
barrier = protoBarrier;
|
||||
@ -12373,7 +12373,7 @@ IonBuilder::jsop_in()
|
||||
break;
|
||||
}
|
||||
|
||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
|
||||
if (ElementAccessHasExtraIndexedProperty(this, obj))
|
||||
break;
|
||||
|
||||
return jsop_in_dense(obj, id, unboxedType);
|
||||
|
@ -649,7 +649,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode)
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
||||
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
@ -791,7 +791,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
||||
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
@ -890,7 +890,7 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo)
|
||||
}
|
||||
|
||||
// Watch out for indexed properties on the prototype.
|
||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
||||
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
@ -1006,7 +1006,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
|
||||
}
|
||||
|
||||
// Watch out for indexed properties on the prototype.
|
||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
||||
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
@ -2127,7 +2127,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo)
|
||||
MDefinition* id = callInfo.getArg(1);
|
||||
MDefinition* value = callInfo.getArg(2);
|
||||
|
||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
|
||||
if (ElementAccessHasExtraIndexedProperty(this, obj))
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
// setElemTryDense will push the value as the result of the define instead
|
||||
|
@ -4884,15 +4884,14 @@ jit::ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefin
|
||||
}
|
||||
|
||||
bool
|
||||
jit::ElementAccessHasExtraIndexedProperty(CompilerConstraintList* constraints,
|
||||
MDefinition* obj)
|
||||
jit::ElementAccessHasExtraIndexedProperty(IonBuilder* builder, MDefinition* obj)
|
||||
{
|
||||
TemporaryTypeSet* types = obj->resultTypeSet();
|
||||
|
||||
if (!types || types->hasObjectFlags(constraints, OBJECT_FLAG_LENGTH_OVERFLOW))
|
||||
if (!types || types->hasObjectFlags(builder->constraints(), OBJECT_FLAG_LENGTH_OVERFLOW))
|
||||
return true;
|
||||
|
||||
return TypeCanHaveExtraIndexedProperties(constraints, types);
|
||||
return TypeCanHaveExtraIndexedProperties(builder, types);
|
||||
}
|
||||
|
||||
MIRType
|
||||
@ -5056,7 +5055,6 @@ jit::PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
||||
|
||||
BarrierKind
|
||||
jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
||||
CompilerConstraintList* constraints,
|
||||
MDefinition* obj, PropertyName* name,
|
||||
TemporaryTypeSet* observed)
|
||||
{
|
||||
@ -5074,13 +5072,14 @@ jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
||||
if (!key)
|
||||
continue;
|
||||
while (true) {
|
||||
if (!key->hasStableClassAndProto(constraints))
|
||||
if (!key->hasStableClassAndProto(builder->constraints()))
|
||||
return BarrierKind::TypeSet;
|
||||
if (!key->proto().isObject())
|
||||
break;
|
||||
JSObject* proto = builder->checkNurseryObject(key->proto().toObject());
|
||||
key = TypeSet::ObjectKey::get(proto);
|
||||
BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, key, name, observed);
|
||||
BarrierKind kind = PropertyReadNeedsTypeBarrier(builder->constraints(),
|
||||
key, name, observed);
|
||||
if (kind == BarrierKind::TypeSet)
|
||||
return BarrierKind::TypeSet;
|
||||
|
||||
@ -5164,6 +5163,58 @@ jit::AddObjectsForPropertyRead(MDefinition* obj, PropertyName* name,
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
PrototypeHasIndexedProperty(IonBuilder* builder, JSObject* obj)
|
||||
{
|
||||
do {
|
||||
TypeSet::ObjectKey* key = TypeSet::ObjectKey::get(builder->checkNurseryObject(obj));
|
||||
if (ClassCanHaveExtraProperties(key->clasp()))
|
||||
return true;
|
||||
if (key->unknownProperties())
|
||||
return true;
|
||||
HeapTypeSetKey index = key->property(JSID_VOID);
|
||||
if (index.nonData(builder->constraints()) || index.isOwnProperty(builder->constraints()))
|
||||
return true;
|
||||
obj = obj->getProto();
|
||||
} while (obj);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Whether Array.prototype, or an object on its proto chain, has an indexed property.
|
||||
bool
|
||||
jit::ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script)
|
||||
{
|
||||
if (JSObject* proto = script->global().maybeGetArrayPrototype())
|
||||
return PrototypeHasIndexedProperty(builder, proto);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Whether obj or any of its prototypes have an indexed property.
|
||||
bool
|
||||
jit::TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types)
|
||||
{
|
||||
const Class* clasp = types->getKnownClass(builder->constraints());
|
||||
|
||||
// Note: typed arrays have indexed properties not accounted for by type
|
||||
// information, though these are all in bounds and will be accounted for
|
||||
// by JIT paths.
|
||||
if (!clasp || (ClassCanHaveExtraProperties(clasp) && !IsAnyTypedArrayClass(clasp)))
|
||||
return true;
|
||||
|
||||
if (types->hasObjectFlags(builder->constraints(), OBJECT_FLAG_SPARSE_INDEXES))
|
||||
return true;
|
||||
|
||||
JSObject* proto;
|
||||
if (!types->getCommonPrototype(builder->constraints(), &proto))
|
||||
return true;
|
||||
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
return PrototypeHasIndexedProperty(builder, proto);
|
||||
}
|
||||
|
||||
static bool
|
||||
PropertyTypeIncludes(TempAllocator& alloc, HeapTypeSetKey property,
|
||||
MDefinition* value, MIRType implicitType)
|
||||
|
@ -13719,8 +13719,7 @@ bool ElementAccessIsAnyTypedArray(CompilerConstraintList* constraints,
|
||||
Scalar::Type* arrayType);
|
||||
bool ElementAccessIsPacked(CompilerConstraintList* constraints, MDefinition* obj);
|
||||
bool ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefinition* obj);
|
||||
bool ElementAccessHasExtraIndexedProperty(CompilerConstraintList* constraints,
|
||||
MDefinition* obj);
|
||||
bool ElementAccessHasExtraIndexedProperty(IonBuilder* builder, MDefinition* obj);
|
||||
MIRType DenseNativeElementType(CompilerConstraintList* constraints, MDefinition* obj);
|
||||
BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
||||
CompilerConstraintList* constraints,
|
||||
@ -13731,7 +13730,6 @@ BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
||||
MDefinition* obj, PropertyName* name,
|
||||
TemporaryTypeSet* observed);
|
||||
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
||||
CompilerConstraintList* constraints,
|
||||
MDefinition* obj, PropertyName* name,
|
||||
TemporaryTypeSet* observed);
|
||||
bool PropertyReadIsIdempotent(CompilerConstraintList* constraints,
|
||||
@ -13745,6 +13743,8 @@ bool PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
|
||||
MBasicBlock* current, MDefinition** pobj,
|
||||
PropertyName* name, MDefinition** pvalue,
|
||||
bool canModify, MIRType implicitType = MIRType_None);
|
||||
bool ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script);
|
||||
bool TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types);
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -2449,57 +2449,6 @@ js::ClassCanHaveExtraProperties(const Class* clasp)
|
||||
|| IsAnyTypedArrayClass(clasp);
|
||||
}
|
||||
|
||||
static bool
|
||||
PrototypeHasIndexedProperty(CompilerConstraintList* constraints, JSObject* obj)
|
||||
{
|
||||
do {
|
||||
TypeSet::ObjectKey* key = TypeSet::ObjectKey::get(obj);
|
||||
if (ClassCanHaveExtraProperties(key->clasp()))
|
||||
return true;
|
||||
if (key->unknownProperties())
|
||||
return true;
|
||||
HeapTypeSetKey index = key->property(JSID_VOID);
|
||||
if (index.nonData(constraints) || index.isOwnProperty(constraints))
|
||||
return true;
|
||||
obj = obj->getProto();
|
||||
} while (obj);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
js::ArrayPrototypeHasIndexedProperty(CompilerConstraintList* constraints, JSScript* script)
|
||||
{
|
||||
if (JSObject* proto = script->global().maybeGetArrayPrototype())
|
||||
return PrototypeHasIndexedProperty(constraints, proto);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::TypeCanHaveExtraIndexedProperties(CompilerConstraintList* constraints,
|
||||
TemporaryTypeSet* types)
|
||||
{
|
||||
const Class* clasp = types->getKnownClass(constraints);
|
||||
|
||||
// Note: typed arrays have indexed properties not accounted for by type
|
||||
// information, though these are all in bounds and will be accounted for
|
||||
// by JIT paths.
|
||||
if (!clasp || (ClassCanHaveExtraProperties(clasp) && !IsAnyTypedArrayClass(clasp)))
|
||||
return true;
|
||||
|
||||
if (types->hasObjectFlags(constraints, OBJECT_FLAG_SPARSE_INDEXES))
|
||||
return true;
|
||||
|
||||
JSObject* proto;
|
||||
if (!types->getCommonPrototype(constraints, &proto))
|
||||
return true;
|
||||
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
return PrototypeHasIndexedProperty(constraints, proto);
|
||||
}
|
||||
|
||||
void
|
||||
TypeZone::processPendingRecompiles(FreeOp* fop, RecompileInfoVector& recompiles)
|
||||
{
|
||||
|
@ -974,17 +974,6 @@ inline bool isInlinableCall(jsbytecode* pc);
|
||||
bool
|
||||
ClassCanHaveExtraProperties(const Class* clasp);
|
||||
|
||||
/*
|
||||
* Whether Array.prototype, or an object on its proto chain, has an
|
||||
* indexed property.
|
||||
*/
|
||||
bool
|
||||
ArrayPrototypeHasIndexedProperty(CompilerConstraintList* constraints, JSScript* script);
|
||||
|
||||
/* Whether obj or any of its prototypes have an indexed property. */
|
||||
bool
|
||||
TypeCanHaveExtraIndexedProperties(CompilerConstraintList* constraints, TemporaryTypeSet* types);
|
||||
|
||||
/* Persistent type information for a script, retained across GCs. */
|
||||
class TypeScript
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user