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 id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1075967
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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