Ignore:
Timestamp:
Nov 7, 2018, 5:47:27 PM (7 years ago)
Author:
Caio Lima
Message:

[BigInt] Add support to BigInt into ValueAdd
https://bugs.webkit.org/show_bug.cgi?id=186177

Reviewed by Keith Miller.

JSTests:

  • stress/big-int-negate-jit.js:
  • stress/value-add-big-int-and-string.js: Added.
  • stress/value-add-big-int-prediction-propagation.js: Added.
  • stress/value-add-big-int-untyped.js: Added.

PerformanceTests:

The idea of BigIntBench is to provide a set of microbenchmarks and
benchmarks to evaluate how fast BigInt computations are happening on
JSC implementation.

Now, we are adding microbenchmarks in this set,
but the plan is to move these tests to "JSTest/microbenchmarks" when
BigInt is enabled by default. After that, the focus of Bigint bench is
to provide a set of tests that represents real use cases of BigInt in
JS programs.

  • BigIntBench/big-int-add-prediction-propagation.js: Added.
  • BigIntBench/big-int-simple-add.js: Added.
  • BigIntBench/big-int-simple-sub.js: Added.

Source/JavaScriptCore:

We are adding a very primitive specialization case of BigInts into ValueAdd.
When compiling a speculated version of this node to BigInt, we are currently
calling 'operationAddBigInt', a function that expects only BigInts as
parameter and effectly add numbers using JSBigInt::add. To properly
speculate BigInt operands, we changed ArithProfile to observe when
its result is a BigInt. With this new observation, we are able to identify
when ValueAdd results into a String or BigInt.

Here are some numbers for this specialization running
microbenchmarks:

big-int-simple-add 21.5411+-1.1096 15.3502+-0.7027 definitely 1.4033x faster
big-int-add-prediction-propagation 13.7762+-0.5578 10.8117+-0.5330 definitely 1.2742x faster

  • bytecode/ArithProfile.cpp:

(JSC::ArithProfile::emitObserveResult):
(JSC::ArithProfile::shouldEmitSetNonNumeric const):
(JSC::ArithProfile::shouldEmitSetBigInt const):
(JSC::ArithProfile::emitSetNonNumeric const):
(JSC::ArithProfile::emitSetBigInt const):
(WTF::printInternal):
(JSC::ArithProfile::shouldEmitSetNonNumber const): Deleted.
(JSC::ArithProfile::emitSetNonNumber const): Deleted.

  • bytecode/ArithProfile.h:

(JSC::ArithProfile::observedUnaryInt):
(JSC::ArithProfile::observedUnaryNumber):
(JSC::ArithProfile::observedBinaryIntInt):
(JSC::ArithProfile::observedBinaryNumberInt):
(JSC::ArithProfile::observedBinaryIntNumber):
(JSC::ArithProfile::observedBinaryNumberNumber):
(JSC::ArithProfile::didObserveNonInt32 const):
(JSC::ArithProfile::didObserveNonNumeric const):
(JSC::ArithProfile::didObserveBigInt const):
(JSC::ArithProfile::setObservedNonNumeric):
(JSC::ArithProfile::setObservedBigInt):
(JSC::ArithProfile::observeResult):
(JSC::ArithProfile::didObserveNonNumber const): Deleted.
(JSC::ArithProfile::setObservedNonNumber): Deleted.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::makeSafe):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGNode.h:

(JSC::DFG::Node::mayHaveNonNumericResult):
(JSC::DFG::Node::mayHaveBigIntResult):
(JSC::DFG::Node::mayHaveNonNumberResult): Deleted.

  • dfg/DFGNodeFlags.cpp:

(JSC::DFG::dumpNodeFlags):

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

(JSC::DFG::SpeculativeJIT::compileValueAdd):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileValueAdd):

  • runtime/CommonSlowPaths.cpp:

(JSC::updateArithProfileForUnaryArithOp):
(JSC::updateArithProfileForBinaryArithOp):

Tools:

  • Scripts/run-jsc-benchmarks:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp

    r222009 r237972  
    3535void ArithProfile::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode)
    3636{
    37     if (!shouldEmitSetDouble() && !shouldEmitSetNonNumber())
     37    if (!shouldEmitSetDouble() && !shouldEmitSetNonNumeric() && !shouldEmitSetBigInt())
    3838        return;
    3939
    40     CCallHelpers::Jump isInt32 = jit.branchIfInt32(regs, mode);
     40    CCallHelpers::JumpList done;
     41    CCallHelpers::JumpList nonNumeric;
     42
     43    done.append(jit.branchIfInt32(regs, mode));
    4144    CCallHelpers::Jump notDouble = jit.branchIfNotDoubleKnownNotInt32(regs, mode);
    4245    emitSetDouble(jit);
    43     CCallHelpers::Jump done = jit.jump();
     46    done.append(jit.jump());
     47
    4448    notDouble.link(&jit);
    45     emitSetNonNumber(jit);
     49
     50    nonNumeric.append(jit.branchIfNotCell(regs, mode));
     51    nonNumeric.append(jit.branchIfNotBigInt(regs.payloadGPR()));
     52    emitSetBigInt(jit);
     53    done.append(jit.jump());
     54
     55    nonNumeric.link(&jit);
     56    emitSetNonNumeric(jit);
     57
    4658    done.link(&jit);
    47     isInt32.link(&jit);
    4859}
    4960
     
    6071}
    6172
    62 bool ArithProfile::shouldEmitSetNonNumber() const
     73bool ArithProfile::shouldEmitSetNonNumeric() const
    6374{
    64     uint32_t mask = ArithProfile::NonNumber;
     75    uint32_t mask = ArithProfile::NonNumeric;
    6576    return (m_bits & mask) != mask;
    6677}
    6778
    68 void ArithProfile::emitSetNonNumber(CCallHelpers& jit) const
     79bool ArithProfile::shouldEmitSetBigInt() const
    6980{
    70     if (shouldEmitSetNonNumber())
    71         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumber), CCallHelpers::AbsoluteAddress(addressOfBits()));
     81    uint32_t mask = ArithProfile::BigInt;
     82    return (m_bits & mask) != mask;
     83}
     84
     85void ArithProfile::emitSetNonNumeric(CCallHelpers& jit) const
     86{
     87    if (shouldEmitSetNonNumeric())
     88        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits()));
     89}
     90
     91void ArithProfile::emitSetBigInt(CCallHelpers& jit) const
     92{
     93    if (shouldEmitSetBigInt())
     94        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::BigInt), CCallHelpers::AbsoluteAddress(addressOfBits()));
    7295}
    7396#endif // ENABLE(JIT)
     
    96119            separator = "|";
    97120        }
    98         if (profile.didObserveNonNumber()) {
    99             out.print(separator, "NonNumber");
     121        if (profile.didObserveNonNumeric()) {
     122            out.print(separator, "NonNumeric");
    100123            separator = "|";
    101124        }
     
    106129        if (profile.didObserveInt52Overflow()) {
    107130            out.print(separator, "Int52Overflow");
     131            separator = "|";
     132        }
     133        if (profile.didObserveBigInt()) {
     134            out.print(separator, "BigInt");
    108135            separator = "|";
    109136        }
Note: See TracChangeset for help on using the changeset viewer.