Bug 994016: TI: add removeSet, r=bhackett

This commit is contained in:
Hannes Verschore 2015-02-28 01:30:40 +01:00
parent e0318ff480
commit f127277ecc
3 changed files with 44 additions and 19 deletions

View File

@ -3470,8 +3470,14 @@ IonBuilder::improveTypesAtCompare(MCompare *ins, bool trueBranch, MTest *test)
// Decide if we need to filter the type or set it.
if ((op == JSOP_STRICTEQ || op == JSOP_EQ) ^ trueBranch) {
// Filter undefined/null
type = subject->resultTypeSet()->filter(alloc_->lifoAlloc(), altersUndefined,
altersNull);
uint32_t flags = 0;
if (altersUndefined)
flags |= types::TYPE_FLAG_UNDEFINED;
if (altersNull)
flags |= types::TYPE_FLAG_NULL;
types::TemporaryTypeSet remove(flags, static_cast<types::TypeSetObjectKey**>(nullptr));
type = types::TypeSet::removeSet(subject->resultTypeSet(), &remove, alloc_->lifoAlloc());
} else {
// Set undefined/null.
uint32_t flags = 0;
@ -3594,7 +3600,9 @@ IonBuilder::improveTypesAtTest(MDefinition *ins, bool trueBranch, MTest *test)
{
return true;
}
type = oldType->filter(alloc_->lifoAlloc(), true, true);
uint32_t flags = types::TYPE_FLAG_UNDEFINED | types::TYPE_FLAG_NULL;
types::TemporaryTypeSet remove(flags, static_cast<types::TypeSetObjectKey**>(nullptr));
type = types::TypeSet::removeSet(oldType, &remove, alloc_->lifoAlloc());
} else {
// According to the standards, we cannot filter out: Strings,
// Int32, Double, Booleans, Objects (if they emulate undefined)

View File

@ -716,22 +716,6 @@ TypeSet::clone(LifoAlloc *alloc) const
return res;
}
TemporaryTypeSet *
TypeSet::filter(LifoAlloc *alloc, bool filterUndefined, bool filterNull) const
{
TemporaryTypeSet *res = clone(alloc);
if (!res)
return nullptr;
if (filterUndefined)
res->flags = res->flags & ~TYPE_FLAG_UNDEFINED;
if (filterNull)
res->flags = res->flags & ~TYPE_FLAG_NULL;
return res;
}
TemporaryTypeSet *
TypeSet::cloneObjectsOnly(LifoAlloc *alloc)
{
@ -778,6 +762,33 @@ TypeSet::unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc)
return res;
}
/* static */ TemporaryTypeSet *
TypeSet::removeSet(TemporaryTypeSet *input, TemporaryTypeSet *removal, LifoAlloc *alloc)
{
// Only allow removal of primitives and the "AnyObject" flag.
MOZ_ASSERT(!removal->unknown());
MOZ_ASSERT_IF(!removal->unknownObject(), removal->getObjectCount() == 0);
uint32_t flags = input->baseFlags() & ~removal->baseFlags();
TemporaryTypeSet *res =
alloc->new_<TemporaryTypeSet>(flags, static_cast<TypeSetObjectKey**>(nullptr));
if (!res)
return nullptr;
res->setBaseObjectCount(0);
if (removal->unknownObject() || input->unknownObject())
return res;
for (size_t i = 0; i < input->getObjectCount(); i++) {
if (!input->getObject(i))
continue;
res->addType(Type::ObjectType(input->getObject(i)), alloc);
}
return res;
}
/* static */ TemporaryTypeSet *
TypeSet::intersectSets(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *alloc)
{

View File

@ -426,6 +426,12 @@ class TypeSet
static TemporaryTypeSet *unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc);
/* Return the intersection of the 2 TypeSets. The result should not be modified further */
static TemporaryTypeSet *intersectSets(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *alloc);
/*
* Returns a copy of TypeSet a excluding/removing the types in TypeSet b.
* TypeSet b can only contain primitives or be any object. No support for
* specific objects. The result should not be modified further.
*/
static TemporaryTypeSet *removeSet(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *alloc);
/* Add a type to this set using the specified allocator. */
void addType(Type type, LifoAlloc *alloc);