Title: [199792] trunk/Source/_javascript_Core
Revision
199792
Author
commit-qu...@webkit.org
Date
2016-04-20 15:24:32 -0700 (Wed, 20 Apr 2016)

Log Message

[JSC] Add register reuse for ArithAdd of an Int32 and constant in DFG
https://bugs.webkit.org/show_bug.cgi?id=155164

Patch by Benjamin Poulain <bpoul...@apple.com> on 2016-04-20
Reviewed by Mark Lam.

Every "inc" in loop was looking like this:
    move rX, rY
    inc rY
    jo 0x230f4a200580

This patch add register Reuse to that case to remove
the extra "move".

* dfg/DFGOSRExit.h:
(JSC::DFG::SpeculationRecovery::SpeculationRecovery):
(JSC::DFG::SpeculationRecovery::immediate):
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithAdd):
* tests/stress/arith-add-with-constant-overflow.js: Added.
(opaqueAdd):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (199791 => 199792)


--- trunk/Source/_javascript_Core/ChangeLog	2016-04-20 22:03:09 UTC (rev 199791)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-04-20 22:24:32 UTC (rev 199792)
@@ -1,3 +1,30 @@
+2016-04-20  Benjamin Poulain  <bpoul...@apple.com>
+
+        [JSC] Add register reuse for ArithAdd of an Int32 and constant in DFG
+        https://bugs.webkit.org/show_bug.cgi?id=155164
+
+        Reviewed by Mark Lam.
+
+        Every "inc" in loop was looking like this:
+            move rX, rY
+            inc rY
+            jo 0x230f4a200580
+
+        This patch add register Reuse to that case to remove
+        the extra "move".
+
+        * dfg/DFGOSRExit.h:
+        (JSC::DFG::SpeculationRecovery::SpeculationRecovery):
+        (JSC::DFG::SpeculationRecovery::immediate):
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithAdd):
+        * tests/stress/arith-add-with-constant-overflow.js: Added.
+        (opaqueAdd):
+
 2016-04-20  Saam barati  <sbar...@apple.com>
 
         We don't need a manual stack for an RAII object when the machine's stack will do just fine

Modified: trunk/Source/_javascript_Core/assembler/MacroAssembler.h (199791 => 199792)


--- trunk/Source/_javascript_Core/assembler/MacroAssembler.h	2016-04-20 22:03:09 UTC (rev 199791)
+++ trunk/Source/_javascript_Core/assembler/MacroAssembler.h	2016-04-20 22:24:32 UTC (rev 199792)
@@ -1694,16 +1694,20 @@
 
     Jump branchAdd32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest)
     {
-        if (src == dest)
-            ASSERT(haveScratchRegisterForBlinding());
-
         if (shouldBlind(imm)) {
-            if (src == dest) {
-                move(src, scratchRegisterForBlinding());
-                src = ""
+            if (src != dest || haveScratchRegisterForBlinding()) {
+                if (src == dest) {
+                    move(src, scratchRegisterForBlinding());
+                    src = ""
+                }
+                loadXorBlindedConstant(xorBlindConstant(imm), dest);
+                return branchAdd32(cond, src, dest);
             }
-            loadXorBlindedConstant(xorBlindConstant(imm), dest);
-            return branchAdd32(cond, src, dest);  
+            // If we don't have a scratch register available for use, we'll just
+            // place a random number of nops.
+            uint32_t nopCount = random() & 3;
+            while (nopCount--)
+                nop();
         }
         return branchAdd32(cond, src, imm.asTrustedImm32(), dest);            
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.h (199791 => 199792)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.h	2016-04-20 22:03:09 UTC (rev 199791)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.h	2016-04-20 22:24:32 UTC (rev 199792)
@@ -48,8 +48,9 @@
 
 // This enum describes the types of additional recovery that
 // may need be performed should a speculation check fail.
-enum SpeculationRecoveryType {
+enum SpeculationRecoveryType : uint8_t {
     SpeculativeAdd,
+    SpeculativeAddImmediate,
     BooleanSpeculationCheck
 };
 
@@ -60,22 +61,36 @@
 class SpeculationRecovery {
 public:
     SpeculationRecovery(SpeculationRecoveryType type, GPRReg dest, GPRReg src)
-        : m_type(type)
+        : m_src(src)
         , m_dest(dest)
-        , m_src(src)
+        , m_type(type)
     {
+        ASSERT(m_type == SpeculativeAdd || m_type == BooleanSpeculationCheck);
     }
 
+    SpeculationRecovery(SpeculationRecoveryType type, GPRReg dest, int32_t immediate)
+        : m_immediate(immediate)
+        , m_dest(dest)
+        , m_type(type)
+    {
+        ASSERT(m_type == SpeculativeAddImmediate);
+    }
+
     SpeculationRecoveryType type() { return m_type; }
     GPRReg dest() { return m_dest; }
     GPRReg src() { return m_src; }
+    int32_t immediate() { return m_immediate; }
 
 private:
+    // different recovery types may required different additional information here.
+    union {
+        GPRReg m_src;
+        int32_t m_immediate;
+    };
+    GPRReg m_dest;
+
     // Indicates the type of additional recovery to be performed.
     SpeculationRecoveryType m_type;
-    // different recovery types may required different additional information here.
-    GPRReg m_dest;
-    GPRReg m_src;
 };
 
 // === OSRExit ===

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp (199791 => 199792)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp	2016-04-20 22:03:09 UTC (rev 199791)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp	2016-04-20 22:24:32 UTC (rev 199792)
@@ -56,6 +56,10 @@
         case SpeculativeAdd:
             m_jit.sub32(recovery->src(), recovery->dest());
             break;
+
+        case SpeculativeAddImmediate:
+            m_jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());
+            break;
             
         case BooleanSpeculationCheck:
             break;

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp (199791 => 199792)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp	2016-04-20 22:03:09 UTC (rev 199791)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp	2016-04-20 22:24:32 UTC (rev 199792)
@@ -61,6 +61,11 @@
             m_jit.sub32(recovery->src(), recovery->dest());
             m_jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());
             break;
+
+        case SpeculativeAddImmediate:
+            m_jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());
+            m_jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());
+            break;
             
         case BooleanSpeculationCheck:
             m_jit.xor64(AssemblyHelpers::TrustedImm32(static_cast<int32_t>(ValueFalse)), recovery->dest());

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (199791 => 199792)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2016-04-20 22:03:09 UTC (rev 199791)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2016-04-20 22:24:32 UTC (rev 199792)
@@ -3496,19 +3496,26 @@
 
         if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
+            GPRTemporary result(this, Reuse, op1);
+
+            GPRReg gpr1 = op1.gpr();
             int32_t imm2 = node->child2()->asInt32();
+            GPRReg gprResult = result.gpr();
 
             if (!shouldCheckOverflow(node->arithMode())) {
-                GPRTemporary result(this, Reuse, op1);
-                m_jit.add32(Imm32(imm2), op1.gpr(), result.gpr());
-                int32Result(result.gpr(), node);
+                m_jit.add32(Imm32(imm2), gpr1, gprResult);
+                int32Result(gprResult, node);
                 return;
             }
 
-            GPRTemporary result(this);
-            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
+            MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, Imm32(imm2), gprResult);
+            if (gpr1 == gprResult) {
+                speculationCheck(Overflow, JSValueRegs(), 0, check,
+                    SpeculationRecovery(SpeculativeAddImmediate, gpr1, imm2));
+            } else
+                speculationCheck(Overflow, JSValueRegs(), 0, check);
 
-            int32Result(result.gpr(), node);
+            int32Result(gprResult, node);
             return;
         }
                 

Added: trunk/Source/_javascript_Core/tests/stress/arith-add-with-constant-overflow.js (0 => 199792)


--- trunk/Source/_javascript_Core/tests/stress/arith-add-with-constant-overflow.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/arith-add-with-constant-overflow.js	2016-04-20 22:24:32 UTC (rev 199792)
@@ -0,0 +1,21 @@
+function opaqueAdd(a)
+{
+    return a + 42;
+}
+noInline(opaqueAdd);
+
+// Warm up.
+for (let i = 0; i < 1e4; ++i) {
+    let result = opaqueAdd(5);
+    if (result !== 47)
+        throw "Invalid opaqueAdd(5) at i = " + i;
+}
+
+// Overflow.
+for (let i = 0; i < 1e3; ++i) {
+    for (let j = -50; j < 50; ++j) {
+        let result = opaqueAdd(2147483647 + j);
+        if (result !== 2147483689 + j)
+            throw "Invalid opaqueAdd(" + 2147483647 + j + ") at i = " + i + " j = " + j;
+    }
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to