Changeset 192531 in webkit


Ignore:
Timestamp:
Nov 17, 2015 1:55:33 PM (8 years ago)
Author:
mark.lam@apple.com
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.
Location:
trunk/Source/JavaScriptCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r192529 r192531  
     12015-11-17  Mark Lam  <mark.lam@apple.com>
     2
     3        Use the JITAddGenerator snippet in the DFG.
     4        https://bugs.webkit.org/show_bug.cgi?id=151266
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        No tests added because the op_add.js stress test already tests for correctness
     9        (using the LLINT as a reference).
     10
     11        Performance-wise, the difference from the pre-existing DFG implementation is
     12        insignificant (at least as measured on x86 and x86_64).  We're moving forward
     13        with adopting this implementation because it unifies the 32-bit and 64-bit
     14        implementations, as well as lays ground work for a repatching inline cache
     15        implementation of op_add later.
     16
     17        * dfg/DFGAbstractValue.cpp:
     18        (JSC::DFG::AbstractValue::resultType):
     19        - Made an assertion less restrictive.  For ValueAdd operands, the DFG thinks that
     20          the operand can also be empty (though we should never see this in practice).
     21
     22        * dfg/DFGFixupPhase.cpp:
     23        (JSC::DFG::FixupPhase::fixupNode):
     24        - Add fallback to unused type operands.
     25
     26        * dfg/DFGSpeculativeJIT.cpp:
     27        (JSC::DFG::SpeculativeJIT::compileValueAdd):
     28        - Introduce a common function to compile the ValueAdd node.
     29
     30        * dfg/DFGSpeculativeJIT.h:
     31        (JSC::DFG::JSValueOperand::JSValueOperand):
     32        - Add the forwarding constructor so that we can use Optional<JSValueOperand>.
     33
     34        * dfg/DFGSpeculativeJIT32_64.cpp:
     35        (JSC::DFG::SpeculativeJIT::compile):
     36        * dfg/DFGSpeculativeJIT64.cpp:
     37        (JSC::DFG::SpeculativeJIT::compile):
     38        - Changed to use the common compileValueAdd().
     39
     40        * jit/AssemblyHelpers.h:
     41        (JSC::AssemblyHelpers::moveValue):
     42        - Similar to moveTrustedValue() but used for untrusted constants.
     43
     44        * jit/JITAddGenerator.cpp:
     45        (JSC::JITAddGenerator::generateFastPath):
     46        * jit/JITAddGenerator.h:
     47        (JSC::JITAddGenerator::JITAddGenerator):
     48        - Updated to take the left or right operand as a constant.  This is necessary
     49          because the client should not be making assumptions about whether the snippet
     50          will determine the operation to be commutative or not.  Instead, the client
     51          should just pass in the operands and let the snippet do any operand order
     52          swapping if necessary.
     53
     54        * jit/JITArithmetic.cpp:
     55        (JSC::JIT::emit_op_add):
     56        - Updated to use the new JITAddGenerator interface.
     57
     58        * tests/stress/op_add.js:
     59        (stringifyIfNeeded):
     60        (runTest):
     61        - Made test output more clear about when string results are expected.
     62
    1632015-11-17  Filip Pizlo  <fpizlo@apple.com>
    264
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r191224 r192531  
    500500ResultType AbstractValue::resultType() const
    501501{
    502     ASSERT(isType(SpecHeapTop));
     502    ASSERT(isType(SpecBytecodeTop));
    503503    if (isType(SpecBoolean))
    504504        return ResultType::booleanType();
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r192034 r192531  
    156156                break;
    157157
    158             // We could attempt to turn this into a StrCat here. But for now, that wouldn't
    159             // significantly reduce the number of branches required.
     158            fixEdge<UntypedUse>(node->child1());
     159            fixEdge<UntypedUse>(node->child2());
     160            node->setResult(NodeResultJS);
    160161            break;
    161162        }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r192295 r192531  
    3939#include "DFGSlowPathGenerator.h"
    4040#include "DirectArguments.h"
     41#include "JITAddGenerator.h"
    4142#include "JITSubGenerator.h"
    4243#include "JSArrowFunction.h"
     
    27812782
    27822783    blessedBooleanResult(scratchReg, node);
     2784}
     2785
     2786void SpeculativeJIT::compileValueAdd(Node* node)
     2787{
     2788    if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node())) {
     2789        JSValueOperand left(this, node->child1());
     2790        JSValueOperand right(this, node->child2());
     2791        JSValueRegs leftRegs = left.jsValueRegs();
     2792        JSValueRegs rightRegs = right.jsValueRegs();
     2793#if USE(JSVALUE64)
     2794        GPRTemporary result(this);
     2795        JSValueRegs resultRegs = JSValueRegs(result.gpr());
     2796#else
     2797        GPRTemporary resultTag(this);
     2798        GPRTemporary resultPayload(this);
     2799        JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
     2800#endif
     2801        flushRegisters();
     2802        callOperation(operationValueAddNotNumber, resultRegs, leftRegs, rightRegs);
     2803        m_jit.exceptionCheck();
     2804   
     2805        jsValueResult(resultRegs, node);
     2806        return;
     2807    }
     2808
     2809    bool leftIsConstInt32 = node->child1()->isInt32Constant();
     2810    bool rightIsConstInt32 = node->child2()->isInt32Constant();
     2811
     2812    // The DFG does not always fold the sum of 2 constant int operands together.
     2813    if (leftIsConstInt32 && rightIsConstInt32) {
     2814#if USE(JSVALUE64)
     2815        GPRTemporary result(this);
     2816        JSValueRegs resultRegs = JSValueRegs(result.gpr());
     2817#else
     2818        GPRTemporary resultTag(this);
     2819        GPRTemporary resultPayload(this);
     2820        JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
     2821#endif
     2822        int64_t leftConst = node->child1()->asInt32();
     2823        int64_t rightConst = node->child2()->asInt32();
     2824        int64_t resultConst = leftConst + rightConst;
     2825        m_jit.moveValue(JSValue(resultConst), resultRegs);
     2826        jsValueResult(resultRegs, node);
     2827        return;
     2828    }
     2829
     2830    Optional<JSValueOperand> left;
     2831    Optional<JSValueOperand> right;
     2832
     2833    JSValueRegs leftRegs;
     2834    JSValueRegs rightRegs;
     2835
     2836    FPRTemporary leftNumber(this);
     2837    FPRTemporary rightNumber(this);
     2838    FPRReg leftFPR = leftNumber.fpr();
     2839    FPRReg rightFPR = rightNumber.fpr();
     2840
     2841#if USE(JSVALUE64)
     2842    GPRTemporary result(this);
     2843    JSValueRegs resultRegs = JSValueRegs(result.gpr());
     2844    GPRTemporary scratch(this);
     2845    GPRReg scratchGPR = scratch.gpr();
     2846    FPRReg scratchFPR = InvalidFPRReg;
     2847#else
     2848    GPRTemporary resultTag(this);
     2849    GPRTemporary resultPayload(this);
     2850    JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
     2851    GPRReg scratchGPR = resultTag.gpr();
     2852    FPRTemporary fprScratch(this);
     2853    FPRReg scratchFPR = fprScratch.fpr();
     2854#endif
     2855
     2856    ResultType leftType = m_state.forNode(node->child1()).resultType();
     2857    ResultType rightType = m_state.forNode(node->child2()).resultType();
     2858    int32_t leftConstInt32 = 0;
     2859    int32_t rightConstInt32 = 0;
     2860
     2861    ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
     2862
     2863    if (leftIsConstInt32) {
     2864        leftConstInt32 = node->child1()->asInt32();
     2865        right = JSValueOperand(this, node->child2());
     2866        rightRegs = right->jsValueRegs();
     2867    } else if (rightIsConstInt32) {
     2868        left = JSValueOperand(this, node->child1());
     2869        leftRegs = left->jsValueRegs();
     2870        rightConstInt32 = node->child2()->asInt32();
     2871    } else {
     2872        left = JSValueOperand(this, node->child1());
     2873        leftRegs = left->jsValueRegs();
     2874        right = JSValueOperand(this, node->child2());
     2875        rightRegs = right->jsValueRegs();
     2876    }
     2877
     2878    JITAddGenerator gen(resultRegs, leftRegs, rightRegs, leftType, rightType,
     2879        leftIsConstInt32, rightIsConstInt32, leftConstInt32, rightConstInt32,
     2880        leftFPR, rightFPR, scratchGPR, scratchFPR);
     2881    gen.generateFastPath(m_jit);
     2882
     2883    gen.slowPathJumpList().link(&m_jit);
     2884
     2885    silentSpillAllRegisters(resultRegs);
     2886
     2887    if (leftIsConstInt32) {
     2888        leftRegs = resultRegs;
     2889        int64_t leftConst = node->child1()->asInt32();
     2890        m_jit.moveValue(JSValue(leftConst), leftRegs);
     2891    } else if (rightIsConstInt32) {
     2892        rightRegs = resultRegs;
     2893        int64_t rightConst = node->child2()->asInt32();
     2894        m_jit.moveValue(JSValue(rightConst), rightRegs);
     2895    }
     2896
     2897    callOperation(operationValueAdd, resultRegs, leftRegs, rightRegs);
     2898
     2899    silentFillAllRegisters(resultRegs);
     2900    m_jit.exceptionCheck();
     2901
     2902    gen.endJumpList().link(&m_jit);
     2903    jsValueResult(resultRegs, node);
     2904    return;
    27832905}
    27842906
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r192000 r192531  
    22082208    void compileUInt32ToNumber(Node*);
    22092209    void compileDoubleAsInt32(Node*);
     2210    void compileValueAdd(Node*);
    22102211    void compileArithAdd(Node*);
    22112212    void compileMakeRope(Node*);
     
    25532554    }
    25542555
     2556    explicit JSValueOperand(JSValueOperand&& other)
     2557        : m_jit(other.m_jit)
     2558        , m_edge(other.m_edge)
     2559    {
     2560#if USE(JSVALUE64)
     2561        m_gprOrInvalid = other.m_gprOrInvalid;
     2562#elif USE(JSVALUE32_64)
     2563        m_register.pair.tagGPR = InvalidGPRReg;
     2564        m_register.pair.payloadGPR = InvalidGPRReg;
     2565        m_isDouble = other.m_isDouble;
     2566
     2567        if (m_edge) {
     2568            if (m_isDouble)
     2569                m_register.fpr = other.m_register.fpr;
     2570            else
     2571                m_register.pair = other.m_register.pair;
     2572        }
     2573#endif
     2574        other.m_edge = Edge();
     2575#if USE(JSVALUE64)
     2576        other.m_gprOrInvalid = InvalidGPRReg;
     2577#elif USE(JSVALUE32_64)
     2578        other.m_isDouble = false;
     2579#endif
     2580    }
     2581
    25552582    ~JSValueOperand()
    25562583    {
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r192125 r192531  
    21352135        break;
    21362136    }
    2137        
    2138     case ValueAdd: {
    2139         JSValueOperand op1(this, node->child1());
    2140         JSValueOperand op2(this, node->child2());
    2141        
    2142         GPRReg op1TagGPR = op1.tagGPR();
    2143         GPRReg op1PayloadGPR = op1.payloadGPR();
    2144         GPRReg op2TagGPR = op2.tagGPR();
    2145         GPRReg op2PayloadGPR = op2.payloadGPR();
    2146        
    2147         flushRegisters();
    2148        
    2149         GPRFlushedCallResult2 resultTag(this);
    2150         GPRFlushedCallResult resultPayload(this);
    2151         if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
    2152             callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
    2153         else
    2154             callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
    2155         m_jit.exceptionCheck();
    2156        
    2157         jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
    2158         break;
    2159     }
     2137
     2138    case ValueAdd:
     2139        compileValueAdd(node);
     2140        break;
    21602141
    21612142    case StrCat: {
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r192465 r192531  
    22692269        break;
    22702270    }
    2271        
    2272     case ValueAdd: {
    2273         JSValueOperand op1(this, node->child1());
    2274         JSValueOperand op2(this, node->child2());
    2275        
    2276         GPRReg op1GPR = op1.gpr();
    2277         GPRReg op2GPR = op2.gpr();
    2278        
    2279         flushRegisters();
    2280        
    2281         GPRFlushedCallResult result(this);
    2282         if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
    2283             callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
    2284         else
    2285             callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
    2286         m_jit.exceptionCheck();
    2287        
    2288         jsValueResult(result.gpr(), node);
    2289         break;
    2290     }
    2291        
     2271
     2272    case ValueAdd:
     2273        compileValueAdd(node);
     2274        break;
     2275
    22922276    case StrCat: {
    22932277        JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r191404 r192531  
    149149#endif
    150150    }
    151    
     151
     152    void moveValue(JSValue value, JSValueRegs regs)
     153    {
     154#if USE(JSVALUE64)
     155        move(Imm64(JSValue::encode(value)), regs.gpr());
     156#else
     157        move(Imm32(value.tag()), regs.tagGPR());
     158        move(Imm32(value.payload()), regs.payloadGPR());
     159#endif
     160    }
     161
    152162    void moveTrustedValue(JSValue value, JSValueRegs regs)
    153163    {
  • trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp

    r191905 r192531  
    3636    ASSERT(m_scratchGPR != m_left.payloadGPR());
    3737    ASSERT(m_scratchGPR != m_right.payloadGPR());
    38 #if ENABLE(JSVALUE32_64)
    39     ASSERT(m_scratchGPR != m_left.tagGPR());x
     38#if USE(JSVALUE32_64)
     39    ASSERT(m_scratchGPR != m_left.tagGPR());
    4040    ASSERT(m_scratchGPR != m_right.tagGPR());
    4141    ASSERT(m_scratchFPR != InvalidFPRReg);
    4242#endif
    4343
     44    ASSERT(!m_leftIsConstInt32 || !m_rightIsConstInt32);
     45   
    4446    if (!m_leftType.mightBeNumber() || !m_rightType.mightBeNumber()) {
    4547        m_slowPathJumpList.append(jit.jump());
     
    4749    }
    4850
    49     if (m_operandsConstness == RightIsConstInt32) {
     51    if (m_leftIsConstInt32 || m_rightIsConstInt32) {
     52        JSValueRegs var;
     53        ResultType varType = ResultType::unknownType();
     54        int32_t constInt32;
     55
     56        if (m_leftIsConstInt32) {
     57            var = m_right;
     58            varType = m_rightType;
     59            constInt32 = m_leftConstInt32;
     60        } else {
     61            var = m_left;
     62            varType = m_leftType;
     63            constInt32 = m_rightConstInt32;
     64        }
     65
    5066        // Try to do intVar + intConstant.
    51         CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(m_left);
     67        CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(var);
    5268
    53         m_slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_left.payloadGPR(), CCallHelpers::Imm32(m_rightConstInt32), m_scratchGPR));
     69        m_slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constInt32), m_scratchGPR));
    5470
    5571        jit.boxInt32(m_scratchGPR, m_result);
     
    6379        // Try to do doubleVar + double(intConstant).
    6480        notInt32.link(&jit);
    65         if (!m_leftType.definitelyIsNumber())
    66             m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
     81        if (!varType.definitelyIsNumber())
     82            m_slowPathJumpList.append(jit.branchIfNotNumber(var, m_scratchGPR));
    6783
    68         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
     84        jit.unboxDoubleNonDestructive(var, m_leftFPR, m_scratchGPR, m_scratchFPR);
    6985
    70         jit.move(CCallHelpers::Imm32(m_rightConstInt32), m_scratchGPR);
     86        jit.move(CCallHelpers::Imm32(constInt32), m_scratchGPR);
    7187        jit.convertInt32ToDouble(m_scratchGPR, m_rightFPR);
    7288
     
    7490
    7591    } else {
    76         ASSERT(m_operandsConstness == NeitherAreConstInt32);
     92        ASSERT(!m_leftIsConstInt32 && !m_rightIsConstInt32);
    7793        CCallHelpers::Jump leftNotInt;
    7894        CCallHelpers::Jump rightNotInt;
  • trunk/Source/JavaScriptCore/jit/JITAddGenerator.h

    r191905 r192531  
    3636class JITAddGenerator {
    3737public:
    38     enum OperandsConstness {
    39         NeitherAreConstInt32,
    40 
    41         // Since addition is commutative, it doesn't matter which operand we make the
    42         // ConstInt32. Let's always put the const in the right, and the variable operand
    43         // in the left.
    44         RightIsConstInt32,
    45 
    46         // We choose not to implement any optimization for the case where both operands
    47         // are ConstInt32 here. The client may choose to do that optimzation and not
    48         // invoke this snippet generator, or may load both operands into registers
    49         // and pass them as variables to the snippet generator instead.
    50     };
    51 
    5238    JITAddGenerator(JSValueRegs result, JSValueRegs left, JSValueRegs right,
    53         OperandsConstness operandsConstness, int32_t rightConstInt32,
    54         ResultType leftType, ResultType rightType, FPRReg leftFPR, FPRReg rightFPR,
     39        ResultType leftType, ResultType rightType, bool leftIsConstInt32, bool rightIsConstInt32,
     40        int32_t leftConstInt32, int32_t rightConstInt32, FPRReg leftFPR, FPRReg rightFPR,
    5541        GPRReg scratchGPR, FPRReg scratchFPR)
    5642        : m_result(result)
    5743        , m_left(left)
    5844        , m_right(right)
    59         , m_operandsConstness(operandsConstness)
    60         , m_rightConstInt32(rightConstInt32)
    6145        , m_leftType(leftType)
    6246        , m_rightType(rightType)
     47        , m_leftIsConstInt32(leftIsConstInt32)
     48        , m_rightIsConstInt32(rightIsConstInt32)
     49        , m_leftConstInt32(leftConstInt32)
     50        , m_rightConstInt32(rightConstInt32)
    6351        , m_leftFPR(leftFPR)
    6452        , m_rightFPR(rightFPR)
    6553        , m_scratchGPR(scratchGPR)
    6654        , m_scratchFPR(scratchFPR)
    67     { }
     55    {
     56        ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
     57    }
    6858
    6959    void generateFastPath(CCallHelpers&);
     
    7666    JSValueRegs m_left;
    7767    JSValueRegs m_right;
    78     OperandsConstness m_operandsConstness;
    79     int32_t m_rightConstInt32;
    8068    ResultType m_leftType;
    8169    ResultType m_rightType;
     70    bool m_leftIsConstInt32;
     71    bool m_rightIsConstInt32;
     72    int32_t m_leftConstInt32;
     73    int32_t m_rightConstInt32;
    8274    FPRReg m_leftFPR;
    8375    FPRReg m_rightFPR;
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r192295 r192531  
    935935    bool leftIsConstInt32 = isOperandConstantInt(op1);
    936936    bool rightIsConstInt32 = isOperandConstantInt(op2);
    937     JITAddGenerator::OperandsConstness operandsConstness;
    938     int32_t rightConstInt32 = 0;
    939937    ResultType leftType = types.first();
    940938    ResultType rightType = types.second();
     939    int32_t leftConstInt32 = 0;
     940    int32_t rightConstInt32 = 0;
    941941
    942942    ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
    943943
    944944    if (leftIsConstInt32) {
    945         // JITAddGenerator expects the const value in the right operand.
    946         // Let's swap the operands.
    947         operandsConstness = JITAddGenerator::RightIsConstInt32;
    948         rightConstInt32 = getOperandConstantInt(op1);
    949         rightType = types.first();
    950         emitGetVirtualRegister(op2, leftRegs);
    951         leftType = types.second();
     945        leftConstInt32 = getOperandConstantInt(op1);
     946        emitGetVirtualRegister(op2, rightRegs);
    952947    } else if (rightIsConstInt32) {
    953         operandsConstness = JITAddGenerator::RightIsConstInt32;
     948        emitGetVirtualRegister(op1, leftRegs);
    954949        rightConstInt32 = getOperandConstantInt(op2);
    955         emitGetVirtualRegister(op1, leftRegs);
    956     } else {
    957         operandsConstness = JITAddGenerator::NeitherAreConstInt32;
     950    } else {
    958951        emitGetVirtualRegister(op1, leftRegs);
    959952        emitGetVirtualRegister(op2, rightRegs);
    960953    }
    961954
    962     JITAddGenerator gen(resultRegs, leftRegs, rightRegs,
    963         operandsConstness, rightConstInt32,
    964         leftType, rightType,
     955    JITAddGenerator gen(resultRegs, leftRegs, rightRegs, leftType, rightType,
     956        leftIsConstInt32, rightIsConstInt32, leftConstInt32, rightConstInt32,
    965957        fpRegT0, fpRegT1, scratchGPR, scratchFPR);
    966958
  • trunk/Source/JavaScriptCore/tests/stress/op_add.js

    r192003 r192531  
    319319var errorReport = "";
    320320
     321function stringifyIfNeeded(x) {
     322    if (typeof x == "string")
     323        return '"' + x + '"';
     324    return x;
     325}
     326
    321327function runTest(test) {
    322328    var failedScenario = [];
     
    328334                var scenario = scenarios[scenarioID];
    329335                if (verbose)
    330                     print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + scenario.expected);
     336                    print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + stringifyIfNeeded(scenario.expected));
    331337
    332338                var result = testFunc(scenario.x, scenario.y);
     
    336342                    continue;
    337343                if (!failedScenario[scenarioID]) {
    338                     errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i + ": expected " + scenario.expected + ", actual " + result + "\n";
     344                    errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i
     345                        + ": expected " + stringifyIfNeeded(scenario.expected) + ", actual " + stringifyIfNeeded(result) + "\n";
    339346                    if (abortOnFirstFail)
    340347                        throw errorReport;
Note: See TracChangeset for help on using the changeset viewer.