mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 20:17:37 +00:00
Bug 996422 - Part 1: Make TypeSets work with MIRTypes directly. (r=bhackett)
This commit is contained in:
parent
95a78e55c8
commit
0529a14819
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user