From 0529a14819df4b1aedc398ab970b7cc7a56f56e8 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Tue, 22 Apr 2014 18:23:27 -0700 Subject: [PATCH] Bug 996422 - Part 1: Make TypeSets work with MIRTypes directly. (r=bhackett) --- js/src/jit/IonBuilder.cpp | 107 +++++++++++++++++------------------ js/src/jit/IonBuilder.h | 2 +- js/src/jit/MCallOptimize.cpp | 4 +- js/src/jit/MIR.cpp | 6 +- js/src/jit/MIR.h | 12 ++-- js/src/jsinfer.cpp | 81 ++++++++++++++++---------- js/src/jsinfer.h | 9 +-- 7 files changed, 118 insertions(+), 103 deletions(-) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index b20cfde5b233..066c05053da7 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -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_(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. diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 034bdf6be733..92a713bad3b6 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -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); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index cb1a5ca2f994..b38b5ed4a996 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -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; diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 83ca26926e53..bdd686a19b97 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -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: diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 056b9488c5c7..37247ce763cc 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -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) diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 4e6efeb87c92..3c1a0dbe066d 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -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_(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 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; diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index f4ab6c85a269..2ca3d5f2eab7 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -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);