Title: [192531] trunk/Source/_javascript_Core
Revision
192531
Author
mark....@apple.com
Date
2015-11-17 13:55:33 -0800 (Tue, 17 Nov 2015)

Log Message

Use the JITAddGenerator snippet in the DFG.
https://bugs.webkit.org/show_bug.cgi?id=151266

Reviewed by Geoffrey Garen.

No tests added because the op_add.js stress test already tests for correctness
(using the LLINT as a reference).

Performance-wise, the difference from the pre-existing DFG implementation is
insignificant (at least as measured on x86 and x86_64).  We're moving forward
with adopting this implementation because it unifies the 32-bit and 64-bit
implementations, as well as lays ground work for a repatching inline cache
implementation of op_add later.

* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::resultType):
- Made an assertion less restrictive.  For ValueAdd operands, the DFG thinks that
  the operand can also be empty (though we should never see this in practice).

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
- Add fallback to unused type operands.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileValueAdd):
- Introduce a common function to compile the ValueAdd node.

* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::JSValueOperand::JSValueOperand):
- Add the forwarding constructor so that we can use Optional<JSValueOperand>.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
- Changed to use the common compileValueAdd().

* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::moveValue):
- Similar to moveTrustedValue() but used for untrusted constants.

* jit/JITAddGenerator.cpp:
(JSC::JITAddGenerator::generateFastPath):
* jit/JITAddGenerator.h:
(JSC::JITAddGenerator::JITAddGenerator):
- Updated to take the left or right operand as a constant.  This is necessary
  because the client should not be making assumptions about whether the snippet
  will determine the operation to be commutative or not.  Instead, the client
  should just pass in the operands and let the snippet do any operand order
  swapping if necessary.

* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_add):
- Updated to use the new JITAddGenerator interface.

* tests/stress/op_add.js:
(stringifyIfNeeded):
(runTest):
- Made test output more clear about when string results are expected.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (192530 => 192531)


--- trunk/Source/_javascript_Core/ChangeLog	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-11-17 21:55:33 UTC (rev 192531)
@@ -1,3 +1,65 @@
+2015-11-17  Mark Lam  <mark....@apple.com>
+
+        Use the JITAddGenerator snippet in the DFG.
+        https://bugs.webkit.org/show_bug.cgi?id=151266
+
+        Reviewed by Geoffrey Garen.
+
+        No tests added because the op_add.js stress test already tests for correctness
+        (using the LLINT as a reference).
+
+        Performance-wise, the difference from the pre-existing DFG implementation is
+        insignificant (at least as measured on x86 and x86_64).  We're moving forward
+        with adopting this implementation because it unifies the 32-bit and 64-bit
+        implementations, as well as lays ground work for a repatching inline cache
+        implementation of op_add later.
+
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::resultType):
+        - Made an assertion less restrictive.  For ValueAdd operands, the DFG thinks that
+          the operand can also be empty (though we should never see this in practice).
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        - Add fallback to unused type operands.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileValueAdd):
+        - Introduce a common function to compile the ValueAdd node.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::JSValueOperand::JSValueOperand):
+        - Add the forwarding constructor so that we can use Optional<JSValueOperand>.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        - Changed to use the common compileValueAdd().
+
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::moveValue):
+        - Similar to moveTrustedValue() but used for untrusted constants.
+
+        * jit/JITAddGenerator.cpp:
+        (JSC::JITAddGenerator::generateFastPath):
+        * jit/JITAddGenerator.h:
+        (JSC::JITAddGenerator::JITAddGenerator):
+        - Updated to take the left or right operand as a constant.  This is necessary
+          because the client should not be making assumptions about whether the snippet
+          will determine the operation to be commutative or not.  Instead, the client
+          should just pass in the operands and let the snippet do any operand order
+          swapping if necessary.
+
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emit_op_add):
+        - Updated to use the new JITAddGenerator interface.
+
+        * tests/stress/op_add.js:
+        (stringifyIfNeeded):
+        (runTest):
+        - Made test output more clear about when string results are expected.
+
 2015-11-17  Filip Pizlo  <fpi...@apple.com>
 
         It's best for the DFG to always have some guess of basic block frequency

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -499,7 +499,7 @@
 
 ResultType AbstractValue::resultType() const
 {
-    ASSERT(isType(SpecHeapTop));
+    ASSERT(isType(SpecBytecodeTop));
     if (isType(SpecBoolean))
         return ResultType::booleanType();
     if (isType(SpecInt32))

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -155,8 +155,9 @@
             if (attemptToMakeFastStringAdd(node))
                 break;
 
-            // We could attempt to turn this into a StrCat here. But for now, that wouldn't
-            // significantly reduce the number of branches required.
+            fixEdge<UntypedUse>(node->child1());
+            fixEdge<UntypedUse>(node->child2());
+            node->setResult(NodeResultJS);
             break;
         }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -38,6 +38,7 @@
 #include "DFGSaneStringGetByValSlowPathGenerator.h"
 #include "DFGSlowPathGenerator.h"
 #include "DirectArguments.h"
+#include "JITAddGenerator.h"
 #include "JITSubGenerator.h"
 #include "JSArrowFunction.h"
 #include "JSCInlines.h"
@@ -2782,6 +2783,127 @@
     blessedBooleanResult(scratchReg, node);
 }
 
+void SpeculativeJIT::compileValueAdd(Node* node)
+{
+    if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node())) {
+        JSValueOperand left(this, node->child1());
+        JSValueOperand right(this, node->child2());
+        JSValueRegs leftRegs = left.jsValueRegs();
+        JSValueRegs rightRegs = right.jsValueRegs();
+#if USE(JSVALUE64)
+        GPRTemporary result(this);
+        JSValueRegs resultRegs = JSValueRegs(result.gpr());
+#else
+        GPRTemporary resultTag(this);
+        GPRTemporary resultPayload(this);
+        JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
+#endif
+        flushRegisters();
+        callOperation(operationValueAddNotNumber, resultRegs, leftRegs, rightRegs);
+        m_jit.exceptionCheck();
+    
+        jsValueResult(resultRegs, node);
+        return;
+    }
+
+    bool leftIsConstInt32 = node->child1()->isInt32Constant();
+    bool rightIsConstInt32 = node->child2()->isInt32Constant();
+
+    // The DFG does not always fold the sum of 2 constant int operands together.
+    if (leftIsConstInt32 && rightIsConstInt32) {
+#if USE(JSVALUE64)
+        GPRTemporary result(this);
+        JSValueRegs resultRegs = JSValueRegs(result.gpr());
+#else
+        GPRTemporary resultTag(this);
+        GPRTemporary resultPayload(this);
+        JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
+#endif
+        int64_t leftConst = node->child1()->asInt32();
+        int64_t rightConst = node->child2()->asInt32();
+        int64_t resultConst = leftConst + rightConst;
+        m_jit.moveValue(JSValue(resultConst), resultRegs);
+        jsValueResult(resultRegs, node);
+        return;
+    }
+
+    Optional<JSValueOperand> left;
+    Optional<JSValueOperand> right;
+
+    JSValueRegs leftRegs;
+    JSValueRegs rightRegs;
+
+    FPRTemporary leftNumber(this);
+    FPRTemporary rightNumber(this);
+    FPRReg leftFPR = leftNumber.fpr();
+    FPRReg rightFPR = rightNumber.fpr();
+
+#if USE(JSVALUE64)
+    GPRTemporary result(this);
+    JSValueRegs resultRegs = JSValueRegs(result.gpr());
+    GPRTemporary scratch(this);
+    GPRReg scratchGPR = scratch.gpr();
+    FPRReg scratchFPR = InvalidFPRReg;
+#else
+    GPRTemporary resultTag(this);
+    GPRTemporary resultPayload(this);
+    JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
+    GPRReg scratchGPR = resultTag.gpr();
+    FPRTemporary fprScratch(this);
+    FPRReg scratchFPR = fprScratch.fpr();
+#endif
+
+    ResultType leftType = m_state.forNode(node->child1()).resultType();
+    ResultType rightType = m_state.forNode(node->child2()).resultType();
+    int32_t leftConstInt32 = 0;
+    int32_t rightConstInt32 = 0;
+
+    ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
+
+    if (leftIsConstInt32) {
+        leftConstInt32 = node->child1()->asInt32();
+        right = JSValueOperand(this, node->child2());
+        rightRegs = right->jsValueRegs();
+    } else if (rightIsConstInt32) {
+        left = JSValueOperand(this, node->child1());
+        leftRegs = left->jsValueRegs();
+        rightConstInt32 = node->child2()->asInt32();
+    } else {
+        left = JSValueOperand(this, node->child1());
+        leftRegs = left->jsValueRegs();
+        right = JSValueOperand(this, node->child2());
+        rightRegs = right->jsValueRegs();
+    }
+
+    JITAddGenerator gen(resultRegs, leftRegs, rightRegs, leftType, rightType,
+        leftIsConstInt32, rightIsConstInt32, leftConstInt32, rightConstInt32,
+        leftFPR, rightFPR, scratchGPR, scratchFPR);
+    gen.generateFastPath(m_jit);
+
+    gen.slowPathJumpList().link(&m_jit);
+
+    silentSpillAllRegisters(resultRegs);
+
+    if (leftIsConstInt32) {
+        leftRegs = resultRegs;
+        int64_t leftConst = node->child1()->asInt32();
+        m_jit.moveValue(JSValue(leftConst), leftRegs);
+    } else if (rightIsConstInt32) {
+        rightRegs = resultRegs;
+        int64_t rightConst = node->child2()->asInt32();
+        m_jit.moveValue(JSValue(rightConst), rightRegs);
+    }
+
+    callOperation(operationValueAdd, resultRegs, leftRegs, rightRegs);
+
+    silentFillAllRegisters(resultRegs);
+    m_jit.exceptionCheck();
+
+    gen.endJumpList().link(&m_jit);
+    jsValueResult(resultRegs, node);
+    return;
+}
+
 void SpeculativeJIT::compileArithAdd(Node* node)
 {
     switch (node->binaryUseKind()) {

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (192530 => 192531)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2015-11-17 21:55:33 UTC (rev 192531)
@@ -2207,6 +2207,7 @@
     void compileValueToInt32(Node*);
     void compileUInt32ToNumber(Node*);
     void compileDoubleAsInt32(Node*);
+    void compileValueAdd(Node*);
     void compileArithAdd(Node*);
     void compileMakeRope(Node*);
     void compileArithClz32(Node*);
@@ -2552,6 +2553,32 @@
 #endif
     }
 
+    explicit JSValueOperand(JSValueOperand&& other)
+        : m_jit(other.m_jit)
+        , m_edge(other.m_edge)
+    {
+#if USE(JSVALUE64)
+        m_gprOrInvalid = other.m_gprOrInvalid;
+#elif USE(JSVALUE32_64)
+        m_register.pair.tagGPR = InvalidGPRReg;
+        m_register.pair.payloadGPR = InvalidGPRReg;
+        m_isDouble = other.m_isDouble;
+
+        if (m_edge) {
+            if (m_isDouble)
+                m_register.fpr = other.m_register.fpr;
+            else
+                m_register.pair = other.m_register.pair;
+        }
+#endif
+        other.m_edge = Edge();
+#if USE(JSVALUE64)
+        other.m_gprOrInvalid = InvalidGPRReg;
+#elif USE(JSVALUE32_64)
+        other.m_isDouble = false;
+#endif
+    }
+
     ~JSValueOperand()
     {
         if (!m_edge)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -2134,29 +2134,10 @@
         compileValueRep(node);
         break;
     }
-        
-    case ValueAdd: {
-        JSValueOperand op1(this, node->child1());
-        JSValueOperand op2(this, node->child2());
-        
-        GPRReg op1TagGPR = op1.tagGPR();
-        GPRReg op1PayloadGPR = op1.payloadGPR();
-        GPRReg op2TagGPR = op2.tagGPR();
-        GPRReg op2PayloadGPR = op2.payloadGPR();
-        
-        flushRegisters();
-        
-        GPRFlushedCallResult2 resultTag(this);
-        GPRFlushedCallResult resultPayload(this);
-        if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
-            callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
-        else
-            callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
-        m_jit.exceptionCheck();
-        
-        jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+
+    case ValueAdd:
+        compileValueAdd(node);
         break;
-    }
 
     case StrCat: {
         JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -2268,27 +2268,11 @@
         }
         break;
     }
-        
-    case ValueAdd: {
-        JSValueOperand op1(this, node->child1());
-        JSValueOperand op2(this, node->child2());
-        
-        GPRReg op1GPR = op1.gpr();
-        GPRReg op2GPR = op2.gpr();
-        
-        flushRegisters();
-        
-        GPRFlushedCallResult result(this);
-        if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
-            callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
-        else
-            callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
-        m_jit.exceptionCheck();
-        
-        jsValueResult(result.gpr(), node);
+
+    case ValueAdd:
+        compileValueAdd(node);
         break;
-    }
-        
+
     case StrCat: {
         JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
         JSValueOperand op2(this, node->child2(), ManualOperandSpeculation);

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (192530 => 192531)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2015-11-17 21:55:33 UTC (rev 192531)
@@ -148,7 +148,17 @@
         }
 #endif
     }
-    
+
+    void moveValue(JSValue value, JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        move(Imm64(JSValue::encode(value)), regs.gpr());
+#else
+        move(Imm32(value.tag()), regs.tagGPR());
+        move(Imm32(value.payload()), regs.payloadGPR());
+#endif
+    }
+
     void moveTrustedValue(JSValue value, JSValueRegs regs)
     {
 #if USE(JSVALUE64)

Modified: trunk/Source/_javascript_Core/jit/JITAddGenerator.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/jit/JITAddGenerator.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/jit/JITAddGenerator.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -35,22 +35,38 @@
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
     ASSERT(m_scratchGPR != m_right.payloadGPR());
-#if ENABLE(JSVALUE32_64)
-    ASSERT(m_scratchGPR != m_left.tagGPR());x
+#if USE(JSVALUE32_64)
+    ASSERT(m_scratchGPR != m_left.tagGPR());
     ASSERT(m_scratchGPR != m_right.tagGPR());
     ASSERT(m_scratchFPR != InvalidFPRReg);
 #endif
 
+    ASSERT(!m_leftIsConstInt32 || !m_rightIsConstInt32);
+    
     if (!m_leftType.mightBeNumber() || !m_rightType.mightBeNumber()) {
         m_slowPathJumpList.append(jit.jump());
         return;
     }
 
-    if (m_operandsConstness == RightIsConstInt32) {
+    if (m_leftIsConstInt32 || m_rightIsConstInt32) {
+        JSValueRegs var;
+        ResultType varType = ResultType::unknownType();
+        int32_t constInt32;
+
+        if (m_leftIsConstInt32) {
+            var = m_right;
+            varType = m_rightType;
+            constInt32 = m_leftConstInt32;
+        } else {
+            var = m_left;
+            varType = m_leftType;
+            constInt32 = m_rightConstInt32;
+        }
+
         // Try to do intVar + intConstant.
-        CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(m_left);
+        CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(var);
 
-        m_slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_left.payloadGPR(), CCallHelpers::Imm32(m_rightConstInt32), m_scratchGPR));
+        m_slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constInt32), m_scratchGPR));
 
         jit.boxInt32(m_scratchGPR, m_result);
         m_endJumpList.append(jit.jump());
@@ -62,18 +78,18 @@
 
         // Try to do doubleVar + double(intConstant).
         notInt32.link(&jit);
-        if (!m_leftType.definitelyIsNumber())
-            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
+        if (!varType.definitelyIsNumber())
+            m_slowPathJumpList.append(jit.branchIfNotNumber(var, m_scratchGPR));
 
-        jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
+        jit.unboxDoubleNonDestructive(var, m_leftFPR, m_scratchGPR, m_scratchFPR);
 
-        jit.move(CCallHelpers::Imm32(m_rightConstInt32), m_scratchGPR);
+        jit.move(CCallHelpers::Imm32(constInt32), m_scratchGPR);
         jit.convertInt32ToDouble(m_scratchGPR, m_rightFPR);
 
         // Fall thru to doubleVar + doubleVar.
 
     } else {
-        ASSERT(m_operandsConstness == NeitherAreConstInt32);
+        ASSERT(!m_leftIsConstInt32 && !m_rightIsConstInt32);
         CCallHelpers::Jump leftNotInt;
         CCallHelpers::Jump rightNotInt;
 

Modified: trunk/Source/_javascript_Core/jit/JITAddGenerator.h (192530 => 192531)


--- trunk/Source/_javascript_Core/jit/JITAddGenerator.h	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/jit/JITAddGenerator.h	2015-11-17 21:55:33 UTC (rev 192531)
@@ -35,36 +35,26 @@
 
 class JITAddGenerator {
 public:
-    enum OperandsConstness {
-        NeitherAreConstInt32,
-
-        // Since addition is commutative, it doesn't matter which operand we make the
-        // ConstInt32. Let's always put the const in the right, and the variable operand
-        // in the left.
-        RightIsConstInt32,
-
-        // We choose not to implement any optimization for the case where both operands
-        // are ConstInt32 here. The client may choose to do that optimzation and not
-        // invoke this snippet generator, or may load both operands into registers
-        // and pass them as variables to the snippet generator instead.
-    };
-
     JITAddGenerator(JSValueRegs result, JSValueRegs left, JSValueRegs right,
-        OperandsConstness operandsConstness, int32_t rightConstInt32,
-        ResultType leftType, ResultType rightType, FPRReg leftFPR, FPRReg rightFPR,
+        ResultType leftType, ResultType rightType, bool leftIsConstInt32, bool rightIsConstInt32,
+        int32_t leftConstInt32, int32_t rightConstInt32, FPRReg leftFPR, FPRReg rightFPR,
         GPRReg scratchGPR, FPRReg scratchFPR)
         : m_result(result)
         , m_left(left)
         , m_right(right)
-        , m_operandsConstness(operandsConstness)
-        , m_rightConstInt32(rightConstInt32)
         , m_leftType(leftType)
         , m_rightType(rightType)
+        , m_leftIsConstInt32(leftIsConstInt32)
+        , m_rightIsConstInt32(rightIsConstInt32)
+        , m_leftConstInt32(leftConstInt32)
+        , m_rightConstInt32(rightConstInt32)
         , m_leftFPR(leftFPR)
         , m_rightFPR(rightFPR)
         , m_scratchGPR(scratchGPR)
         , m_scratchFPR(scratchFPR)
-    { }
+    {
+        ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
+    }
 
     void generateFastPath(CCallHelpers&);
 
@@ -75,10 +65,12 @@
     JSValueRegs m_result;
     JSValueRegs m_left;
     JSValueRegs m_right;
-    OperandsConstness m_operandsConstness;
-    int32_t m_rightConstInt32;
     ResultType m_leftType;
     ResultType m_rightType;
+    bool m_leftIsConstInt32;
+    bool m_rightIsConstInt32;
+    int32_t m_leftConstInt32;
+    int32_t m_rightConstInt32;
     FPRReg m_leftFPR;
     FPRReg m_rightFPR;
     GPRReg m_scratchGPR;

Modified: trunk/Source/_javascript_Core/jit/JITArithmetic.cpp (192530 => 192531)


--- trunk/Source/_javascript_Core/jit/JITArithmetic.cpp	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic.cpp	2015-11-17 21:55:33 UTC (rev 192531)
@@ -934,34 +934,26 @@
 
     bool leftIsConstInt32 = isOperandConstantInt(op1);
     bool rightIsConstInt32 = isOperandConstantInt(op2);
-    JITAddGenerator::OperandsConstness operandsConstness;
-    int32_t rightConstInt32 = 0;
     ResultType leftType = types.first();
     ResultType rightType = types.second();
+    int32_t leftConstInt32 = 0;
+    int32_t rightConstInt32 = 0;
 
     ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
 
     if (leftIsConstInt32) {
-        // JITAddGenerator expects the const value in the right operand.
-        // Let's swap the operands.
-        operandsConstness = JITAddGenerator::RightIsConstInt32;
-        rightConstInt32 = getOperandConstantInt(op1);
-        rightType = types.first();
-        emitGetVirtualRegister(op2, leftRegs);
-        leftType = types.second();
+        leftConstInt32 = getOperandConstantInt(op1);
+        emitGetVirtualRegister(op2, rightRegs);
     } else if (rightIsConstInt32) {
-        operandsConstness = JITAddGenerator::RightIsConstInt32;
-        rightConstInt32 = getOperandConstantInt(op2);
         emitGetVirtualRegister(op1, leftRegs);
+        rightConstInt32 = getOperandConstantInt(op2);
     } else {
-        operandsConstness = JITAddGenerator::NeitherAreConstInt32;
         emitGetVirtualRegister(op1, leftRegs);
         emitGetVirtualRegister(op2, rightRegs);
     }
 
-    JITAddGenerator gen(resultRegs, leftRegs, rightRegs,
-        operandsConstness, rightConstInt32,
-        leftType, rightType,
+    JITAddGenerator gen(resultRegs, leftRegs, rightRegs, leftType, rightType,
+        leftIsConstInt32, rightIsConstInt32, leftConstInt32, rightConstInt32,
         fpRegT0, fpRegT1, scratchGPR, scratchFPR);
 
     gen.generateFastPath(*this);

Modified: trunk/Source/_javascript_Core/tests/stress/op_add.js (192530 => 192531)


--- trunk/Source/_javascript_Core/tests/stress/op_add.js	2015-11-17 21:45:32 UTC (rev 192530)
+++ trunk/Source/_javascript_Core/tests/stress/op_add.js	2015-11-17 21:55:33 UTC (rev 192531)
@@ -318,6 +318,12 @@
 
 var errorReport = "";
 
+function stringifyIfNeeded(x) {
+    if (typeof x == "string")
+        return '"' + x + '"';
+    return x;
+}
+
 function runTest(test) {
     var failedScenario = [];
     var scenarios = test.scenarios;
@@ -327,7 +333,7 @@
             for (var scenarioID = 0; scenarioID < scenarios.length; scenarioID++) {
                 var scenario = scenarios[scenarioID];
                 if (verbose)
-                    print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + scenario.expected); 
+                    print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + stringifyIfNeeded(scenario.expected)); 
 
                 var result = testFunc(scenario.x, scenario.y);
                 if (result == scenario.expected)
@@ -335,7 +341,8 @@
                 if (Number.isNaN(result) && Number.isNaN(scenario.expected))
                     continue;
                 if (!failedScenario[scenarioID]) {
-                    errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i + ": expected " + scenario.expected + ", actual " + result + "\n";
+                    errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i
+                        + ": expected " + stringifyIfNeeded(scenario.expected) + ", actual " + stringifyIfNeeded(result) + "\n";
                     if (abortOnFirstFail)
                         throw errorReport;
                     failedScenario[scenarioID] = scenario;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to