Bug 996422 - Part 1: Make TypeSets work with MIRTypes directly. (r=bhackett)

This commit is contained in:
Shu-yu Guo 2014-04-22 18:23:27 -07:00
parent 95a78e55c8
commit 0529a14819
7 changed files with 118 additions and 103 deletions

View File

@ -477,7 +477,7 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock *entry, jsbytecode *start, jsbytecod
if (js_CodeSpec[*last].format & JOF_TYPESET) {
types::TemporaryTypeSet *typeSet = bytecodeTypes(last);
if (!typeSet->empty()) {
MIRType type = MIRTypeFromValueType(typeSet->getKnownTypeTag());
MIRType type = typeSet->getKnownMIRType();
if (!phi->addBackedgeType(type, typeSet))
return false;
}
@ -889,9 +889,7 @@ IonBuilder::rewriteParameter(uint32_t slotIdx, MDefinition *param, int32_t argIn
JS_ASSERT(param->isParameter() || param->isGetArgumentsObjectArg());
types::TemporaryTypeSet *types = param->resultTypeSet();
JSValueType definiteType = types->getKnownTypeTag();
MDefinition *actual = ensureDefiniteType(param, definiteType);
MDefinition *actual = ensureDefiniteType(param, types->getKnownMIRType());
if (actual == param)
return;
@ -5194,7 +5192,7 @@ ArgumentTypesMatch(MDefinition *def, types::StackTypeSet *calleeTypes)
if (def->type() == MIRType_Object)
return calleeTypes->unknownObject();
return calleeTypes->mightBeType(ValueTypeFromMIRType(def->type()));
return calleeTypes->mightBeMIRType(def->type());
}
bool
@ -5219,7 +5217,7 @@ IonBuilder::testNeedsArgumentCheck(JSFunction *target, CallInfo &callInfo)
return true;
}
for (size_t i = callInfo.argc(); i < target->nargs(); i++) {
if (!types::TypeScript::ArgTypes(targetScript, i)->mightBeType(JSVAL_TYPE_UNDEFINED))
if (!types::TypeScript::ArgTypes(targetScript, i)->mightBeMIRType(MIRType_Undefined))
return true;
}
@ -5320,7 +5318,7 @@ DOMCallNeedsBarrier(const JSJitInfo* jitinfo, types::TemporaryTypeSet *types)
return true;
// No need for a barrier if we're already expecting the type we'll produce.
return jitinfo->returnType() != types->getKnownTypeTag();
return MIRTypeFromValueType(jitinfo->returnType()) != types->getKnownMIRType();
}
bool
@ -5373,8 +5371,8 @@ IonBuilder::jsop_eval(uint32_t argc)
// same. This is not guaranteed if a primitive string/number/etc.
// is passed through to the eval invoke as the primitive may be
// boxed into different objects if accessed via 'this'.
JSValueType type = thisTypes->getKnownTypeTag();
if (type != JSVAL_TYPE_OBJECT && type != JSVAL_TYPE_NULL && type != JSVAL_TYPE_UNDEFINED)
MIRType type = thisTypes->getKnownMIRType();
if (type != MIRType_Object && type != MIRType_Null && type != MIRType_Undefined)
return abort("Direct eval from script with maybe-primitive 'this'");
CallInfo callInfo(alloc(), /* constructing = */ false);
@ -5958,7 +5956,7 @@ IonBuilder::newPendingLoopHeader(MBasicBlock *predecessor, jsbytecode *pc, bool
alloc_->lifoAlloc()->new_<types::TemporaryTypeSet>(existingType);
if (!typeSet)
return nullptr;
MIRType type = MIRTypeFromValueType(typeSet->getKnownTypeTag());
MIRType type = typeSet->getKnownMIRType();
if (!phi->addBackedgeType(type, typeSet))
return nullptr;
}
@ -6259,8 +6257,7 @@ IonBuilder::pushTypeBarrier(MDefinition *def, types::TemporaryTypeSet *observed,
// to that point will explicitly monitor the new type.
if (!needsBarrier) {
JSValueType type = observed->getKnownTypeTag();
MDefinition *replace = ensureDefiniteType(def, type);
MDefinition *replace = ensureDefiniteType(def, observed->getKnownMIRType());
if (replace != def) {
current->pop();
current->push(replace);
@ -6294,7 +6291,7 @@ IonBuilder::pushDOMTypeBarrier(MInstruction *ins, types::TemporaryTypeSet *obser
const JSJitInfo *jitinfo = func->jitInfo();
bool barrier = DOMCallNeedsBarrier(jitinfo, observed);
// Need to be a bit careful: if jitinfo->returnType is JSVAL_TYPE_DOUBLE but
// types->getKnownTypeTag() is JSVAL_TYPE_INT32, then don't unconditionally
// types->getKnownMIRType() is MIRType_Int32, then don't unconditionally
// unbox as a double. Instead, go ahead and barrier on having an int type,
// since we know we need a barrier anyway due to the type mismatch. This is
// the only situation in which TI actually has more information about the
@ -6302,11 +6299,11 @@ IonBuilder::pushDOMTypeBarrier(MInstruction *ins, types::TemporaryTypeSet *obser
// JSVAL_TYPE_UNKNOWN.
MDefinition* replace = ins;
if (jitinfo->returnType() != JSVAL_TYPE_DOUBLE ||
observed->getKnownTypeTag() != JSVAL_TYPE_INT32) {
observed->getKnownMIRType() != MIRType_Int32) {
JS_ASSERT(jitinfo->returnType() == JSVAL_TYPE_UNKNOWN ||
observed->getKnownTypeTag() == JSVAL_TYPE_UNKNOWN ||
jitinfo->returnType() == observed->getKnownTypeTag());
replace = ensureDefiniteType(ins, jitinfo->returnType());
observed->getKnownMIRType() == MIRType_Value ||
MIRTypeFromValueType(jitinfo->returnType()) == observed->getKnownMIRType());
replace = ensureDefiniteType(ins, MIRTypeFromValueType(jitinfo->returnType()));
if (replace != ins) {
current->pop();
current->push(replace);
@ -6319,30 +6316,29 @@ IonBuilder::pushDOMTypeBarrier(MInstruction *ins, types::TemporaryTypeSet *obser
}
MDefinition *
IonBuilder::ensureDefiniteType(MDefinition *def, JSValueType definiteType)
IonBuilder::ensureDefiniteType(MDefinition *def, MIRType definiteType)
{
MInstruction *replace;
switch (definiteType) {
case JSVAL_TYPE_UNDEFINED:
case MIRType_Undefined:
def->setImplicitlyUsedUnchecked();
replace = MConstant::New(alloc(), UndefinedValue());
break;
case JSVAL_TYPE_NULL:
case MIRType_Null:
def->setImplicitlyUsedUnchecked();
replace = MConstant::New(alloc(), NullValue());
break;
case JSVAL_TYPE_UNKNOWN:
case MIRType_Value:
return def;
default: {
MIRType replaceType = MIRTypeFromValueType(definiteType);
if (def->type() != MIRType_Value) {
JS_ASSERT(def->type() == replaceType);
JS_ASSERT(def->type() == definiteType);
return def;
}
replace = MUnbox::New(alloc(), def, replaceType, MUnbox::Infallible);
replace = MUnbox::New(alloc(), def, definiteType, MUnbox::Infallible);
break;
}
}
@ -6359,7 +6355,7 @@ IonBuilder::ensureDefiniteTypeSet(MDefinition *def, types::TemporaryTypeSet *typ
// Use ensureDefiniteType to do unboxing. If that happened the type can
// be added on the newly created unbox operation.
MDefinition *replace = ensureDefiniteType(def, types->getKnownTypeTag());
MDefinition *replace = ensureDefiniteType(def, types->getKnownMIRType());
if (replace != def) {
replace->setResultTypeSet(types);
return replace;
@ -6428,22 +6424,22 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
JSObject *singleton = types->getSingleton();
JSValueType knownType = types->getKnownTypeTag();
MIRType knownType = types->getKnownMIRType();
if (!barrier) {
if (singleton) {
// Try to inline a known constant value.
if (testSingletonProperty(staticObject, name) == singleton)
return pushConstant(ObjectValue(*singleton));
}
if (knownType == JSVAL_TYPE_UNDEFINED)
if (knownType == MIRType_Undefined)
return pushConstant(UndefinedValue());
if (knownType == JSVAL_TYPE_NULL)
if (knownType == MIRType_Null)
return pushConstant(NullValue());
}
MInstruction *obj = constant(ObjectValue(*staticObject));
MIRType rvalType = MIRTypeFromValueType(types->getKnownTypeTag());
MIRType rvalType = types->getKnownMIRType();
if (barrier)
rvalType = MIRType_Value;
@ -6526,9 +6522,9 @@ IonBuilder::setStaticName(JSObject *staticObject, PropertyName *name)
// If the property has a known type, we may be able to optimize typed stores by not
// storing the type tag.
MIRType slotType = MIRType_None;
JSValueType knownType = property.knownTypeTag(constraints());
if (knownType != JSVAL_TYPE_UNKNOWN)
slotType = MIRTypeFromValueType(knownType);
MIRType knownType = property.knownMIRType(constraints());
if (knownType != MIRType_Value)
slotType = knownType;
bool needsBarrier = property.needsBarrier(constraints());
return storeSlot(obj, property.maybeTypes()->definiteSlot(), NumFixedSlots(staticObject),
@ -6593,11 +6589,10 @@ bool
IonBuilder::jsop_intrinsic(PropertyName *name)
{
types::TemporaryTypeSet *types = bytecodeTypes(pc);
JSValueType type = types->getKnownTypeTag();
// If we haven't executed this opcode yet, we need to get the intrinsic
// value and monitor the result.
if (type == JSVAL_TYPE_UNKNOWN) {
if (types->empty()) {
MCallGetIntrinsicValue *ins = MCallGetIntrinsicValue::New(alloc(), name);
current->add(ins);
@ -6632,23 +6627,23 @@ IonBuilder::jsop_bindname(PropertyName *name)
return resumeAfter(ins);
}
static JSValueType
static MIRType
GetElemKnownType(bool needsHoleCheck, types::TemporaryTypeSet *types)
{
JSValueType knownType = types->getKnownTypeTag();
MIRType knownType = types->getKnownMIRType();
// Null and undefined have no payload so they can't be specialized.
// Since folding null/undefined while building SSA is not safe (see the
// comment in IsPhiObservable), we just add an untyped load instruction
// and rely on pushTypeBarrier and DCE to replace it with a null/undefined
// constant.
if (knownType == JSVAL_TYPE_UNDEFINED || knownType == JSVAL_TYPE_NULL)
knownType = JSVAL_TYPE_UNKNOWN;
if (knownType == MIRType_Undefined || knownType == MIRType_Null)
knownType = MIRType_Value;
// Different architectures may want typed element reads which require
// hole checks to be done as either value or typed reads.
if (needsHoleCheck && !LIRGenerator::allowTypedElementHoleCheck())
knownType = JSVAL_TYPE_UNKNOWN;
knownType = MIRType_Value;
return knownType;
}
@ -7237,10 +7232,10 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index)
// Spice up type information.
if (index->type() == MIRType_Int32 && !barrier) {
bool needHoleCheck = !ElementAccessIsPacked(constraints(), obj);
JSValueType knownType = GetElemKnownType(needHoleCheck, types);
MIRType knownType = GetElemKnownType(needHoleCheck, types);
if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
ins->setResultType(MIRTypeFromValueType(knownType));
if (knownType != MIRType_Value && knownType != MIRType_Double)
ins->setResultType(knownType);
}
if (!pushTypeBarrier(ins, types, barrier))
@ -7272,7 +7267,7 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
types->hasType(types::Type::UndefinedType()) &&
!ElementAccessHasExtraIndexedProperty(constraints(), obj);
JSValueType knownType = JSVAL_TYPE_UNKNOWN;
MIRType knownType = MIRType_Value;
if (!barrier)
knownType = GetElemKnownType(needsHoleCheck, types);
@ -7305,7 +7300,7 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
loopDepth_ &&
!readOutOfBounds &&
!needsHoleCheck &&
knownType == JSVAL_TYPE_DOUBLE &&
knownType == MIRType_Double &&
objTypes &&
objTypes->convertDoubleElements(constraints()) == types::TemporaryTypeSet::AlwaysConvertToDoubles;
if (loadDouble)
@ -7332,7 +7327,7 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
// If maybeUndefined was true, the typeset must have undefined, and
// then either additional types or a barrier. This means we should
// never have a typed version of LoadElementHole.
JS_ASSERT(knownType == JSVAL_TYPE_UNKNOWN);
JS_ASSERT(knownType == MIRType_Value);
}
// If the array is being converted to doubles, but we've observed
@ -7353,7 +7348,7 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
// cannot *assume* the result is a double.
if (executionMode == ParallelExecution &&
barrier &&
types->getKnownTypeTag() == JSVAL_TYPE_INT32 &&
types->getKnownMIRType() == MIRType_Int32 &&
objTypes &&
objTypes->convertDoubleElements(constraints()) == types::TemporaryTypeSet::AlwaysConvertToDoubles)
{
@ -7365,8 +7360,8 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
barrier = false; // Don't need a barrier anymore
}
if (knownType != JSVAL_TYPE_UNKNOWN)
load->setResultType(MIRTypeFromValueType(knownType));
if (knownType != MIRType_Value)
load->setResultType(knownType);
current->push(load);
return pushTypeBarrier(load, types, barrier);
@ -8049,7 +8044,7 @@ IonBuilder::jsop_length_fastPath()
{
types::TemporaryTypeSet *types = bytecodeTypes(pc);
if (types->getKnownTypeTag() != JSVAL_TYPE_INT32)
if (types->getKnownMIRType() != MIRType_Int32)
return false;
MDefinition *obj = current->peek(-1);
@ -8739,7 +8734,7 @@ IonBuilder::getPropTryDefiniteSlot(bool *emitted, PropertyName *name,
MLoadFixedSlot *fixed = MLoadFixedSlot::New(alloc(), useObj, property.maybeTypes()->definiteSlot());
if (!barrier)
fixed->setResultType(MIRTypeFromValueType(types->getKnownTypeTag()));
fixed->setResultType(types->getKnownMIRType());
current->add(fixed);
current->push(fixed);
@ -8797,7 +8792,7 @@ IonBuilder::getPropTryCommonGetter(bool *emitted, PropertyName *name,
}
// Don't call the getter with a primitive value.
if (objTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT) {
if (objTypes->getKnownMIRType() != MIRType_Object) {
MGuardObject *guardObj = MGuardObject::New(alloc(), obj);
current->add(guardObj);
obj = guardObj;
@ -8873,7 +8868,7 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, PropertyName *name,
if (shapes.empty() || !CanInlinePropertyOpShapes(shapes))
return true;
MIRType rvalType = MIRTypeFromValueType(types->getKnownTypeTag());
MIRType rvalType = types->getKnownMIRType();
if (barrier || IsNullOrUndefined(rvalType))
rvalType = MIRType_Value;
@ -8975,7 +8970,7 @@ IonBuilder::getPropTryCache(bool *emitted, PropertyName *name,
if (load->isEffectful() && !resumeAfter(load))
return false;
MIRType rvalType = MIRTypeFromValueType(types->getKnownTypeTag());
MIRType rvalType = types->getKnownMIRType();
if (barrier || IsNullOrUndefined(rvalType))
rvalType = MIRType_Value;
load->setResultType(rvalType);
@ -9084,7 +9079,7 @@ IonBuilder::setPropTryCommonSetter(bool *emitted, MDefinition *obj,
return true;
// Don't call the setter with a primitive value.
if (objTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT) {
if (objTypes->getKnownMIRType() != MIRType_Object) {
MGuardObject *guardObj = MGuardObject::New(alloc(), obj);
current->add(guardObj);
obj = guardObj;
@ -9584,7 +9579,7 @@ IonBuilder::jsop_this()
return true;
}
if (thisTypes->getKnownTypeTag() == JSVAL_TYPE_OBJECT ||
if (thisTypes->getKnownMIRType() == MIRType_Object ||
(thisTypes->empty() && baselineFrame_ && baselineFrame_->thisType.isSomeObject()))
{
// This is safe, because if the entry type of |this| is an object, it
@ -10037,7 +10032,7 @@ IonBuilder::typeSetToTypeDescrSet(types::TemporaryTypeSet *types,
TypeDescrSet *out)
{
// Extract TypeDescrSet directly if we can
if (!types || types->getKnownTypeTag() != JSVAL_TYPE_OBJECT)
if (!types || types->getKnownMIRType() != MIRType_Object)
return true;
// And only known objects.

View File

@ -354,7 +354,7 @@ class IonBuilder : public MIRGenerator
// returns def. Otherwise, returns an MInstruction that has that definite
// type, infallibly unboxing ins as needed. The new instruction will be
// added to |current| in this case.
MDefinition *ensureDefiniteType(MDefinition* def, JSValueType definiteType);
MDefinition *ensureDefiniteType(MDefinition* def, MIRType definiteType);
// Creates a MDefinition based on the given def improved with type as TypeSet.
MDefinition *ensureDefiniteTypeSet(MDefinition* def, types::TemporaryTypeSet *types);

View File

@ -202,7 +202,7 @@ MIRType
IonBuilder::getInlineReturnType()
{
types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
return MIRTypeFromValueType(returnTypes->getKnownTypeTag());
return returnTypes->getKnownMIRType();
}
IonBuilder::InliningStatus
@ -1537,7 +1537,7 @@ IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo)
// constructed type objects, so we can only perform the inlining if we
// already have one of these type objects.
types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
if (returnTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT)
if (returnTypes->getKnownMIRType() != MIRType_Object)
return InliningStatus_NotInlined;
if (returnTypes->unknownObject() || returnTypes->getObjectCount() != 1)
return InliningStatus_NotInlined;

View File

@ -1122,7 +1122,7 @@ MPhi::typeIncludes(MDefinition *def)
return types->isSubset(this->resultTypeSet());
if (this->type() == MIRType_Value || types->empty())
return true;
return this->type() == MIRTypeFromValueType(types->getKnownTypeTag());
return this->type() == types->getKnownMIRType();
}
if (def->type() == MIRType_Value) {
@ -3065,7 +3065,7 @@ jit::DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinit
types::HeapTypeSetKey elementTypes = object->property(JSID_VOID);
MIRType type = MIRTypeFromValueType(elementTypes.knownTypeTag(constraints));
MIRType type = elementTypes.knownMIRType(constraints);
if (type == MIRType_None)
return MIRType_None;
@ -3342,7 +3342,7 @@ TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *c
JS_ASSERT(!aggregateProperty.empty());
MIRType propertyType = MIRTypeFromValueType(aggregateProperty.ref().knownTypeTag(constraints));
MIRType propertyType = aggregateProperty.ref().knownMIRType(constraints);
switch (propertyType) {
case MIRType_Boolean:
case MIRType_Int32:

View File

@ -463,7 +463,7 @@ class MDefinition : public MNode
if (MIRType_Value != this->type())
return false;
return !resultTypeSet() || resultTypeSet()->mightBeType(ValueTypeFromMIRType(type));
return !resultTypeSet() || resultTypeSet()->mightBeMIRType(type);
}
// Float32 specialization operations (see big comment in IonAnalysis before the Float32
@ -8988,9 +8988,7 @@ class MFilterTypeSet
: MUnaryInstruction(def)
{
JS_ASSERT(!types->unknown());
MIRType type = MIRTypeFromValueType(types->getKnownTypeTag());
setResultType(type);
setResultType(types->getKnownMIRType());
setResultTypeSet(types);
}
@ -9022,9 +9020,7 @@ class MTypeBarrier
: MUnaryInstruction(def)
{
JS_ASSERT(!types->unknown());
MIRType type = MIRTypeFromValueType(types->getKnownTypeTag());
setResultType(type);
setResultType(types->getKnownMIRType());
setResultTypeSet(types);
setGuard();
@ -9057,7 +9053,7 @@ class MTypeBarrier
bool alwaysBails() const {
// If mirtype of input doesn't agree with mirtype of barrier,
// we will definitely bail.
MIRType type = MIRTypeFromValueType(resultTypeSet()->getKnownTypeTag());
MIRType type = resultTypeSet()->getKnownMIRType();
if (type == MIRType_Value)
return false;
if (input()->type() == MIRType_Value)

View File

@ -310,16 +310,39 @@ TemporaryTypeSet::TemporaryTypeSet(Type type)
}
}
static inline TypeFlags
PrimitiveMIRType(jit::MIRType type)
{
switch (type) {
case jit::MIRType_Undefined:
return TYPE_FLAG_UNDEFINED;
case jit::MIRType_Null:
return TYPE_FLAG_NULL;
case jit::MIRType_Boolean:
return TYPE_FLAG_BOOLEAN;
case jit::MIRType_Int32:
return TYPE_FLAG_INT32;
case jit::MIRType_Double:
return TYPE_FLAG_DOUBLE;
case jit::MIRType_String:
return TYPE_FLAG_STRING;
case jit::MIRType_Magic:
return TYPE_FLAG_LAZYARGS;
default:
MOZ_ASSUME_UNREACHABLE("Bad MIR type");
}
}
bool
TypeSet::mightBeType(JSValueType type)
TypeSet::mightBeMIRType(jit::MIRType type)
{
if (unknown())
return true;
if (type == JSVAL_TYPE_OBJECT)
if (type == jit::MIRType_Object)
return unknownObject() || baseObjectCount() != 0;
return baseFlags() & PrimitiveTypeFlag(type);
return baseFlags() & PrimitiveMIRType(type);
}
bool
@ -1142,41 +1165,41 @@ HeapTypeSetKey::freeze(CompilerConstraintList *constraints)
constraints->add(alloc->new_<T>(alloc, *this, ConstraintDataFreeze()));
}
static inline JSValueType
GetValueTypeFromTypeFlags(TypeFlags flags)
static inline jit::MIRType
GetMIRTypeFromTypeFlags(TypeFlags flags)
{
switch (flags) {
case TYPE_FLAG_UNDEFINED:
return JSVAL_TYPE_UNDEFINED;
return jit::MIRType_Undefined;
case TYPE_FLAG_NULL:
return JSVAL_TYPE_NULL;
return jit::MIRType_Null;
case TYPE_FLAG_BOOLEAN:
return JSVAL_TYPE_BOOLEAN;
return jit::MIRType_Boolean;
case TYPE_FLAG_INT32:
return JSVAL_TYPE_INT32;
return jit::MIRType_Int32;
case (TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE):
return JSVAL_TYPE_DOUBLE;
return jit::MIRType_Double;
case TYPE_FLAG_STRING:
return JSVAL_TYPE_STRING;
return jit::MIRType_String;
case TYPE_FLAG_LAZYARGS:
return JSVAL_TYPE_MAGIC;
return jit::MIRType_Magic;
case TYPE_FLAG_ANYOBJECT:
return JSVAL_TYPE_OBJECT;
return jit::MIRType_Object;
default:
return JSVAL_TYPE_UNKNOWN;
return jit::MIRType_Value;
}
}
JSValueType
TemporaryTypeSet::getKnownTypeTag()
jit::MIRType
TemporaryTypeSet::getKnownMIRType()
{
TypeFlags flags = baseFlags();
JSValueType type;
jit::MIRType type;
if (baseObjectCount())
type = flags ? JSVAL_TYPE_UNKNOWN : JSVAL_TYPE_OBJECT;
type = flags ? jit::MIRType_Value : jit::MIRType_Object;
else
type = GetValueTypeFromTypeFlags(flags);
type = GetMIRTypeFromTypeFlags(flags);
/*
* If the type set is totally empty then it will be treated as unknown,
@ -1186,28 +1209,28 @@ TemporaryTypeSet::getKnownTypeTag()
* added to the set.
*/
DebugOnly<bool> empty = flags == 0 && baseObjectCount() == 0;
JS_ASSERT_IF(empty, type == JSVAL_TYPE_UNKNOWN);
JS_ASSERT_IF(empty, type == jit::MIRType_Value);
return type;
}
JSValueType
HeapTypeSetKey::knownTypeTag(CompilerConstraintList *constraints)
jit::MIRType
HeapTypeSetKey::knownMIRType(CompilerConstraintList *constraints)
{
TypeSet *types = maybeTypes();
if (!types || types->unknown())
return JSVAL_TYPE_UNKNOWN;
return jit::MIRType_Value;
TypeFlags flags = types->baseFlags() & ~TYPE_FLAG_ANYOBJECT;
JSValueType type;
jit::MIRType type;
if (types->unknownObject() || types->getObjectCount())
type = flags ? JSVAL_TYPE_UNKNOWN : JSVAL_TYPE_OBJECT;
type = flags ? jit::MIRType_Value : jit::MIRType_Object;
else
type = GetValueTypeFromTypeFlags(flags);
type = GetMIRTypeFromTypeFlags(flags);
if (type != JSVAL_TYPE_UNKNOWN)
if (type != jit::MIRType_Value)
freeze(constraints);
/*
@ -1217,7 +1240,7 @@ HeapTypeSetKey::knownTypeTag(CompilerConstraintList *constraints)
* that the exact tag is unknown, as it will stay unknown as more types are
* added to the set.
*/
JS_ASSERT_IF(types->empty(), type == JSVAL_TYPE_UNKNOWN);
JS_ASSERT_IF(types->empty(), type == jit::MIRType_Value);
return type;
}
@ -1671,7 +1694,7 @@ TemporaryTypeSet::convertDoubleElements(CompilerConstraintList *constraints)
// Only bother with converting known packed arrays whose possible
// element types are int or double. Other arrays require type tests
// when elements are accessed regardless of the conversion.
if (property.knownTypeTag(constraints) == JSVAL_TYPE_DOUBLE &&
if (property.knownMIRType(constraints) == jit::MIRType_Double &&
!type->hasFlags(constraints, OBJECT_FLAG_NON_PACKED))
{
maybeConvert = true;

View File

@ -20,6 +20,7 @@
#include "ds/LifoAlloc.h"
#include "gc/Barrier.h"
#include "gc/Marking.h"
#include "jit/IonTypes.h"
#include "js/Utility.h"
#include "js/Vector.h"
@ -562,7 +563,7 @@ class TypeSet
}
/* Whether any values in this set might have the specified type. */
bool mightBeType(JSValueType type);
bool mightBeMIRType(jit::MIRType type);
/*
* Get whether this type set is known to be a subset of other.
@ -654,9 +655,9 @@ class TemporaryTypeSet : public TypeSet
*/
/* Get any type tag which all values in this set must have. */
JSValueType getKnownTypeTag();
jit::MIRType getKnownMIRType();
bool isMagicArguments() { return getKnownTypeTag() == JSVAL_TYPE_MAGIC; }
bool isMagicArguments() { return getKnownMIRType() == jit::MIRType_Magic; }
/* Whether this value may be an object. */
bool maybeObject() { return unknownObject() || baseObjectCount() > 0; }
@ -1403,7 +1404,7 @@ class HeapTypeSetKey
bool instantiate(JSContext *cx);
void freeze(CompilerConstraintList *constraints);
JSValueType knownTypeTag(CompilerConstraintList *constraints);
jit::MIRType knownMIRType(CompilerConstraintList *constraints);
bool nonData(CompilerConstraintList *constraints);
bool nonWritable(CompilerConstraintList *constraints);
bool isOwnProperty(CompilerConstraintList *constraints);