Bug 1341263 - Optimize null/undefined comparisons more in CompareIC. r=jandem
authorTom Schuster <evilpies@gmail.com>
Fri, 03 Mar 2017 16:12:40 +0100
changeset 374846 0a00935f57effe6981a62c6e2db989f2f15fad6d
parent 374845 e090bd2b732cfb91b4b84ac7803a2e3160ef0615
child 374847 bcf89da3a9c0b30fbcec4a3ac7c8e1ba7fa8c7cd
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1341263
milestone54.0a1
Bug 1341263 - Optimize null/undefined comparisons more in CompareIC. r=jandem
js/src/jit/SharedIC.cpp
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -1552,23 +1552,20 @@ DoCompareFallback(JSContext* cx, void* p
             ICStub* objectStub = compiler.getStub(compiler.getStubSpace(info.outerScript(cx)));
             if (!objectStub)
                 return false;
 
             stub->addNewStub(objectStub);
             return true;
         }
 
-        if ((lhs.isObject() || lhs.isNull() || lhs.isUndefined()) &&
-            (rhs.isObject() || rhs.isNull() || rhs.isUndefined()) &&
-            !stub->hasStub(ICStub::Compare_ObjectWithUndefined))
-        {
-            JitSpew(JitSpew_BaselineIC, "  Generating %s(Obj/Null/Undef, Obj/Null/Undef) stub",
+        if (lhs.isNullOrUndefined() || rhs.isNullOrUndefined()) {
+            JitSpew(JitSpew_BaselineIC, "  Generating %s(Null/Undef or X, Null/Undef or X) stub",
                     CodeName[op]);
-            bool lhsIsUndefined = lhs.isNull() || lhs.isUndefined();
+            bool lhsIsUndefined = lhs.isNullOrUndefined();
             bool compareWithNull = lhs.isNull() || rhs.isNull();
             ICCompare_ObjectWithUndefined::Compiler compiler(cx, op, engine,
                                                              lhsIsUndefined, compareWithNull);
             ICStub* objectStub = compiler.getStub(compiler.getStubSpace(info.outerScript(cx)));
             if (!objectStub)
                 return false;
 
             stub->addNewStub(objectStub);
@@ -1805,24 +1802,41 @@ ICCompare_ObjectWithUndefined::Compiler:
         masm.bind(&emulatesUndefined);
         masm.moveValue(BooleanValue(op == JSOP_EQ), R0);
         EmitReturnFromIC(masm);
     }
 
     masm.bind(&notObject);
 
     // Also support null == null or undefined == undefined comparisons.
+    Label differentTypes;
     if (compareWithNull)
-        masm.branchTestNull(Assembler::NotEqual, objectOperand, &failure);
+        masm.branchTestNull(Assembler::NotEqual, objectOperand, &differentTypes);
     else
-        masm.branchTestUndefined(Assembler::NotEqual, objectOperand, &failure);
+        masm.branchTestUndefined(Assembler::NotEqual, objectOperand, &differentTypes);
 
     masm.moveValue(BooleanValue(op == JSOP_STRICTEQ || op == JSOP_EQ), R0);
     EmitReturnFromIC(masm);
 
+    masm.bind(&differentTypes);
+    // Also support null == undefined or undefined == null.
+    Label neverEqual;
+    if (compareWithNull)
+        masm.branchTestUndefined(Assembler::NotEqual, objectOperand, &neverEqual);
+    else
+        masm.branchTestNull(Assembler::NotEqual, objectOperand, &neverEqual);
+
+    masm.moveValue(BooleanValue(op == JSOP_EQ || op == JSOP_STRICTNE), R0);
+    EmitReturnFromIC(masm);
+
+    // null/undefined can only be equal to null/undefined or emulatesUndefined.
+    masm.bind(&neverEqual);
+    masm.moveValue(BooleanValue(op == JSOP_NE || op == JSOP_STRICTNE), R0);
+    EmitReturnFromIC(masm);
+
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
 //
 // Compare_Int32WithBoolean