Changeset 192993 in webkit


Ignore:
Timestamp:
Dec 2, 2015 9:42:56 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

Polymorphic operand types for DFG and FTL mul.
https://bugs.webkit.org/show_bug.cgi?id=151746

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Perf on benchmarks is neutral except for the newly added JSRegress ftl-object-mul
test which shows a 2.16x speed up on x86_64 FTL, 1.27x speed up on x86_64 DFG,
and 1.56x on x86 DFG.

The speed up comes not from the mul operator itself, but from the fact that the
polymorphic operand types support now allow the test function to run without OSR
exiting, thereby realizing the DFG and FTL's speed up on other work that the test
function does.

This patch has passed the layout tests on x86_64 with a debug build.
It passed the JSC tests with x86 and x86_64 debug builds.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithMul):

  • ftl/FTLCompile.cpp:
  • Changed to call generateBinaryOpFastPath() instead now, and let it dispatch to the appropriate snippet generator.
  • ftl/FTLCompileBinaryOp.cpp:

(JSC::FTL::generateBinaryArithOpFastPath):
(JSC::FTL::generateBinaryOpFastPath):
(JSC::FTL::generateArithSubFastPath): Deleted.
(JSC::FTL::generateValueAddFastPath): Deleted.

  • Refactored these functions to eliminate the need for copy-pasting every time we add support for another binary arithmetic snippet.
  • ftl/FTLCompileBinaryOp.h:
  • ftl/FTLInlineCacheDescriptor.h:
  • ftl/FTLInlineCacheDescriptorInlines.h:

(JSC::FTL::ArithMulDescriptor::ArithMulDescriptor):
(JSC::FTL::ArithMulDescriptor::icSize):

  • ftl/FTLInlineCacheSize.cpp:

(JSC::FTL::sizeOfArithMul):

  • ftl/FTLInlineCacheSize.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::lower):
(JSC::FTL::DFG::LowerDFGToLLVM::compileArithMul):

  • jit/JITMulGenerator.h:

(JSC::JITMulGenerator::JITMulGenerator):

  • tests/stress/op_mul.js:
  • Updated a test value: the interesting value for imminent overflow from an int32 is 0x7fffffff, not 0x7ffffff.

LayoutTests:

  • js/regress/ftl-object-mul-expected.txt: Added.
  • js/regress/ftl-object-mul.html: Added.
  • js/regress/script-tests/ftl-object-mul.js: Added.

(o1.valueOf):
(foo):

Location:
trunk
Files:
3 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r192992 r192993  
     12015-12-02  Mark Lam  <mark.lam@apple.com>
     2
     3        Polymorphic operand types for DFG and FTL mul.
     4        https://bugs.webkit.org/show_bug.cgi?id=151746
     5
     6        Reviewed by Filip Pizlo.
     7
     8        * js/regress/ftl-object-mul-expected.txt: Added.
     9        * js/regress/ftl-object-mul.html: Added.
     10        * js/regress/script-tests/ftl-object-mul.js: Added.
     11        (o1.valueOf):
     12        (foo):
     13
    1142015-12-02  Myles C. Maxfield  <mmaxfield@apple.com>
    215
  • trunk/Source/JavaScriptCore/ChangeLog

    r192991 r192993  
     12015-12-02  Mark Lam  <mark.lam@apple.com>
     2
     3        Polymorphic operand types for DFG and FTL mul.
     4        https://bugs.webkit.org/show_bug.cgi?id=151746
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Perf on benchmarks is neutral except for the newly added JSRegress ftl-object-mul
     9        test which shows a 2.16x speed up on x86_64 FTL, 1.27x speed up on x86_64 DFG,
     10        and 1.56x on x86 DFG.
     11
     12        The speed up comes not from the mul operator itself, but from the fact that the
     13        polymorphic operand types support now allow the test function to run without OSR
     14        exiting, thereby realizing the DFG and FTL's speed up on other work that the test
     15        function does.
     16
     17        This patch has passed the layout tests on x86_64 with a debug build.
     18        It passed the JSC tests with x86 and x86_64 debug builds.
     19
     20        * dfg/DFGAbstractInterpreterInlines.h:
     21        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     22        * dfg/DFGClobberize.h:
     23        (JSC::DFG::clobberize):
     24        * dfg/DFGFixupPhase.cpp:
     25        (JSC::DFG::FixupPhase::fixupNode):
     26        * dfg/DFGOperations.cpp:
     27        * dfg/DFGOperations.h:
     28        * dfg/DFGPredictionPropagationPhase.cpp:
     29        (JSC::DFG::PredictionPropagationPhase::propagate):
     30        * dfg/DFGSpeculativeJIT.cpp:
     31        (JSC::DFG::SpeculativeJIT::compileArithMul):
     32        * ftl/FTLCompile.cpp:
     33        - Changed to call generateBinaryOpFastPath() instead now, and let it dispatch to
     34          the appropriate snippet generator.
     35
     36        * ftl/FTLCompileBinaryOp.cpp:
     37        (JSC::FTL::generateBinaryArithOpFastPath):
     38        (JSC::FTL::generateBinaryOpFastPath):
     39        (JSC::FTL::generateArithSubFastPath): Deleted.
     40        (JSC::FTL::generateValueAddFastPath): Deleted.
     41        - Refactored these functions to eliminate the need for copy-pasting every time
     42          we add support for another binary arithmetic snippet.
     43
     44        * ftl/FTLCompileBinaryOp.h:
     45        * ftl/FTLInlineCacheDescriptor.h:
     46        * ftl/FTLInlineCacheDescriptorInlines.h:
     47        (JSC::FTL::ArithMulDescriptor::ArithMulDescriptor):
     48        (JSC::FTL::ArithMulDescriptor::icSize):
     49        * ftl/FTLInlineCacheSize.cpp:
     50        (JSC::FTL::sizeOfArithMul):
     51        * ftl/FTLInlineCacheSize.h:
     52        * ftl/FTLLowerDFGToLLVM.cpp:
     53        (JSC::FTL::DFG::LowerDFGToLLVM::lower):
     54        (JSC::FTL::DFG::LowerDFGToLLVM::compileArithMul):
     55        * jit/JITMulGenerator.h:
     56        (JSC::JITMulGenerator::JITMulGenerator):
     57
     58        * tests/stress/op_mul.js:
     59        - Updated a test value: the interesting value for imminent overflow from an
     60          int32 is 0x7fffffff, not 0x7ffffff.
     61
    1622015-12-02  Joseph Pecoraro  <pecoraro@apple.com>
    263
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r192949 r192993  
    634634                typeOfDoubleProduct(
    635635                    forNode(node->child1()).m_type, forNode(node->child2()).m_type));
     636            break;
     637        case UntypedUse:
     638            clobberWorld(node->origin.semantic, clobberLimit);
     639            forNode(node).setType(m_graph, SpecBytecodeNumber);
    636640            break;
    637641        default:
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r192952 r192993  
    249249    case ArithAdd:
    250250    case ArithNegate:
    251     case ArithMul:
    252251    case ArithDiv:
    253252    case ArithMod:
     
    258257
    259258    case ArithSub:
     259    case ArithMul:
    260260        switch (node->binaryUseKind()) {
    261261        case Int32Use:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r192882 r192993  
    228228           
    229229        case ArithMul: {
     230            Edge& leftChild = node->child1();
     231            Edge& rightChild = node->child2();
     232            if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())
     233                || m_graph.hasExitSite(node->origin.semantic, BadType)) {
     234                fixEdge<UntypedUse>(leftChild);
     235                fixEdge<UntypedUse>(rightChild);
     236                node->setResult(NodeResultJS);
     237                break;
     238            }
    230239            if (m_graph.mulShouldSpeculateInt32(node, FixupPass)) {
    231                 fixIntOrBooleanEdge(node->child1());
    232                 fixIntOrBooleanEdge(node->child2());
     240                fixIntOrBooleanEdge(leftChild);
     241                fixIntOrBooleanEdge(rightChild);
    233242                if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
    234243                    node->setArithMode(Arith::Unchecked);
     
    240249            }
    241250            if (m_graph.mulShouldSpeculateMachineInt(node, FixupPass)) {
    242                 fixEdge<Int52RepUse>(node->child1());
    243                 fixEdge<Int52RepUse>(node->child2());
     251                fixEdge<Int52RepUse>(leftChild);
     252                fixEdge<Int52RepUse>(rightChild);
    244253                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
    245254                    node->setArithMode(Arith::CheckOverflow);
     
    249258                break;
    250259            }
    251             fixDoubleOrBooleanEdge(node->child1());
    252             fixDoubleOrBooleanEdge(node->child2());
     260            fixDoubleOrBooleanEdge(leftChild);
     261            fixDoubleOrBooleanEdge(rightChild);
    253262            node->setResult(NodeResultDouble);
    254263            break;
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r192814 r192993  
    201201}
    202202
     203EncodedJSValue JIT_OPERATION operationValueMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
     204{
     205    VM* vm = &exec->vm();
     206    NativeCallFrameTracer tracer(vm, exec);
     207
     208    JSValue op1 = JSValue::decode(encodedOp1);
     209    JSValue op2 = JSValue::decode(encodedOp2);
     210
     211    double a = op1.toNumber(exec);
     212    double b = op2.toNumber(exec);
     213    return JSValue::encode(jsNumber(a * b));
     214}
     215
    203216EncodedJSValue JIT_OPERATION operationValueSub(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
    204217{
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r192814 r192993  
    4646EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    4747EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
     48EncodedJSValue JIT_OPERATION operationValueMul(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    4849EncodedJSValue JIT_OPERATION operationValueSub(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    4950EncodedJSValue JIT_OPERATION operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r192949 r192993  
    335335           
    336336            if (left && right) {
    337                 if (m_graph.mulShouldSpeculateInt32(node, m_pass))
    338                     changed |= mergePrediction(SpecInt32);
    339                 else if (m_graph.mulShouldSpeculateMachineInt(node, m_pass))
    340                     changed |= mergePrediction(SpecInt52);
    341                 else
    342                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
     337                if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
     338                    && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
     339                    if (m_graph.mulShouldSpeculateInt32(node, m_pass))
     340                        changed |= mergePrediction(SpecInt32);
     341                    else if (m_graph.mulShouldSpeculateMachineInt(node, m_pass))
     342                        changed |= mergePrediction(SpecInt52);
     343                    else
     344                        changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
     345                } else
     346                    changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
    343347            }
    344348            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r192882 r192993  
    4040#include "DirectArguments.h"
    4141#include "JITAddGenerator.h"
     42#include "JITMulGenerator.h"
    4243#include "JITSubGenerator.h"
    4344#include "JSArrowFunction.h"
     
    34443445        return;
    34453446    }
    3446        
     3447
     3448    case UntypedUse: {
     3449        Edge& leftChild = node->child1();
     3450        Edge& rightChild = node->child2();
     3451
     3452        if (isKnownNotNumber(leftChild.node()) || isKnownNotNumber(rightChild.node())) {
     3453            JSValueOperand left(this, leftChild);
     3454            JSValueOperand right(this, rightChild);
     3455            JSValueRegs leftRegs = left.jsValueRegs();
     3456            JSValueRegs rightRegs = right.jsValueRegs();
     3457#if USE(JSVALUE64)
     3458            GPRTemporary result(this);
     3459            JSValueRegs resultRegs = JSValueRegs(result.gpr());
     3460#else
     3461            GPRTemporary resultTag(this);
     3462            GPRTemporary resultPayload(this);
     3463            JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
     3464#endif
     3465            flushRegisters();
     3466            callOperation(operationValueMul, resultRegs, leftRegs, rightRegs);
     3467            m_jit.exceptionCheck();
     3468
     3469            jsValueResult(resultRegs, node);
     3470            return;
     3471        }
     3472
     3473        Optional<JSValueOperand> left;
     3474        Optional<JSValueOperand> right;
     3475
     3476        JSValueRegs leftRegs;
     3477        JSValueRegs rightRegs;
     3478
     3479        FPRTemporary leftNumber(this);
     3480        FPRTemporary rightNumber(this);
     3481        FPRReg leftFPR = leftNumber.fpr();
     3482        FPRReg rightFPR = rightNumber.fpr();
     3483
     3484#if USE(JSVALUE64)
     3485        GPRTemporary result(this);
     3486        JSValueRegs resultRegs = JSValueRegs(result.gpr());
     3487        GPRTemporary scratch(this);
     3488        GPRReg scratchGPR = scratch.gpr();
     3489        FPRReg scratchFPR = InvalidFPRReg;
     3490#else
     3491        GPRTemporary resultTag(this);
     3492        GPRTemporary resultPayload(this);
     3493        JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
     3494        GPRReg scratchGPR = resultTag.gpr();
     3495        FPRTemporary fprScratch(this);
     3496        FPRReg scratchFPR = fprScratch.fpr();
     3497#endif
     3498
     3499        SnippetOperand leftOperand(m_state.forNode(leftChild).resultType());
     3500        SnippetOperand rightOperand(m_state.forNode(rightChild).resultType());
     3501
     3502        if (leftChild->isInt32Constant())
     3503            leftOperand.setConstInt32(leftChild->asInt32());
     3504        if (rightChild->isInt32Constant())
     3505            rightOperand.setConstInt32(rightChild->asInt32());
     3506
     3507        RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
     3508
     3509        if (!leftOperand.isPositiveConstInt32()) {
     3510            left = JSValueOperand(this, leftChild);
     3511            leftRegs = left->jsValueRegs();
     3512        }
     3513        if (!rightOperand.isPositiveConstInt32()) {
     3514            right = JSValueOperand(this, rightChild);
     3515            rightRegs = right->jsValueRegs();
     3516        }
     3517
     3518        JITMulGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs,
     3519            leftFPR, rightFPR, scratchGPR, scratchFPR);
     3520        gen.generateFastPath(m_jit);
     3521
     3522        ASSERT(gen.didEmitFastPath());
     3523        gen.endJumpList().append(m_jit.jump());
     3524
     3525        gen.slowPathJumpList().link(&m_jit);
     3526        silentSpillAllRegisters(resultRegs);
     3527
     3528        if (leftOperand.isPositiveConstInt32()) {
     3529            leftRegs = resultRegs;
     3530            int64_t leftConst = leftOperand.asConstInt32();
     3531            m_jit.moveValue(JSValue(leftConst), leftRegs);
     3532        }
     3533        if (rightOperand.isPositiveConstInt32()) {
     3534            rightRegs = resultRegs;
     3535            int64_t rightConst = rightOperand.asConstInt32();
     3536            m_jit.moveValue(JSValue(rightConst), rightRegs);
     3537        }
     3538
     3539        callOperation(operationValueMul, resultRegs, leftRegs, rightRegs);
     3540
     3541        silentFillAllRegisters(resultRegs);
     3542        m_jit.exceptionCheck();
     3543
     3544        gen.endJumpList().link(&m_jit);
     3545        jsValueResult(resultRegs, node);
     3546        return;
     3547    }
     3548
    34473549    default:
    34483550        RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp

    r192950 r192993  
    337337        CCallHelpers::Jump slowPathStart;
    338338
    339         switch (ic.nodeType()) {
    340         case ArithSub:
    341             generateArithSubFastPath(ic, fastPathJIT, result, left, right, usedRegisters, done, slowPathStart);
    342             break;
    343         case ValueAdd:
    344             generateValueAddFastPath(ic, fastPathJIT, result, left, right, usedRegisters, done, slowPathStart);
    345             break;
    346         default:
    347             RELEASE_ASSERT_NOT_REACHED();
    348         }
     339        generateBinaryOpFastPath(ic, fastPathJIT, result, left, right, usedRegisters, done, slowPathStart);
    349340
    350341        char* startOfIC = bitwise_cast<char*>(generatedFunction) + record.instructionOffset;
  • trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp

    r192950 r192993  
    3333#include "GPRInfo.h"
    3434#include "JITAddGenerator.h"
     35#include "JITMulGenerator.h"
    3536#include "JITSubGenerator.h"
    3637#include "ScratchRegisterAllocator.h"
     
    153154};
    154155
    155 void generateArithSubFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
     156template<typename BinaryArithOpGenerator>
     157void generateBinaryArithOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
    156158    GPRReg result, GPRReg left, GPRReg right, RegisterSet usedRegisters,
    157159    CCallHelpers::Jump& done, CCallHelpers::Jump& slowPathStart)
    158160{
    159     ASSERT(ic.nodeType() == ArithSub);
    160161    ScratchRegisterAllocator allocator(usedRegisters);
    161162
     
    167168    FPRReg scratchFPR = InvalidFPRReg;
    168169
    169     JITSubGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
     170    BinaryArithOpGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
    170171        JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR);
    171172
     
    190191}
    191192
    192 void generateValueAddFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
     193void generateBinaryOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
    193194    GPRReg result, GPRReg left, GPRReg right, RegisterSet usedRegisters,
    194195    CCallHelpers::Jump& done, CCallHelpers::Jump& slowPathStart)
    195196{
    196     ASSERT(ic.nodeType() == ValueAdd);
    197     ScratchRegisterAllocator allocator(usedRegisters);
    198 
    199     BinarySnippetRegisterContext context(allocator, result, left, right);
    200 
    201     GPRReg scratchGPR = allocator.allocateScratchGPR();
    202     FPRReg leftFPR = allocator.allocateScratchFPR();
    203     FPRReg rightFPR = allocator.allocateScratchFPR();
    204     FPRReg scratchFPR = InvalidFPRReg;
    205 
    206     JITAddGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
    207         JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR);
    208 
    209     auto numberOfBytesUsedToPreserveReusedRegisters =
    210     allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    211 
    212     context.initializeRegisters(jit);
    213     gen.generateFastPath(jit);
    214 
    215     ASSERT(gen.didEmitFastPath());
    216     gen.endJumpList().link(&jit);
    217     context.restoreRegisters(jit);
    218     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    219         ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
    220     done = jit.jump();
    221 
    222     gen.slowPathJumpList().link(&jit);
    223     context.restoreRegisters(jit);
    224     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    225         ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
    226     slowPathStart = jit.jump();
     197    switch (ic.nodeType()) {
     198    case ArithMul:
     199        generateBinaryArithOpFastPath<JITMulGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart);
     200        break;
     201    case ArithSub:
     202        generateBinaryArithOpFastPath<JITSubGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart);
     203        break;
     204    case ValueAdd:
     205        generateBinaryArithOpFastPath<JITAddGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart);
     206        break;
     207    default:
     208        RELEASE_ASSERT_NOT_REACHED();
     209    }
    227210}
    228211
  • trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.h

    r192950 r192993  
    3636class BinaryOpDescriptor;
    3737
    38 void generateArithSubFastPath(BinaryOpDescriptor&, CCallHelpers&,
    39     GPRReg result, GPRReg left, GPRReg right, RegisterSet usedRegisters,
    40     CCallHelpers::Jump& done, CCallHelpers::Jump& slowPathStart);
    41 
    42 void generateValueAddFastPath(BinaryOpDescriptor&, CCallHelpers&,
     38void generateBinaryOpFastPath(BinaryOpDescriptor&, CCallHelpers&,
    4339    GPRReg result, GPRReg left, GPRReg right, RegisterSet usedRegisters,
    4440    CCallHelpers::Jump& done, CCallHelpers::Jump& slowPathStart);
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h

    r192950 r192993  
    166166};
    167167
     168class ArithMulDescriptor : public BinaryOpDescriptor {
     169public:
     170    ArithMulDescriptor(unsigned stackmapID, CodeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand);
     171    static size_t icSize();
     172};
     173
    168174class ArithSubDescriptor : public BinaryOpDescriptor {
    169175public:
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptorInlines.h

    r192950 r192993  
    3636namespace JSC { namespace FTL {
    3737
     38ArithMulDescriptor::ArithMulDescriptor(unsigned stackmapID, CodeOrigin codeOrigin,
     39    const SnippetOperand& leftOperand, const SnippetOperand& rightOperand)
     40    : BinaryOpDescriptor(DFG::ArithMul, stackmapID, codeOrigin, icSize(),
     41        "ArithMul", "ArithMul IC fast path", DFG::operationValueMul, leftOperand, rightOperand)
     42{
     43}
     44
     45size_t ArithMulDescriptor::icSize()
     46{
     47    return sizeOfArithMul();
     48}
     49
    3850ArithSubDescriptor::ArithSubDescriptor(unsigned stackmapID, CodeOrigin codeOrigin,
    3951    const SnippetOperand& leftOperand, const SnippetOperand& rightOperand)
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp

    r192950 r192993  
    126126#else
    127127    return 5;
     128#endif
     129}
     130
     131size_t sizeOfArithMul()
     132{
     133#if CPU(ARM64)
     134#ifdef NDEBUG
     135    return 180; // ARM64 release.
     136#else
     137    return 276; // ARM64 debug.
     138#endif
     139#else // CPU(X86_64)
     140#ifdef NDEBUG
     141    return 199; // X86_64 release.
     142#else
     143    return 286; // X86_64 debug.
     144#endif
    128145#endif
    129146}
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h

    r192950 r192993  
    4747size_t sizeOfConstructForwardVarargs();
    4848size_t sizeOfIn();
     49size_t sizeOfArithMul();
    4950size_t sizeOfArithSub();
    5051size_t sizeOfValueAdd();
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r192950 r192993  
    233233                        break;
    234234                    }
     235                    case ArithMul:
    235236                    case ArithSub:
    236237                    case GetById:
     
    14861487    void compileValueAdd()
    14871488    {
    1488         auto leftChild = m_node->child1();
    1489         auto rightChild = m_node->child2();
     1489        Edge& leftChild = m_node->child1();
     1490        Edge& rightChild = m_node->child2();
    14901491
    14911492        if (!(provenType(leftChild) & SpecFullNumber) || !(provenType(rightChild) & SpecFullNumber)) {
     
    18101811            break;
    18111812        }
    1812            
     1813
     1814        case UntypedUse: {
     1815            Edge& leftChild = m_node->child1();
     1816            Edge& rightChild = m_node->child2();
     1817
     1818            if (!(provenType(leftChild) & SpecFullNumber) || !(provenType(rightChild) & SpecFullNumber)) {
     1819                setJSValue(vmCall(m_out.int64, m_out.operation(operationValueMul), m_callFrame,
     1820                    lowJSValue(leftChild), lowJSValue(rightChild)));
     1821                return;
     1822            }
     1823
     1824            unsigned stackmapID = m_stackmapIDs++;
     1825
     1826            if (Options::verboseCompilation())
     1827                dataLog("    Emitting ArithMul patchpoint with stackmap #", stackmapID, "\n");
     1828
     1829#if FTL_USES_B3
     1830            CRASH();
     1831#else
     1832            LValue left = lowJSValue(leftChild);
     1833            LValue right = lowJSValue(rightChild);
     1834
     1835            SnippetOperand leftOperand(abstractValue(leftChild).resultType());
     1836            SnippetOperand rightOperand(abstractValue(rightChild).resultType());
     1837
     1838            if (leftChild->isInt32Constant())
     1839                leftOperand.setConstInt32(leftChild->asInt32());
     1840            if (rightChild->isInt32Constant())
     1841                rightOperand.setConstInt32(rightChild->asInt32());
     1842
     1843            RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
     1844
     1845            // Arguments: id, bytes, target, numArgs, args...
     1846            StackmapArgumentList arguments;
     1847            arguments.append(m_out.constInt64(stackmapID));
     1848            arguments.append(m_out.constInt32(ArithSubDescriptor::icSize()));
     1849            arguments.append(constNull(m_out.ref8));
     1850            arguments.append(m_out.constInt32(2));
     1851            arguments.append(left);
     1852            arguments.append(right);
     1853
     1854            appendOSRExitArgumentsForPatchpointIfWillCatchException(arguments,
     1855                ExceptionType::BinaryOpGenerator, 3); // left, right, and result show up in the stackmap locations.
     1856
     1857            LValue call = m_out.call(m_out.int64, m_out.patchpointInt64Intrinsic(), arguments);
     1858            setInstructionCallingConvention(call, LLVMAnyRegCallConv);
     1859
     1860            m_ftlState.binaryOps.append(ArithMulDescriptor(stackmapID, m_node->origin.semantic, leftOperand, rightOperand));
     1861
     1862            setJSValue(call);
     1863#endif
     1864            break;
     1865        }
     1866
    18131867        default:
    18141868            DFG_CRASH(m_graph, m_node, "Bad use kind");
  • trunk/Source/JavaScriptCore/jit/JITMulGenerator.h

    r192842 r192993  
    3838    JITMulGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
    3939        JSValueRegs result, JSValueRegs left, JSValueRegs right,
    40         FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR, uint32_t* profilingCounter)
     40        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR, uint32_t* profilingCounter = nullptr)
    4141        : m_leftOperand(leftOperand)
    4242        , m_rightOperand(rightOperand)
  • trunk/Source/JavaScriptCore/tests/stress/op_mul.js

    r192664 r192993  
    4444    '0x10000',
    4545    '-0x10000',
    46     '0x7ffffff',
    47     '-0x7ffffff',
     46    '0x7fffffff',
     47    '-0x7fffffff',
    4848    '0x100000000',
    4949    '-0x100000000',
     
    6060    '"0x10000"',
    6161    '"-0x10000"',
    62     '"0x7ffffff"',
    63     '"-0x7ffffff"',
     62    '"0x7fffffff"',
     63    '"-0x7fffffff"',
    6464    '"0x100000000"',
    6565    '"-0x100000000"',
Note: See TracChangeset for help on using the changeset viewer.