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 345904 0a00935f57effe6981a62c6e2db989f2f15fad6d
parent 345903 e090bd2b732cfb91b4b84ac7803a2e3160ef0615
child 345905 bcf89da3a9c0b30fbcec4a3ac7c8e1ba7fa8c7cd
push id38337
push userkwierso@gmail.com
push dateSat, 04 Mar 2017 01:30:14 +0000
treeherderautoland@b691557cb7a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1341263
milestone54.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 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