Changeset 236901 in webkit


Ignore:
Timestamp:
Oct 6, 2018 5:20:59 PM (5 years ago)
Author:
Caio Lima
Message:

[ESNext][BigInt] Implement support for "|"
https://bugs.webkit.org/show_bug.cgi?id=186229

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/big-int-bitwise-and-jit.js:
  • stress/big-int-bitwise-or-general.js: Added.
  • stress/big-int-bitwise-or-jit-untyped.js: Added.
  • stress/big-int-bitwise-or-jit.js: Added.
  • stress/big-int-bitwise-or-memory-stress.js: Added.
  • stress/big-int-bitwise-or-to-primitive-precedence.js: Added.
  • stress/big-int-bitwise-or-type-error.js: Added.
  • stress/big-int-bitwise-or-wrapped-value.js: Added.

Source/JavaScriptCore:

This patch is introducing support for BigInt into bitwise "or" operator.
In addition, we are also introducing 2 new DFG nodes, named "ArithBitOr" and
"ValueBitOr", to replace "BitOr" node. The idea is to follow the
difference that we make on Arith<op> and Value<op>, where ArithBitOr
handles cases when the operands are Int32 and ValueBitOr handles
the remaining cases.

We are also changing op_bitor to use ValueProfile. We are using
ValueProfile during DFG generation to emit "ArithBitOr" when
outcome prediction is Int32.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::arithProfileForPC):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitBinaryOp):

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGBackwardsPropagationPhase.cpp:

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

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

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

(JSC::DFG::bitwiseOp):

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

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileValueBitwiseOp):
(JSC::DFG::SpeculativeJIT::compileBitwiseOp):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::bitOp):

  • 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::compileValueBitOr):
(JSC::FTL::DFG::LowerDFGToB3::compileArithBitOr):
(JSC::FTL::DFG::LowerDFGToB3::compileBitOr): Deleted.

  • jit/JITArithmetic.cpp:

(JSC::JIT::emit_op_bitor):

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

(JSC::SLOW_PATH_DECL):

  • runtime/JSBigInt.cpp:

(JSC::JSBigInt::bitwiseAnd):
(JSC::JSBigInt::bitwiseOr):
(JSC::JSBigInt::absoluteBitwiseOp):
(JSC::JSBigInt::absoluteAddOne):

  • runtime/JSBigInt.h:
Location:
trunk
Files:
7 added
29 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r236872 r236901  
     12018-10-06  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [ESNext][BigInt] Implement support for "|"
     4        https://bugs.webkit.org/show_bug.cgi?id=186229
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * stress/big-int-bitwise-and-jit.js:
     9        * stress/big-int-bitwise-or-general.js: Added.
     10        * stress/big-int-bitwise-or-jit-untyped.js: Added.
     11        * stress/big-int-bitwise-or-jit.js: Added.
     12        * stress/big-int-bitwise-or-memory-stress.js: Added.
     13        * stress/big-int-bitwise-or-to-primitive-precedence.js: Added.
     14        * stress/big-int-bitwise-or-type-error.js: Added.
     15        * stress/big-int-bitwise-or-wrapped-value.js: Added.
     16
    1172018-10-05  Dominik Infuehr  <dominik.infuehr@gmail.com>
    218
  • trunk/JSTests/stress/big-int-bitwise-and-jit.js

    r236637 r236901  
    1010function bigIntBitAnd(a, b) {
    1111    return (a & b) & (a & 0b11n);
    12 
    1312}
    1413noInline(bigIntBitAnd);
  • trunk/Source/JavaScriptCore/ChangeLog

    r236900 r236901  
     12018-10-06  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [ESNext][BigInt] Implement support for "|"
     4        https://bugs.webkit.org/show_bug.cgi?id=186229
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        This patch is introducing support for BigInt into bitwise "or" operator.
     9        In addition, we are also introducing 2 new DFG nodes, named "ArithBitOr" and
     10        "ValueBitOr", to replace "BitOr" node. The idea is to follow the
     11        difference that we make on Arith<op> and Value<op>, where ArithBitOr
     12        handles cases when the operands are Int32 and ValueBitOr handles
     13        the remaining cases.
     14
     15        We are also changing op_bitor to use ValueProfile. We are using
     16        ValueProfile during DFG generation to emit "ArithBitOr" when
     17        outcome prediction is Int32.
     18
     19        * bytecode/CodeBlock.cpp:
     20        (JSC::CodeBlock::finishCreation):
     21        (JSC::CodeBlock::arithProfileForPC):
     22        * bytecompiler/BytecodeGenerator.cpp:
     23        (JSC::BytecodeGenerator::emitBinaryOp):
     24        * dfg/DFGAbstractInterpreterInlines.h:
     25        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     26        * dfg/DFGBackwardsPropagationPhase.cpp:
     27        (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
     28        (JSC::DFG::BackwardsPropagationPhase::propagate):
     29        * dfg/DFGByteCodeParser.cpp:
     30        (JSC::DFG::ByteCodeParser::parseBlock):
     31        * dfg/DFGClobberize.h:
     32        (JSC::DFG::clobberize):
     33        * dfg/DFGDoesGC.cpp:
     34        (JSC::DFG::doesGC):
     35        * dfg/DFGFixupPhase.cpp:
     36        (JSC::DFG::FixupPhase::fixupNode):
     37        * dfg/DFGNodeType.h:
     38        * dfg/DFGOperations.cpp:
     39        (JSC::DFG::bitwiseOp):
     40        * dfg/DFGOperations.h:
     41        * dfg/DFGPredictionPropagationPhase.cpp:
     42        * dfg/DFGSafeToExecute.h:
     43        (JSC::DFG::safeToExecute):
     44        * dfg/DFGSpeculativeJIT.cpp:
     45        (JSC::DFG::SpeculativeJIT::compileValueBitwiseOp):
     46        (JSC::DFG::SpeculativeJIT::compileBitwiseOp):
     47        * dfg/DFGSpeculativeJIT.h:
     48        (JSC::DFG::SpeculativeJIT::bitOp):
     49        * dfg/DFGSpeculativeJIT32_64.cpp:
     50        (JSC::DFG::SpeculativeJIT::compile):
     51        * dfg/DFGSpeculativeJIT64.cpp:
     52        (JSC::DFG::SpeculativeJIT::compile):
     53        * dfg/DFGStrengthReductionPhase.cpp:
     54        (JSC::DFG::StrengthReductionPhase::handleNode):
     55        * ftl/FTLCapabilities.cpp:
     56        (JSC::FTL::canCompile):
     57        * ftl/FTLLowerDFGToB3.cpp:
     58        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     59        (JSC::FTL::DFG::LowerDFGToB3::compileValueBitOr):
     60        (JSC::FTL::DFG::LowerDFGToB3::compileArithBitOr):
     61        (JSC::FTL::DFG::LowerDFGToB3::compileBitOr): Deleted.
     62        * jit/JITArithmetic.cpp:
     63        (JSC::JIT::emit_op_bitor):
     64        * llint/LowLevelInterpreter32_64.asm:
     65        * llint/LowLevelInterpreter64.asm:
     66        * runtime/CommonSlowPaths.cpp:
     67        (JSC::SLOW_PATH_DECL):
     68        * runtime/JSBigInt.cpp:
     69        (JSC::JSBigInt::bitwiseAnd):
     70        (JSC::JSBigInt::bitwiseOr):
     71        (JSC::JSBigInt::absoluteBitwiseOp):
     72        (JSC::JSBigInt::absoluteAddOne):
     73        * runtime/JSBigInt.h:
     74
    1752018-10-05  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
    276
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r236637 r236901  
    583583
    584584        case op_bitand:
     585        case op_bitor:
    585586        case op_to_this: {
    586587            linkValueProfile(i, opLength);
     
    29362937    case op_negate:
    29372938        return bitwise_cast<ArithProfile*>(&pc[3].u.operand);
    2938     case op_bitor:
    2939     case op_bitand:
    29402939    case op_bitxor:
    29412940    case op_add:
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r236637 r236901  
    17341734{
    17351735
    1736     if (opcodeID == op_bitand) {
     1736    if (opcodeID == op_bitand || opcodeID == op_bitor) {
    17371737        UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
    17381738        instructions().append(dst->index());
     
    17481748    instructions().append(src2->index());
    17491749
    1750     if (opcodeID == op_bitor || opcodeID == op_bitxor ||
    1751         opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
     1750    if (opcodeID == op_bitxor || opcodeID == op_add ||
     1751        opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
    17521752        instructions().append(ArithProfile(types.first(), types.second()).bits());
    17531753
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r236637 r236901  
    376376    }
    377377           
     378    case ValueBitOr:
    378379    case ValueBitAnd:
    379380        clobberWorld();
    380         setTypeForNode(node, SpecBoolInt32 | SpecBigInt);
     381        if (node->binaryUseKind() == BigIntUse)
     382            setTypeForNode(node, SpecBigInt);
     383        else
     384            setTypeForNode(node, SpecBoolInt32 | SpecBigInt);
    381385        break;
    382386           
    383387    case ArithBitAnd:
    384     case BitOr:
     388    case ArithBitOr:
    385389    case BitXor:
    386390    case BitRShift:
     
    402406                setConstant(node, JSValue(a & b));
    403407                break;
    404             case BitOr:
     408            case ArithBitOr:
    405409                setConstant(node, JSValue(a | b));
    406410                break;
  • trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp

    r236637 r236901  
    119119        }
    120120           
    121         case BitOr:
     121        case ArithBitOr:
    122122        case BitXor:
    123123        case BitLShift: {
     
    209209           
    210210        case ArithBitAnd:
    211         case BitOr:
     211        case ArithBitOr:
    212212        case BitXor:
    213213        case BitRShift:
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r236637 r236901  
    48574857            Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
    48584858            Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
    4859             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(BitOr, op1, op2));
     4859            if (isInt32Speculation(getPrediction()))
     4860                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ArithBitOr, op1, op2));
     4861            else
     4862                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ValueBitOr, op1, op2));
    48604863            NEXT_OPCODE(op_bitor);
    48614864        }
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r236637 r236901  
    264264
    265265    case ArithBitAnd:
    266     case BitOr:
     266    case ArithBitOr:
    267267    case BitXor:
    268268    case BitLShift:
     
    637637    case HasOwnProperty:
    638638    case ValueBitAnd:
     639    case ValueBitOr:
    639640    case ValueNegate:
    640641    case ValueAdd:
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r236637 r236901  
    6969    case SetArgument:
    7070    case ArithBitAnd:
    71     case BitOr:
     71    case ArithBitOr:
    7272    case BitXor:
    7373    case BitLShift:
     
    9898    case ArithUnary:
    9999    case ValueBitAnd:
     100    case ValueBitOr:
    100101    case ValueAdd:
    101102    case ValueNegate:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r236637 r236901  
    100100        }
    101101           
     102        case ValueBitOr:
    102103        case ValueBitAnd: {
    103104            if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
     
    112113        }
    113114   
     115        case ArithBitOr:
    114116        case ArithBitAnd: {
    115117            if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
    116118                fixEdge<UntypedUse>(node->child1());
    117119                fixEdge<UntypedUse>(node->child2());
    118                 node->setOpAndDefaultFlags(ValueBitAnd);
     120
     121                switch (op) {
     122                case ArithBitOr:
     123                    node->setOpAndDefaultFlags(ValueBitOr);
     124                    break;
     125                case ArithBitAnd:
     126                    node->setOpAndDefaultFlags(ValueBitAnd);
     127                    break;
     128                default:
     129                    DFG_CRASH(m_graph, node, "Unexpected node during ArithBit operation fixup");
     130                    break;
     131                }
     132
    119133                break;
    120134            }
     
    124138        }
    125139
    126         case BitOr:
    127140        case BitXor:
    128141        case BitRShift:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r236637 r236901  
    114114    macro(ValueBitAnd, NodeResultJS | NodeMustGenerate) \
    115115    macro(ArithBitAnd, NodeResultInt32) \
    116     macro(BitOr, NodeResultInt32) \
     116    macro(ValueBitOr, NodeResultJS | NodeMustGenerate) \
     117    macro(ArithBitOr, NodeResultInt32) \
    117118    macro(BitXor, NodeResultInt32) \
    118119    macro(BitLShift, NodeResultInt32) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r236697 r236901  
    355355        }
    356356
    357         return throwVMTypeError(exec, scope, "Invalid mix of BigInt and other type in bitwise and operation.");
     357        return throwVMTypeError(exec, scope, "Invalid mix of BigInt and other type in bitwise 'and' operation.");
    358358    }
    359359
     
    370370    JSValue op2 = JSValue::decode(encodedOp2);
    371371
    372     int32_t a = op1.toInt32(exec);
     372    auto leftNumeric = op1.toBigIntOrInt32(exec);
    373373    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    374     scope.release();
    375     int32_t b = op2.toInt32(exec);
    376     return JSValue::encode(jsNumber(a | b));
     374    auto rightNumeric = op2.toBigIntOrInt32(exec);
     375    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     376
     377    if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
     378        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
     379            JSBigInt* result = JSBigInt::bitwiseOr(*vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
     380            RETURN_IF_EXCEPTION(scope, encodedJSValue());
     381            return JSValue::encode(result);
     382        }
     383
     384        return throwVMTypeError(exec, scope, "Invalid mix of BigInt and other type in bitwise 'or' operation.");
     385    }
     386
     387    return JSValue::encode(jsNumber(WTF::get<int32_t>(leftNumeric) | WTF::get<int32_t>(rightNumeric)));
    377388}
    378389
     
    12851296   
    12861297    return JSBigInt::bitwiseAnd(*vm, leftOperand, rightOperand);
     1298}
     1299
     1300JSCell* JIT_OPERATION operationBitOrBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
     1301{
     1302    VM* vm = &exec->vm();
     1303    NativeCallFrameTracer tracer(vm, exec);
     1304   
     1305    JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     1306    JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     1307   
     1308    return JSBigInt::bitwiseOr(*vm, leftOperand, rightOperand);
    12871309}
    12881310
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r236637 r236901  
    165165size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
    166166JSCell* JIT_OPERATION operationBitAndBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
     167JSCell* JIT_OPERATION operationBitOrBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
    167168size_t JIT_OPERATION operationSameValue(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    168169JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r236637 r236901  
    247247        }
    248248
     249        case ValueBitOr:
    249250        case ValueBitAnd: {
    250251            if (node->child1()->shouldSpeculateBigInt() && node->child2()->shouldSpeculateBigInt())
     
    709710
    710711        case ArithBitAnd:
    711         case BitOr:
     712        case ArithBitOr:
    712713        case BitXor:
    713714        case BitRShift:
     
    10641065        case SetLocal:
    10651066        case UInt32ToNumber:
     1067        case ValueBitOr:
    10661068        case ValueBitAnd:
    10671069        case ValueNegate:
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r236637 r236901  
    199199    case SetArgument:
    200200    case ArithBitAnd:
    201     case BitOr:
     201    case ArithBitOr:
    202202    case BitXor:
    203203    case BitLShift:
     
    228228    case ArithUnary:
    229229    case ValueBitAnd:
     230    case ValueBitOr:
    230231    case ValueNegate:
    231232    case ValueAdd:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r236734 r236901  
    36003600            emitUntypedBitOp<JITBitAndGenerator, operationValueBitAnd>(node);
    36013601            return;
     3602        case ValueBitOr:
     3603            emitUntypedBitOp<JITBitOrGenerator, operationValueBitOr>(node);
     3604            return;
    36023605        default:
    36033606            RELEASE_ASSERT_NOT_REACHED();
     
    36183621    GPRFlushedCallResult result(this);
    36193622    GPRReg resultGPR = result.gpr();
    3620     callOperation(operationBitAndBigInt, resultGPR, leftGPR, rightGPR);
     3623
     3624    switch (op) {
     3625    case ValueBitAnd:
     3626        callOperation(operationBitAndBigInt, resultGPR, leftGPR, rightGPR);
     3627        break;
     3628    case ValueBitOr:
     3629        callOperation(operationBitOrBigInt, resultGPR, leftGPR, rightGPR);
     3630        break;
     3631    default:
     3632        RELEASE_ASSERT_NOT_REACHED();
     3633    }
     3634
    36213635    m_jit.exceptionCheck();
    36223636    cellResult(resultGPR, node);
     
    36313645    if (leftChild.useKind() == UntypedUse || rightChild.useKind() == UntypedUse) {
    36323646        switch (op) {
    3633         case BitOr:
    3634             emitUntypedBitOp<JITBitOrGenerator, operationValueBitOr>(node);
    3635             return;
    36363647        case BitXor:
    36373648            emitUntypedBitOp<JITBitXorGenerator, operationValueBitXor>(node);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r236637 r236901  
    637637            m_jit.and32(Imm32(imm), op1, result);
    638638            break;
    639         case BitOr:
     639        case ArithBitOr:
    640640            m_jit.or32(Imm32(imm), op1, result);
    641641            break;
     
    653653            m_jit.and32(op1, op2, result);
    654654            break;
    655         case BitOr:
     655        case ArithBitOr:
    656656            m_jit.or32(op1, op2, result);
    657657            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r236734 r236901  
    19801980        break;
    19811981
     1982    case ValueBitOr:
    19821983    case ValueBitAnd:
    19831984        compileValueBitwiseOp(node);
     
    19851986
    19861987    case ArithBitAnd:
    1987     case BitOr:
     1988    case ArithBitOr:
    19881989    case BitXor:
    19891990        compileBitwiseOp(node);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r236734 r236901  
    20762076
    20772077    case ValueBitAnd:
     2078    case ValueBitOr:
    20782079        compileValueBitwiseOp(node);
    20792080        break;
    20802081
    20812082    case ArithBitAnd:
    2082     case BitOr:
     2083    case ArithBitOr:
    20832084    case BitXor:
    20842085        compileBitwiseOp(node);
  • trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

    r236637 r236901  
    7979    {
    8080        switch (m_node->op()) {
    81         case BitOr:
     81        case ArithBitOr:
    8282            handleCommutativity();
    8383
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r236637 r236901  
    6060    case Return:
    6161    case ArithBitAnd:
    62     case BitOr:
     62    case ArithBitOr:
    6363    case BitXor:
    6464    case BitRShift:
     
    8888    case PutGlobalVariable:
    8989    case ValueBitAnd:
     90    case ValueBitOr:
    9091    case ValueNegate:
    9192    case ValueAdd:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r236824 r236901  
    656656            compileArithBitAnd();
    657657            break;
    658         case DFG::BitOr:
    659             compileBitOr();
     658        case ValueBitOr:
     659            compileValueBitOr();
     660            break;
     661        case ArithBitOr:
     662            compileArithBitOr();
    660663            break;
    661664        case DFG::BitXor:
     
    28292832    }
    28302833   
    2831     void compileBitOr()
    2832     {
    2833         if (m_node->isBinaryUseKind(UntypedUse)) {
    2834             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
    2835             return;
    2836         }
     2834    void compileValueBitOr()
     2835    {
     2836        if (m_node->isBinaryUseKind(BigIntUse)) {
     2837            LValue left = lowBigInt(m_node->child1());
     2838            LValue right = lowBigInt(m_node->child2());
     2839
     2840            LValue result = vmCall(pointerType(), m_out.operation(operationBitOrBigInt), m_callFrame, left, right);
     2841            setJSValue(result);
     2842            return;
     2843        }
     2844
     2845        emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
     2846    }
     2847
     2848    void compileArithBitOr()
     2849    {
    28372850        setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
    28382851    }
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r236637 r236901  
    582582void JIT::emit_op_bitor(Instruction* currentInstruction)
    583583{
    584     emitBitBinaryOpFastPath<JITBitOrGenerator>(currentInstruction);
     584    emitBitBinaryOpFastPath<JITBitOrGenerator>(currentInstruction, ProfilingPolicy::ShouldEmitProfiling);
    585585}
    586586
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r236637 r236901  
    12421242_llint_op_bitor:
    12431243    traceExecution()
    1244     bitOp(
     1244    bitOpProfiled(
    12451245        macro (left, right) ori left, right end,
    12461246        _slow_path_bitor,
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r236637 r236901  
    11851185_llint_op_bitor:
    11861186    traceExecution()
    1187     bitOp(
     1187    bitOpProfiled(
    11881188        macro (left, right) ori left, right end,
    11891189        _slow_path_bitor,
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r236637 r236901  
    668668        }
    669669
    670         THROW(createTypeError(exec, "Invalid mix of BigInt and other type in bitwise and operation."));
     670        THROW(createTypeError(exec, "Invalid mix of BigInt and other type in bitwise 'and' operation."));
    671671    }
    672672
     
    677677{
    678678    BEGIN();
    679     int32_t a = OP_C(2).jsValue().toInt32(exec);
    680     if (UNLIKELY(throwScope.exception()))
    681         RETURN(JSValue());
    682     int32_t b = OP_C(3).jsValue().toInt32(exec);
    683     RETURN(jsNumber(a | b));
     679    auto leftNumeric = OP_C(2).jsValue().toBigIntOrInt32(exec);
     680    CHECK_EXCEPTION();
     681    auto rightNumeric = OP_C(3).jsValue().toBigIntOrInt32(exec);
     682    CHECK_EXCEPTION();
     683    if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
     684        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
     685            JSBigInt* result = JSBigInt::bitwiseOr(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
     686            CHECK_EXCEPTION();
     687            RETURN_PROFILED(op_bitor, result);
     688        }
     689
     690        THROW(createTypeError(exec, "Invalid mix of BigInt and other type in bitwise 'or' operation."));
     691    }
     692
     693    RETURN_PROFILED(op_bitor, jsNumber(WTF::get<int32_t>(leftNumeric) | WTF::get<int32_t>(rightNumeric)));
    684694}
    685695
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp

    r236737 r236901  
    392392        result = absoluteOr(vm, result, y1);
    393393
    394         return absoluteAddOne(vm, result, true);
     394        return absoluteAddOne(vm, result, SignOption::Signed);
    395395    }
    396396
     
    402402    // x & (-y) == x & ~(y-1) == x & ~(y-1)
    403403    return absoluteAndNot(vm, x, absoluteSubOne(vm, y, y->length()));
     404}
     405
     406JSBigInt* JSBigInt::bitwiseOr(VM& vm, JSBigInt* x, JSBigInt* y)
     407{
     408    unsigned resultLength = std::max(x->length(), y->length());
     409
     410    if (!x->sign() && !y->sign())
     411        return absoluteOr(vm, x, y);
     412   
     413    if (x->sign() && y->sign()) {
     414        // (-x) | (-y) == ~(x-1) | ~(y-1) == ~((x-1) & (y-1))
     415        // == -(((x-1) & (y-1)) + 1)
     416        JSBigInt* result = absoluteSubOne(vm, x, resultLength);
     417        JSBigInt* y1 = absoluteSubOne(vm, y, y->length());
     418        result = absoluteAnd(vm, result, y1);
     419        return absoluteAddOne(vm, result, SignOption::Signed);
     420    }
     421   
     422    ASSERT(x->sign() != y->sign());
     423
     424    // Assume that x is the positive BigInt.
     425    if (x->sign())
     426        std::swap(x, y);
     427   
     428    // x | (-y) == x | ~(y-1) == ~((y-1) &~ x) == -(((y-1) &~ x) + 1)
     429    JSBigInt* result = absoluteSubOne(vm, y, resultLength);
     430    result = absoluteAndNot(vm, result, x);
     431    return absoluteAddOne(vm, result, SignOption::Signed);
    404432}
    405433
     
    10291057//                   v     v     v     v
    10301058// result: [  0 ][ x3 ][ r2 ][ r1 ][ r0 ]
    1031 inline JSBigInt* JSBigInt::absoluteBitwiseOp(VM& vm, JSBigInt* x, JSBigInt* y, ExtraDigitsHandling extraDigits, SymmetricOp symmetric, std::function<Digit(Digit, Digit)> op)
     1059template<typename BitwiseOp>
     1060inline JSBigInt* JSBigInt::absoluteBitwiseOp(VM& vm, JSBigInt* x, JSBigInt* y, ExtraDigitsHandling extraDigits, SymmetricOp symmetric, BitwiseOp&& op)
    10321061{
    10331062    unsigned xLength = x->length();
     
    10851114}
    10861115
    1087 JSBigInt* JSBigInt::absoluteAddOne(VM& vm, JSBigInt* x, bool sign)
     1116JSBigInt* JSBigInt::absoluteAddOne(VM& vm, JSBigInt* x, SignOption signOption)
    10881117{
    10891118    unsigned inputLength = x->length();
     
    11121141        ASSERT(!carry);
    11131142
    1114     result->setSign(sign);
     1143    result->setSign(signOption == SignOption::Signed);
    11151144    return result->rightTrim(vm);
    11161145}
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.h

    r236737 r236901  
    115115
    116116    static JSBigInt* bitwiseAnd(VM&, JSBigInt* x, JSBigInt* y);
     117    static JSBigInt* bitwiseOr(VM&, JSBigInt* x, JSBigInt* y);
    117118
    118119private:
     
    161162    };
    162163
    163     static JSBigInt* absoluteBitwiseOp(VM&, JSBigInt* x, JSBigInt* y, ExtraDigitsHandling, SymmetricOp, std::function<Digit(Digit, Digit)> op);
     164    template<typename BitwiseOp>
     165    static JSBigInt* absoluteBitwiseOp(VM&, JSBigInt* x, JSBigInt* y, ExtraDigitsHandling, SymmetricOp, BitwiseOp&&);
     166
    164167    static JSBigInt* absoluteAnd(VM&, JSBigInt* x, JSBigInt* y);
    165168    static JSBigInt* absoluteOr(VM&, JSBigInt* x, JSBigInt* y);
    166169    static JSBigInt* absoluteAndNot(VM&, JSBigInt* x, JSBigInt* y);
    167170
    168     static JSBigInt* absoluteAddOne(VM&, JSBigInt* x, bool sign);
     171    enum class SignOption {
     172        Signed,
     173        Unsigned
     174    };
     175
     176    static JSBigInt* absoluteAddOne(VM&, JSBigInt* x, SignOption);
    169177    static JSBigInt* absoluteSubOne(VM&, JSBigInt* x, unsigned resultLength);
    170178
Note: See TracChangeset for help on using the changeset viewer.