Bug 1038839 - Use type information for alias analysis. r=jandem

This commit is contained in:
Sean Stangl 2015-03-10 14:56:13 -07:00
Родитель 78ab87250d
Коммит 85a0952972
4 изменённых файлов: 113 добавлений и 0 удалений

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

@ -4124,6 +4124,97 @@ MLoadElement::foldsTo(TempAllocator &alloc)
return foldsToStoredValue(alloc, store->value());
}
// Gets the MDefinition* representing the source/target object's storage.
// Usually this is just an MElements*, but sometimes there are layers
// of indirection or inlining, which are handled elsewhere.
static inline const MElements *
MaybeUnwrapElements(const MDefinition *elementsOrObj)
{
// Sometimes there is a level of indirection for conversion.
if (elementsOrObj->isConvertElementsToDoubles())
return MaybeUnwrapElements(elementsOrObj->toConvertElementsToDoubles()->elements());
// For inline elements, the object may be passed directly, for example as MUnbox.
if (elementsOrObj->type() == MIRType_Object)
return nullptr;
return elementsOrObj->toElements();
}
// Gets the MDefinition of the target Object for the given store operation.
static inline const MDefinition *
GetStoreObject(const MDefinition *store)
{
switch (store->op()) {
case MDefinition::Op_StoreElement: {
const MDefinition *elementsOrObj = store->toStoreElement()->elements();
const MDefinition *elements = MaybeUnwrapElements(elementsOrObj);
if (elements)
return elements->toElements()->input();
MOZ_ASSERT(elementsOrObj->type() == MIRType_Object);
return elementsOrObj;
}
case MDefinition::Op_StoreElementHole:
return store->toStoreElementHole()->object();
default:
return nullptr;
}
}
// Implements mightAlias() logic common to all load operations.
static bool
GenericLoadMightAlias(const MDefinition *elementsOrObj, const MDefinition *store)
{
const MElements *elements = MaybeUnwrapElements(elementsOrObj);
if (elements)
return elements->mightAlias(store);
// If MElements couldn't be extracted, then storage must be inline.
// Refer to IsValidElementsType().
const MDefinition *object = elementsOrObj;
MOZ_ASSERT(object->type() == MIRType_Object);
if (!object->resultTypeSet())
return true;
const MDefinition *storeObject = GetStoreObject(store);
if (!storeObject)
return true;
if (!storeObject->resultTypeSet())
return true;
return object->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet());
}
bool
MElements::mightAlias(const MDefinition *store) const
{
if (!input()->resultTypeSet())
return true;
const MDefinition *storeObj = GetStoreObject(store);
if (!storeObj)
return true;
if (!storeObj->resultTypeSet())
return true;
return input()->resultTypeSet()->objectsIntersect(storeObj->resultTypeSet());
}
bool
MLoadElement::mightAlias(const MDefinition *store) const
{
return GenericLoadMightAlias(elements(), store);
}
bool
MInitializedLength::mightAlias(const MDefinition *store) const
{
return GenericLoadMightAlias(elements(), store);
}
bool
MGuardReceiverPolymorphic::congruentTo(const MDefinition *ins) const
{

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

@ -7494,6 +7494,7 @@ class MElements
AliasSet getAliasSet() const MOZ_OVERRIDE {
return AliasSet::Load(AliasSet::ObjectFields);
}
bool mightAlias(const MDefinition *store) const;
ALLOW_CLONE(MElements)
};
@ -7681,6 +7682,7 @@ class MInitializedLength
AliasSet getAliasSet() const MOZ_OVERRIDE {
return AliasSet::Load(AliasSet::ObjectFields);
}
bool mightAlias(const MDefinition *store) const;
void computeRange(TempAllocator &alloc) MOZ_OVERRIDE;
@ -8184,6 +8186,7 @@ class MLoadElement
AliasSet getAliasSet() const MOZ_OVERRIDE {
return AliasSet::Load(AliasSet::Element);
}
bool mightAlias(const MDefinition *store) const;
ALLOW_CLONE(MLoadElement)
};

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

@ -419,6 +419,23 @@ TypeSet::isSubset(const TypeSet *other) const
return true;
}
bool
TypeSet::objectsIntersect(const TypeSet *other) const
{
if (unknownObject() || other->unknownObject())
return true;
for (unsigned i = 0; i < getObjectCount(); i++) {
ObjectKey *key = getObject(i);
if (!key)
continue;
if (other->hasType(ObjectType(key)))
return true;
}
return false;
}
template <class TypeListT>
bool
TypeSet::enumerateTypes(TypeListT *list) const

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

@ -492,6 +492,8 @@ class TypeSet
return this->isSubset(other) && other->isSubset(this);
}
bool objectsIntersect(const TypeSet *other) const;
/* Forward all types in this set to the specified constraint. */
bool addTypesToConstraint(JSContext *cx, TypeConstraint *constraint);