Changeset 247387 in webkit


Ignore:
Timestamp:
Jul 12, 2019 7:47:36 AM (5 years ago)
Author:
Caio Lima
Message:

[BigInt] Add ValueBitLShift into DFG
https://bugs.webkit.org/show_bug.cgi?id=192664

Reviewed by Saam Barati.

JSTests:

We are adding tests to cover ValueBitwise operations AI changes.

  • stress/big-int-left-shift-untyped.js: Added.
  • stress/bit-op-with-object-returning-int32.js:
  • stress/value-bit-and-ai-rule.js: Added.
  • stress/value-bit-lshift-ai-rule.js: Added.
  • stress/value-bit-or-ai-rule.js: Added.
  • stress/value-bit-xor-ai-rule.js: Added.

PerformanceTests:

  • BigIntBench/big-int-simple-lshift.js: Added.

Source/JavaScriptCore:

This patch is splitting the BitLShift into ArithBitLShift and
ValueBitLShift to handle BigInt speculation more efficiently during
DFG and FTL layers. Following the same approach of other ValueBitOps,
ValueBitLShift handles Untyped and BigInt speculations, while
ArithBitLShift handles number and boolean operands and always results into
Int32.

  • bytecode/BytecodeList.rb:
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):

  • bytecode/Opcode.h:
  • dfg/DFGAbstractInterpreter.h:
  • dfg/DFGAbstractInterpreterInlines.h:

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

We moved BitLShift constant fold rules to a new method
handleConstantBinaryBitwiseOp to be reused by ArithBitLShift and
ValueBitLShift. This also enables support of constant folding on other
bitwise operations like ValueBitAnd, ValueBitOr and ValueBitXor, when
their binary use kind is UntypedUse. Such cases can happen on those
nodes because fixup phase is conservative.

  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
(JSC::DFG::ByteCodeParser::parseBlock):

We parse op_lshift as ArithBitLShift when its operands are numbers.
Otherwise, we fallback to ValueBitLShift and rely on fixup phase to
convert ValueBitLShift into ArithBitLShift when possible.

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

ArithBitLShift has the same clobberize rules as former BitLShift.
ValueBitLShift only clobberize world when it is UntypedUse.

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

ValueBitLShift can GC when BigIntUse because it allocates new
JSBigInts to perform this operation. It also can GC on UntypedUse
because of observable user code.

  • dfg/DFGFixupPhase.cpp:

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

ValueBitLShift and ArithBitLShift has the same fixup rules of
other binary bitwise operations. In the case of ValueBitLShift
We check if we should speculate on BigInt or Untyped and fallback to
ArithBitLShift when both cheks fail.

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasHeapPrediction):

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

We updated operationValueBitLShift to handle BigInt cases. Also, we
added operationBitLShiftBigInt that is used when we compile
ValueBitLValueBitLShift(BigIntUse).

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

ValueBitLShift's prediction propagation rules differs from other
bitwise operations, because using only heap prediction for this node causes
significant performance regression on Octane's zlib and mandreel.
The reason is because of cases where a function is compiled but the
instruction op_lshift was never executed before. If we use
getPrediction() we will emit a ForceOSRExit, resulting in more OSR
than desired. To solve such issue, we are then using
getPredictionWithoutOSR() and falling back to getHeapPrediction()
only on cases where we can't rely on node's input types.

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileValueLShiftOp):
(JSC::DFG::SpeculativeJIT::compileShiftOp):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::shiftOp):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileArithBitLShift):
(JSC::FTL::DFG::LowerDFGToB3::compileValueBitLShift):
(JSC::FTL::DFG::LowerDFGToB3::compileBitLShift): Deleted.

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

Location:
trunk
Files:
6 added
30 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r247363 r247387  
     12019-07-12  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [BigInt] Add ValueBitLShift into DFG
     4        https://bugs.webkit.org/show_bug.cgi?id=192664
     5
     6        Reviewed by Saam Barati.
     7
     8        We are adding tests to cover ValueBitwise operations AI changes.
     9
     10        * stress/big-int-left-shift-untyped.js: Added.
     11        * stress/bit-op-with-object-returning-int32.js:
     12        * stress/value-bit-and-ai-rule.js: Added.
     13        * stress/value-bit-lshift-ai-rule.js: Added.
     14        * stress/value-bit-or-ai-rule.js: Added.
     15        * stress/value-bit-xor-ai-rule.js: Added.
     16
    1172019-07-11  Justin Michaud  <justin_michaud@apple.com>
    218
  • trunk/JSTests/stress/bit-op-with-object-returning-int32.js

    r242715 r247387  
    4747assert(numberOfDFGCompiles(bitNot) <= 1, true);
    4848
     49function bitLShift(a, b) {
     50    return a << b;
     51}
     52noInline(bitLShift);
     53
     54for (var i = 0; i < 10000; i++)
     55    assert(bitLShift(o, 3), 0b1101000);
     56
     57assert(numberOfDFGCompiles(bitLShift) <= 1, true);
     58
  • trunk/PerformanceTests/ChangeLog

    r246925 r247387  
     12019-07-12  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [BigInt] Add ValueBitLShift into DFG
     4        https://bugs.webkit.org/show_bug.cgi?id=192664
     5
     6        Reviewed by Saam Barati.
     7
     8        * BigIntBench/big-int-simple-lshift.js: Added.
     9
    1102019-06-28  Konstantin Tokarev  <annulen@yandex.ru>
    211
  • trunk/Source/JavaScriptCore/ChangeLog

    r247386 r247387  
     12019-07-12  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [BigInt] Add ValueBitLShift into DFG
     4        https://bugs.webkit.org/show_bug.cgi?id=192664
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch is splitting the `BitLShift` into `ArithBitLShift` and
     9        `ValueBitLShift` to handle BigInt speculation more efficiently during
     10        DFG and FTL layers. Following the same approach of other `ValueBitOps`,
     11        `ValueBitLShift` handles Untyped and BigInt speculations, while
     12        `ArithBitLShift` handles number and boolean operands and always results into
     13        Int32.
     14
     15        * bytecode/BytecodeList.rb:
     16        * bytecode/CodeBlock.cpp:
     17        (JSC::CodeBlock::finishCreation):
     18        * bytecode/Opcode.h:
     19        * dfg/DFGAbstractInterpreter.h:
     20        * dfg/DFGAbstractInterpreterInlines.h:
     21        (JSC::DFG::AbstractInterpreter<AbstractStateType>::handleConstantBinaryBitwiseOp):
     22        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     23
     24        We moved `BitLShift` constant fold rules to a new method
     25        `handleConstantBinaryBitwiseOp` to be reused by `ArithBitLShift` and
     26        `ValueBitLShift`. This also enables support of constant folding on other
     27        bitwise operations like `ValueBitAnd`, `ValueBitOr` and `ValueBitXor`, when
     28        their binary use kind is UntypedUse. Such cases can happen on those
     29        nodes because fixup phase is conservative.
     30
     31        * dfg/DFGBackwardsPropagationPhase.cpp:
     32        (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
     33        (JSC::DFG::BackwardsPropagationPhase::propagate):
     34        * dfg/DFGByteCodeParser.cpp:
     35        (JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
     36        (JSC::DFG::ByteCodeParser::parseBlock):
     37
     38        We parse `op_lshift` as `ArithBitLShift` when its operands are numbers.
     39        Otherwise, we fallback to `ValueBitLShift` and rely on fixup phase to
     40        convert `ValueBitLShift` into `ArithBitLShift` when possible.
     41
     42        * dfg/DFGClobberize.h:
     43        (JSC::DFG::clobberize):
     44
     45        `ArithBitLShift` has the same clobberize rules as former `BitLShift`.
     46        `ValueBitLShift` only clobberize world when it is UntypedUse.
     47
     48        * dfg/DFGDoesGC.cpp:
     49        (JSC::DFG::doesGC):
     50
     51        `ValueBitLShift` can GC when `BigIntUse` because it allocates new
     52        JSBigInts to perform this operation. It also can GC on UntypedUse
     53        because of observable user code.
     54
     55        * dfg/DFGFixupPhase.cpp:
     56        (JSC::DFG::FixupPhase::fixupNode):
     57
     58        `ValueBitLShift` and `ArithBitLShift` has the same fixup rules of
     59        other binary bitwise operations. In the case of `ValueBitLShift`
     60        We check if we should speculate on BigInt or Untyped and fallback to
     61        `ArithBitLShift` when both cheks fail.
     62
     63        * dfg/DFGNode.h:
     64        (JSC::DFG::Node::hasHeapPrediction):
     65        * dfg/DFGNodeType.h:
     66        * dfg/DFGOperations.cpp:
     67
     68        We updated `operationValueBitLShift` to handle BigInt cases. Also, we
     69        added `operationBitLShiftBigInt` that is used when we compile
     70        `ValueBitLValueBitLShift(BigIntUse)`.
     71
     72        * dfg/DFGOperations.h:
     73        * dfg/DFGPredictionPropagationPhase.cpp:
     74
     75        `ValueBitLShift`'s prediction propagation rules differs from other
     76        bitwise operations, because using only heap prediction for this node causes
     77        significant performance regression on Octane's zlib and mandreel.
     78        The reason is because of cases where a function is compiled but the
     79        instruction `op_lshift` was never executed before. If we use
     80        `getPrediction()` we will emit a `ForceOSRExit`, resulting in more OSR
     81        than desired. To solve such issue, we are then using
     82        `getPredictionWithoutOSR()` and falling back to `getHeapPrediction()`
     83        only on cases where we can't rely on node's input types.
     84
     85        * dfg/DFGSafeToExecute.h:
     86        (JSC::DFG::safeToExecute):
     87        * dfg/DFGSpeculativeJIT.cpp:
     88        (JSC::DFG::SpeculativeJIT::compileValueLShiftOp):
     89        (JSC::DFG::SpeculativeJIT::compileShiftOp):
     90        * dfg/DFGSpeculativeJIT.h:
     91        (JSC::DFG::SpeculativeJIT::shiftOp):
     92        * dfg/DFGSpeculativeJIT32_64.cpp:
     93        (JSC::DFG::SpeculativeJIT::compile):
     94        * dfg/DFGSpeculativeJIT64.cpp:
     95        (JSC::DFG::SpeculativeJIT::compile):
     96        * dfg/DFGStrengthReductionPhase.cpp:
     97        (JSC::DFG::StrengthReductionPhase::handleNode):
     98        * ftl/FTLCapabilities.cpp:
     99        (JSC::FTL::canCompile):
     100        * ftl/FTLLowerDFGToB3.cpp:
     101        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     102        (JSC::FTL::DFG::LowerDFGToB3::compileArithBitLShift):
     103        (JSC::FTL::DFG::LowerDFGToB3::compileValueBitLShift):
     104        (JSC::FTL::DFG::LowerDFGToB3::compileBitLShift): Deleted.
     105        * llint/LowLevelInterpreter32_64.asm:
     106        * llint/LowLevelInterpreter64.asm:
     107        * runtime/CommonSlowPaths.cpp:
     108        (JSC::SLOW_PATH_DECL):
     109
    11102019-07-12  Keith Miller  <keith_miller@apple.com>
    2111
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb

    r245906 r247387  
    227227        :mod,
    228228        :pow,
    229         :lshift,
    230229        :rshift,
    231230        :urshift,
     
    262261        :bitor,
    263262        :bitxor,
     263        :lshift,
    264264    ],
    265265    args: {
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r246505 r247387  
    546546        LINK(OpBitnot, profile)
    547547        LINK(OpBitxor, profile)
     548        LINK(OpLshift, profile)
    548549
    549550        LINK(OpGetById, profile)
  • trunk/Source/JavaScriptCore/bytecode/Opcode.h

    r245906 r247387  
    108108    macro(OpBitnot) \
    109109    macro(OpBitxor) \
     110    macro(OpLshift) \
    110111
    111112#define FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(macro) \
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h

    r245063 r247387  
    219219    void didFoldClobberWorld();
    220220   
     221    bool handleConstantBinaryBitwiseOp(Node*);
     222
    221223    template<typename Functor>
    222224    void forAllValues(unsigned indexInBlock, Functor&);
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r246490 r247387  
    235235
    236236template<typename AbstractStateType>
     237bool AbstractInterpreter<AbstractStateType>::handleConstantBinaryBitwiseOp(Node* node)
     238{
     239    JSValue left = forNode(node->child1()).value();
     240    JSValue right = forNode(node->child2()).value();
     241    if (left && right && left.isInt32() && right.isInt32()) {
     242        int32_t a = left.asInt32();
     243        int32_t b = right.asInt32();
     244        if (node->isBinaryUseKind(UntypedUse))
     245            didFoldClobberWorld();
     246        NodeType op = node->op();
     247        switch (op) {
     248        case ValueBitAnd:
     249        case ArithBitAnd:
     250            setConstant(node, JSValue(a & b));
     251            break;
     252        case ValueBitOr:
     253        case ArithBitOr:
     254            setConstant(node, JSValue(a | b));
     255            break;
     256        case ValueBitXor:
     257        case ArithBitXor:
     258            setConstant(node, JSValue(a ^ b));
     259            break;
     260        case BitRShift:
     261            setConstant(node, JSValue(a >> (static_cast<uint32_t>(b) & 0x1f)));
     262            break;
     263        case ValueBitLShift:
     264        case ArithBitLShift:
     265            setConstant(node, JSValue(a << (static_cast<uint32_t>(b) & 0x1f)));
     266            break;
     267        case BitURShift:
     268            setConstant(node, JSValue(static_cast<int32_t>(static_cast<uint32_t>(a) >> (static_cast<uint32_t>(b) & 0x1f))));
     269            break;
     270        default:
     271            RELEASE_ASSERT_NOT_REACHED();
     272            break;
     273        }
     274
     275        return true;
     276    }
     277
     278    return false;
     279}
     280
     281template<typename AbstractStateType>
    237282bool AbstractInterpreter<AbstractStateType>::handleConstantDivOp(Node* node)
    238283{
     
    464509    case ValueBitAnd:
    465510    case ValueBitOr:
     511    case ValueBitLShift: {
     512        if (handleConstantBinaryBitwiseOp(node))
     513            break;
     514
    466515        if (node->binaryUseKind() == BigIntUse)
    467516            setTypeForNode(node, SpecBigInt);
     
    471520        }
    472521        break;
     522    }
    473523           
    474524    case ArithBitAnd:
     
    476526    case ArithBitXor:
    477527    case BitRShift:
    478     case BitLShift:
     528    case ArithBitLShift:
    479529    case BitURShift: {
    480530        if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) {
     
    484534        }
    485535
    486         JSValue left = forNode(node->child1()).value();
    487         JSValue right = forNode(node->child2()).value();
    488         if (left && right && left.isInt32() && right.isInt32()) {
    489             int32_t a = left.asInt32();
    490             int32_t b = right.asInt32();
    491             switch (node->op()) {
    492             case ArithBitAnd:
    493                 setConstant(node, JSValue(a & b));
    494                 break;
    495             case ArithBitOr:
    496                 setConstant(node, JSValue(a | b));
    497                 break;
    498             case ArithBitXor:
    499                 setConstant(node, JSValue(a ^ b));
    500                 break;
    501             case BitRShift:
    502                 setConstant(node, JSValue(a >> (static_cast<uint32_t>(b) & 0x1f)));
    503                 break;
    504             case BitLShift:
    505                 setConstant(node, JSValue(a << (static_cast<uint32_t>(b) & 0x1f)));
    506                 break;
    507             case BitURShift:
    508                 setConstant(node, JSValue(static_cast<int32_t>(static_cast<uint32_t>(a) >> (static_cast<uint32_t>(b) & 0x1f))));
    509                 break;
    510             default:
    511                 RELEASE_ASSERT_NOT_REACHED();
    512                 break;
    513             }
    514             break;
    515         }
     536        if (handleConstantBinaryBitwiseOp(node))
     537            break;
    516538       
    517539        if (node->op() == ArithBitAnd
  • trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp

    r245063 r247387  
    124124        case ValueBitOr:
    125125        case ValueBitXor:
    126         case BitLShift: {
     126        case ValueBitLShift:
     127        case ArithBitLShift: {
    127128            return power > 31;
    128129        }
     
    227228        case ValueBitXor:
    228229        case BitRShift:
    229         case BitLShift:
     230        case ValueBitLShift:
     231        case ArithBitLShift:
    230232        case BitURShift:
    231233        case ArithIMul: {
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r246073 r247387  
    35103510        // that overflows int32.
    35113511        Node* shiftNode = jsConstant(jsNumber(logSize));
    3512         set(result, addToGraph(BitLShift, lengthNode, shiftNode));
     3512        set(result, addToGraph(ArithBitLShift, lengthNode, shiftNode));
    35133513
    35143514        return true;
     
    50325032            Node* op1 = get(bytecode.m_lhs);
    50335033            Node* op2 = get(bytecode.m_rhs);
    5034             set(bytecode.m_dst, addToGraph(BitLShift, op1, op2));
     5034            if (op1->hasNumberOrAnyIntResult() && op2->hasNumberOrAnyIntResult())
     5035                set(bytecode.m_dst, addToGraph(ArithBitLShift, op1, op2));
     5036            else {
     5037                SpeculatedType prediction = getPredictionWithoutOSRExit();
     5038                set(bytecode.m_dst, addToGraph(ValueBitLShift, OpInfo(), OpInfo(prediction), op1, op2));
     5039            }
    50355040            NEXT_OPCODE(op_lshift);
    50365041        }
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r246073 r247387  
    281281    case ArithBitOr:
    282282    case ArithBitXor:
    283     case BitLShift:
     283    case ArithBitLShift:
    284284    case BitRShift:
    285285    case BitURShift:
     
    683683    case ValueMod:
    684684    case ValuePow:
     685    case ValueBitLShift:
    685686        if (node->isBinaryUseKind(BigIntUse)) {
    686687            def(PureValue(node));
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r246041 r247387  
    8585    case ArithBitOr:
    8686    case ArithBitXor:
    87     case BitLShift:
     87    case ArithBitLShift:
    8888    case BitRShift:
    8989    case BitURShift:
     
    376376    case ValueBitOr:
    377377    case ValueBitXor:
     378    case ValueBitLShift:
    378379    case ValueAdd:
    379380    case ValueSub:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r246041 r247387  
    216216        }
    217217
     218        case ValueBitLShift:
    218219        case ValueBitXor:
    219220        case ValueBitOr:
     
    222223                fixEdge<BigIntUse>(node->child1());
    223224                fixEdge<BigIntUse>(node->child2());
     225                node->clearFlags(NodeMustGenerate);
    224226                break;
    225227            }
     
    230232                break;
    231233            }
    232 
    233             // In such case, we need to fallback to ArithBitOp
     234           
    234235            switch (op) {
    235236            case ValueBitXor:
     
    241242            case ValueBitAnd:
    242243                node->setOp(ArithBitAnd);
     244                break;
     245            case ValueBitLShift:
     246                node->setOp(ArithBitLShift);
    243247                break;
    244248            default:
     
    278282        }
    279283
     284        case ArithBitLShift:
    280285        case ArithBitXor:
    281286        case ArithBitOr:
     
    287292
    288293        case BitRShift:
    289         case BitLShift:
    290294        case BitURShift: {
    291295            if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r244238 r247387  
    16951695        case ValueBitXor:
    16961696        case ValueBitNot:
     1697        case ValueBitLShift:
    16971698        case CallObjectConstructor:
    16981699        case LoadKeyFromMapBucket:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r246041 r247387  
    122122    macro(ValueBitXor, NodeResultJS | NodeMustGenerate) \
    123123    macro(ArithBitXor, NodeResultInt32) \
    124     macro(BitLShift, NodeResultInt32) \
     124    macro(ArithBitLShift, NodeResultInt32) \
     125    macro(ValueBitLShift, NodeResultJS | NodeMustGenerate) \
    125126    macro(BitRShift, NodeResultInt32) \
    126127    macro(BitURShift, NodeResultInt32) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r247194 r247387  
    479479EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
    480480{
    481     VM* vm = &exec->vm();
    482     NativeCallFrameTracer tracer(vm, exec);
    483     auto scope = DECLARE_THROW_SCOPE(*vm);
    484 
    485     JSValue op1 = JSValue::decode(encodedOp1);
    486     JSValue op2 = JSValue::decode(encodedOp2);
    487 
    488     int32_t a = op1.toInt32(exec);
    489     RETURN_IF_EXCEPTION(scope, encodedJSValue());
    490     scope.release();
    491     uint32_t b = op2.toUInt32(exec);
    492     return JSValue::encode(jsNumber(a << (b & 0x1f)));
     481    auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
     482        return JSBigInt::leftShift(exec, left, right);
     483    };
     484
     485    auto int32Op = [] (int32_t left, int32_t right) -> int32_t {
     486        return left << (right & 0x1f);
     487    };
     488
     489    return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in left shift operation."_s);
    493490}
    494491
     
    14301427
    14311428    return JSBigInt::bitwiseAnd(exec, leftOperand, rightOperand);
     1429}
     1430
     1431JSCell* JIT_OPERATION operationBitLShiftBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
     1432{
     1433    VM* vm = &exec->vm();
     1434    NativeCallFrameTracer tracer(vm, exec);
     1435
     1436    JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     1437    JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     1438
     1439    return JSBigInt::leftShift(exec, leftOperand, rightOperand);
    14321440}
    14331441
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r246041 r247387  
    177177JSCell* JIT_OPERATION operationBitNotBigInt(ExecState*, JSCell* op1) WTF_INTERNAL;
    178178JSCell* JIT_OPERATION operationBitOrBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
     179JSCell* JIT_OPERATION operationBitLShiftBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
    179180JSCell* JIT_OPERATION operationAddBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
    180181JSCell* JIT_OPERATION operationBitXorBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r246237 r247387  
    177177            else
    178178                changed |= mergePrediction(SpecBytecodeNumber);
     179            break;
     180        }
     181
     182        case ValueBitLShift: {
     183            SpeculatedType left = node->child1()->prediction();
     184            SpeculatedType right = node->child2()->prediction();
     185
     186            if (left && right) {
     187                if (isBigIntSpeculation(left) && isBigIntSpeculation(right))
     188                    changed |= mergePrediction(SpecBigInt);
     189                else if (isFullNumberOrBooleanSpeculationExpectingDefined(left) && isFullNumberOrBooleanSpeculationExpectingDefined(right))
     190                    changed |= mergePrediction(SpecInt32Only);
     191                else
     192                    changed |= mergePrediction(node->getHeapPrediction());
     193            }
     194
    179195            break;
    180196        }
     
    769785        case ArithBitXor:
    770786        case BitRShift:
    771         case BitLShift:
     787        case ArithBitLShift:
    772788        case BitURShift:
    773789        case ArithIMul:
     
    11381154        case ValueMod:
    11391155        case ValuePow:
     1156        case ValueBitLShift:
    11401157        case ArithAdd:
    11411158        case ArithSub:
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r246041 r247387  
    204204    case ArithBitOr:
    205205    case ArithBitXor:
    206     case BitLShift:
     206    case ArithBitLShift:
    207207    case BitRShift:
    208208    case BitURShift:
     
    234234    case ValueBitOr:
    235235    case ValueBitNot:
     236    case ValueBitLShift:
    236237    case ValueNegate:
    237238    case ValueAdd:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r246740 r247387  
    38623862}
    38633863
     3864void SpeculativeJIT::compileValueLShiftOp(Node* node)
     3865{
     3866    Edge& leftChild = node->child1();
     3867    Edge& rightChild = node->child2();
     3868
     3869    if (node->binaryUseKind() == BigIntUse) {
     3870        SpeculateCellOperand left(this, leftChild);
     3871        SpeculateCellOperand right(this, rightChild);
     3872        GPRReg leftGPR = left.gpr();
     3873        GPRReg rightGPR = right.gpr();
     3874
     3875        speculateBigInt(leftChild, leftGPR);
     3876        speculateBigInt(rightChild, rightGPR);
     3877
     3878        flushRegisters();
     3879        GPRFlushedCallResult result(this);
     3880        GPRReg resultGPR = result.gpr();
     3881
     3882        callOperation(operationBitLShiftBigInt, resultGPR, leftGPR, rightGPR);
     3883        m_jit.exceptionCheck();
     3884        cellResult(resultGPR, node);
     3885        return;
     3886    }
     3887
     3888    ASSERT(leftChild.useKind() == UntypedUse && rightChild.useKind() == UntypedUse);
     3889    emitUntypedBitOp<JITLeftShiftGenerator, operationValueBitLShift>(node);
     3890}
     3891
    38643892void SpeculativeJIT::compileShiftOp(Node* node)
    38653893{
     
    38703898    if (leftChild.useKind() == UntypedUse || rightChild.useKind() == UntypedUse) {
    38713899        switch (op) {
    3872         case BitLShift:
    3873             emitUntypedBitOp<JITLeftShiftGenerator, operationValueBitLShift>(node);
    3874             return;
    38753900        case BitRShift:
    38763901        case BitURShift:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r246368 r247387  
    664664            m_jit.rshift32(op1, Imm32(shiftAmount), result);
    665665            break;
    666         case BitLShift:
     666        case ArithBitLShift:
    667667            m_jit.lshift32(op1, Imm32(shiftAmount), result);
    668668            break;
     
    680680            m_jit.rshift32(op1, shiftAmount, result);
    681681            break;
    682         case BitLShift:
     682        case ArithBitLShift:
    683683            m_jit.lshift32(op1, shiftAmount, result);
    684684            break;
     
    13351335
    13361336    void emitUntypedRightShiftBitOp(Node*);
     1337    void compileValueLShiftOp(Node*);
    13371338    void compileShiftOp(Node*);
    13381339
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r246636 r247387  
    20022002        break;
    20032003
     2004    case ValueBitLShift:
     2005        compileValueLShiftOp(node);
     2006        break;
     2007
    20042008    case BitRShift:
    2005     case BitLShift:
     2009    case ArithBitLShift:
    20062010    case BitURShift:
    20072011        compileShiftOp(node);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r246636 r247387  
    21012101        break;
    21022102
     2103    case ValueBitLShift:
     2104        compileValueLShiftOp(node);
     2105        break;
     2106
    21032107    case BitRShift:
    2104     case BitLShift:
     2108    case ArithBitLShift:
    21052109    case BitURShift:
    21062110        compileShiftOp(node);
  • trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

    r246034 r247387  
    9393            break;
    9494           
    95         case BitLShift:
     95        case ArithBitLShift:
    9696        case BitRShift:
    9797        case BitURShift:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r246041 r247387  
    6565    case ArithBitXor:
    6666    case BitRShift:
    67     case BitLShift:
     67    case ArithBitLShift:
    6868    case BitURShift:
    6969    case CheckStructure:
     
    9494    case ValueBitOr:
    9595    case ValueBitNot:
     96    case ValueBitLShift:
    9697    case ValueNegate:
    9798    case ValueAdd:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r247101 r247387  
    854854            compileBitRShift();
    855855            break;
    856         case BitLShift:
    857             compileBitLShift();
     856        case ArithBitLShift:
     857            compileArithBitLShift();
     858            break;
     859        case ValueBitLShift:
     860            compileValueBitLShift();
    858861            break;
    859862        case BitURShift:
     
    31853188    }
    31863189   
    3187     void compileBitLShift()
    3188     {
    3189         if (m_node->isBinaryUseKind(UntypedUse)) {
    3190             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
    3191             return;
    3192         }
     3190    void compileArithBitLShift()
     3191    {
    31933192        setInt32(m_out.shl(
    31943193            lowInt32(m_node->child1()),
     
    31963195    }
    31973196   
     3197    void compileValueBitLShift()
     3198    {
     3199        if (m_node->isBinaryUseKind(BigIntUse)) {
     3200            LValue left = lowBigInt(m_node->child1());
     3201            LValue right = lowBigInt(m_node->child2());
     3202           
     3203            LValue result = vmCall(pointerType(), m_out.operation(operationBitLShiftBigInt), m_callFrame, left, right);
     3204            setJSValue(result);
     3205            return;
     3206        }
     3207
     3208        ASSERT(m_node->isBinaryUseKind(UntypedUse));
     3209        emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
     3210    }
     3211
    31983212    void compileBitURShift()
    31993213    {
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r245906 r247387  
    11711171
    11721172
    1173 bitOp(lshift, OpLshift,
     1173bitOpProfiled(lshift, OpLshift,
    11741174    macro (left, right) lshifti left, right end)
    11751175
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r247101 r247387  
    11471147end
    11481148
    1149 bitOp(lshift, OpLshift,
     1149bitOpProfiled(lshift, OpLshift,
    11501150    macro (left, right) lshifti left, right end)
    11511151
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r246490 r247387  
    675675            JSBigInt* result = JSBigInt::leftShift(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
    676676            CHECK_EXCEPTION();
    677             RETURN(result);
     677            RETURN_PROFILED(result);
    678678        }
    679679
     
    681681    }
    682682
    683     RETURN(jsNumber(WTF::get<int32_t>(leftNumeric) << (WTF::get<int32_t>(rightNumeric) & 31)));
     683    RETURN_PROFILED(jsNumber(WTF::get<int32_t>(leftNumeric) << (WTF::get<int32_t>(rightNumeric) & 31)));
    684684}
    685685
Note: See TracChangeset for help on using the changeset viewer.