Bug 1075967 - Inline ToInteger, if TypeSet contains multiple optimizable types. r=h4writer
authorJohannes Schulte <j_schulte@outlook.com>
Tue, 30 Sep 2014 21:21:44 +0200
changeset 232137 a799b8e48161c3ac3f11cece3036747dc5f23960
parent 232136 264cf0a35e48aa02936aca5dac807970bdb0f905
child 232138 5f13639d2f126da7e774723b94f537ce30529f11
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersh4writer
bugs1075967
milestone35.0a1
Bug 1075967 - Inline ToInteger, if TypeSet contains multiple optimizable types. r=h4writer
js/src/jit/IonTypes.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.h
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -528,16 +528,26 @@ IsNullOrUndefined(MIRType type)
 }
 
 static inline bool
 IsSimdType(MIRType type)
 {
     return type == MIRType_Int32x4 || type == MIRType_Float32x4;
 };
 
+static inline bool
+IsMagicType(MIRType type)
+{
+    return type == MIRType_MagicHole ||
+           type == MIRType_MagicOptimizedOut ||
+           type == MIRType_MagicIsConstructing ||
+           type == MIRType_MagicOptimizedArguments ||
+           type == MIRType_MagicUninitializedLexical;
+}
+
 // Returns the number of vector elements (hereby called "length") for a given
 // SIMD kind. It is the Y part of the name "Foo x Y".
 static inline unsigned
 SimdTypeToLength(MIRType type)
 {
     MOZ_ASSERT(IsSimdType(type));
     switch (type) {
       case MIRType_Int32x4:
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -2068,21 +2068,30 @@ IonBuilder::inlineToObject(CallInfo &cal
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineToInteger(CallInfo &callInfo)
 {
     if (callInfo.argc() != 1 || callInfo.constructing())
         return InliningStatus_NotInlined;
 
-    MIRType type = callInfo.getArg(0)->type();
+    MDefinition *input = callInfo.getArg(0);
 
-    // Only optimize cases where input is number, null, or boolean
-    if (!IsNumberType(type) && type != MIRType_Null && type != MIRType_Boolean)
+    // Only optimize cases where input contains only number, null or boolean
+    if (input->mightBeType(MIRType_Object) ||
+        input->mightBeType(MIRType_String) ||
+        input->mightBeType(MIRType_Symbol) ||
+        input->mightBeType(MIRType_Undefined) ||
+        input->mightBeMagicType())
+    {
         return InliningStatus_NotInlined;
+    }
+
+    MOZ_ASSERT(input->type() == MIRType_Value || input->type() == MIRType_Null ||
+               input->type() == MIRType_Boolean || IsNumberType(input->type()));
 
     // Only optimize cases where output is int32
     if (getInlineReturnType() != MIRType_Int32)
         return InliningStatus_NotInlined;
 
     callInfo.setImplicitlyUsedUnchecked();
 
     MToInt32 *toInt32 = MToInt32::New(alloc(), callInfo.getArg(0));
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -591,16 +591,26 @@ class MDefinition : public MNode
             return true;
 
         if (MIRType_Value != this->type())
             return false;
 
         return !resultTypeSet() || resultTypeSet()->mightBeMIRType(type);
     }
 
+    bool mightBeMagicType() const {
+        if (IsMagicType(type()))
+            return true;
+
+        if (MIRType_Value != type())
+            return false;
+
+        return !resultTypeSet() || resultTypeSet()->hasType(types::Type::MagicArgType());
+    }
+
     // Float32 specialization operations (see big comment in IonAnalysis before the Float32
     // specialization algorithm).
     virtual bool isFloat32Commutative() const { return false; }
     virtual bool canProduceFloat32() const { return false; }
     virtual bool canConsumeFloat32(MUse *use) const { return false; }
     virtual void trySpecializeFloat32(TempAllocator &alloc) {}
 #ifdef DEBUG
     // Used during the pass that checks that Float32 flow into valid MDefinitions