Ignore:
Timestamp:
Nov 7, 2019, 6:46:09 PM (6 years ago)
Author:
[email protected]
Message:

Split ArithProfile into a Unary and a Binary version
https://bugs.webkit.org/show_bug.cgi?id=202832
<rdar://problem/56266847>

Reviewed by Keith Miller.

ArithProfile was for a long time only used for add/sub/mul/div, but recently it started being used for negate. And it will soon also have to be used for inc and dec due to BigInt.
So in this patch I make a separate version that only has the data for a single argument, and thus takes half as much memory.

After discussing this change with Phil I realized that the ResultType(s) that were taking space in ArithProfile are not needed: they never change and a copy is already in the bytecode instruction itself.
Removing them allowed shrinking both kinds of ArithProfile to fit in 16 bits (9 and 13 respectively).
I kept the two kinds separate because they may shrink or grow independently in the future.

This also required adding the "orh" instruction to the offline assembler, to set bits in the ArithProfile.
This in turn motivated the addition of "storeh", as on RISC platforms "orh" on a memory location is actually loadh -> orh -> storeh.

  • bytecode/ArithProfile.cpp:

(JSC::ArithProfile<BitfieldType>::emitObserveResult):
(JSC::ArithProfile<BitfieldType>::shouldEmitSetDouble const):
(JSC::ArithProfile<BitfieldType>::emitSetDouble const):
(JSC::ArithProfile<BitfieldType>::shouldEmitSetNonNumeric const):
(JSC::ArithProfile<BitfieldType>::shouldEmitSetBigInt const):
(JSC::ArithProfile<BitfieldType>::emitSetNonNumeric const):
(JSC::ArithProfile<BitfieldType>::emitSetBigInt const):
(WTF::printInternal):

  • bytecode/ArithProfile.h:

(JSC::ArithProfile::didObserveNonInt32 const):
(JSC::ArithProfile::didObserveDouble const):
(JSC::ArithProfile::didObserveNonNegZeroDouble const):
(JSC::ArithProfile::didObserveNegZeroDouble const):
(JSC::ArithProfile::didObserveNonNumeric const):
(JSC::ArithProfile::didObserveBigInt const):
(JSC::ArithProfile::didObserveInt32Overflow const):
(JSC::ArithProfile::didObserveInt52Overflow const):
(JSC::ArithProfile::setObservedNonNegZeroDouble):
(JSC::ArithProfile::setObservedNegZeroDouble):
(JSC::ArithProfile::setObservedNonNumeric):
(JSC::ArithProfile::setObservedBigInt):
(JSC::ArithProfile::setObservedInt32Overflow):
(JSC::ArithProfile::setObservedInt52Overflow):
(JSC::ArithProfile::observeResult):
(JSC::ArithProfile::addressOfBits const):
(JSC::ArithProfile::bits const):
(JSC::ArithProfile::ArithProfile):
(JSC::ArithProfile::hasBits const):
(JSC::ArithProfile::setBit):
(JSC::UnaryArithProfile::UnaryArithProfile):
(JSC::UnaryArithProfile::observedIntBits):
(JSC::UnaryArithProfile::observedNumberBits):
(JSC::UnaryArithProfile::argObservedType const):
(JSC::UnaryArithProfile::setArgObservedType):
(JSC::UnaryArithProfile::argSawInt32):
(JSC::UnaryArithProfile::argSawNumber):
(JSC::UnaryArithProfile::argSawNonNumber):
(JSC::UnaryArithProfile::observeArg):
(JSC::UnaryArithProfile::isObservedTypeEmpty):
(JSC::BinaryArithProfile::BinaryArithProfile):
(JSC::BinaryArithProfile::observedIntIntBits):
(JSC::BinaryArithProfile::observedNumberIntBits):
(JSC::BinaryArithProfile::observedIntNumberBits):
(JSC::BinaryArithProfile::observedNumberNumberBits):
(JSC::BinaryArithProfile::setLhsObservedType):
(JSC::BinaryArithProfile::setRhsObservedType):
(JSC::BinaryArithProfile::observeLHS):
(JSC::BinaryArithProfile::observeLHSAndRHS):
(JSC::BinaryArithProfile::isObservedTypeEmpty):

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

(JSC::CodeBlock::addJITAddIC):
(JSC::CodeBlock::addJITMulIC):
(JSC::CodeBlock::addJITSubIC):
(JSC::CodeBlock::addJITNegIC):
(JSC::CodeBlock::binaryArithProfileForBytecodeOffset):
(JSC::CodeBlock::unaryArithProfileForBytecodeOffset):
(JSC::CodeBlock::binaryArithProfileForPC):
(JSC::CodeBlock::unaryArithProfileForPC):
(JSC::CodeBlock::couldTakeSpecialFastCase):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::addMathIC):

  • bytecode/Fits.h:
  • bytecode/MethodOfGettingAValueProfile.cpp:

(JSC::MethodOfGettingAValueProfile::emitReportValue const):
(JSC::MethodOfGettingAValueProfile::reportValue):

  • bytecode/MethodOfGettingAValueProfile.h:

(JSC::MethodOfGettingAValueProfile::MethodOfGettingAValueProfile):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitUnaryOp):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::UnaryOpNode::emitBytecode):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::methodOfGettingAValueProfileFor):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileValueSub):
(JSC::DFG::SpeculativeJIT::compileValueNegate):
(JSC::DFG::SpeculativeJIT::compileValueMul):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileValueAdd):
(JSC::FTL::DFG::LowerDFGToB3::compileValueSub):
(JSC::FTL::DFG::LowerDFGToB3::compileValueMul):
(JSC::FTL::DFG::LowerDFGToB3::compileUnaryMathIC):
(JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC):
(JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
(JSC::FTL::DFG::LowerDFGToB3::compileValueNegate):

  • jit/JIT.h:
  • jit/JITAddGenerator.cpp:

(JSC::JITAddGenerator::generateInline):
(JSC::JITAddGenerator::generateFastPath):

  • jit/JITAddGenerator.h:
  • jit/JITArithmetic.cpp:

(JSC::JIT::emit_op_negate):
(JSC::JIT::emit_op_add):
(JSC::JIT::emitMathICFast):
(JSC::JIT::emitMathICSlow):
(JSC::JIT::emit_op_div):
(JSC::JIT::emit_op_mul):
(JSC::JIT::emit_op_sub):

  • jit/JITDivGenerator.cpp:

(JSC::JITDivGenerator::generateFastPath):

  • jit/JITDivGenerator.h:

(JSC::JITDivGenerator::JITDivGenerator):

  • jit/JITInlines.h:

(JSC::JIT::copiedArithProfile):

  • jit/JITMathIC.h:

(JSC::JITMathIC::JITMathIC):
(JSC::JITMathIC::generateInline):
(JSC::JITMathIC::arithProfile const):
(JSC::isBinaryProfileEmpty):
(JSC::JITBinaryMathIC::JITBinaryMathIC):
(JSC::isUnaryProfileEmpty):
(JSC::JITUnaryMathIC::JITUnaryMathIC):

  • jit/JITMulGenerator.cpp:

(JSC::JITMulGenerator::generateInline):
(JSC::JITMulGenerator::generateFastPath):

  • jit/JITMulGenerator.h:
  • jit/JITNegGenerator.cpp:

(JSC::JITNegGenerator::generateInline):
(JSC::JITNegGenerator::generateFastPath):

  • jit/JITNegGenerator.h:
  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • jit/JITSubGenerator.cpp:

(JSC::JITSubGenerator::generateInline):
(JSC::JITSubGenerator::generateFastPath):

  • jit/JITSubGenerator.h:
  • llint/LLIntData.cpp:

(JSC::LLInt::Data::performAssertions):

  • llint/LLIntOffsetsExtractor.cpp:

(JSC::LLIntOffsetsExtractor::dummy):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • parser/ResultType.h:

(JSC::ResultType::ResultType):

  • runtime/CommonSlowPaths.cpp:

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

File:
1 edited

Legend:

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

    r252021 r252229  
    3333
    3434#if ENABLE(JIT)
    35 void ArithProfile::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode)
     35template<typename BitfieldType>
     36void ArithProfile<BitfieldType>::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode)
    3637{
    3738    if (!shouldEmitSetDouble() && !shouldEmitSetNonNumeric() && !shouldEmitSetBigInt())
     
    5960}
    6061
    61 bool ArithProfile::shouldEmitSetDouble() const
     62template<typename BitfieldType>
     63bool ArithProfile<BitfieldType>::shouldEmitSetDouble() const
    6264{
    63     uint32_t mask = ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble;
     65    uint32_t mask = Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble;
    6466    return (m_bits & mask) != mask;
    6567}
    6668
    67 void ArithProfile::emitSetDouble(CCallHelpers& jit) const
     69template<typename BitfieldType>
     70void ArithProfile<BitfieldType>::emitSetDouble(CCallHelpers& jit) const
    6871{
    6972    if (shouldEmitSetDouble())
    70         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));
     73        jit.or32(CCallHelpers::TrustedImm32(Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));
    7174}
    7275
    73 bool ArithProfile::shouldEmitSetNonNumeric() const
     76template<typename BitfieldType>
     77bool ArithProfile<BitfieldType>::shouldEmitSetNonNumeric() const
    7478{
    7579    uint32_t mask = ArithProfile::NonNumeric;
     
    7781}
    7882
    79 bool ArithProfile::shouldEmitSetBigInt() const
     83template<typename BitfieldType>
     84bool ArithProfile<BitfieldType>::shouldEmitSetBigInt() const
    8085{
    8186    uint32_t mask = ArithProfile::BigInt;
     
    8388}
    8489
    85 void ArithProfile::emitSetNonNumeric(CCallHelpers& jit) const
     90template<typename BitfieldType>
     91void ArithProfile<BitfieldType>::emitSetNonNumeric(CCallHelpers& jit) const
    8692{
    8793    if (shouldEmitSetNonNumeric())
    88         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits()));
     94        jit.or32(CCallHelpers::TrustedImm32(NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits()));
    8995}
    9096
    91 void ArithProfile::emitSetBigInt(CCallHelpers& jit) const
     97template<typename BitfieldType>
     98void ArithProfile<BitfieldType>::emitSetBigInt(CCallHelpers& jit) const
    9299{
    93100    if (shouldEmitSetBigInt())
    94         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::BigInt), CCallHelpers::AbsoluteAddress(addressOfBits()));
     101        jit.or32(CCallHelpers::TrustedImm32(BigInt), CCallHelpers::AbsoluteAddress(addressOfBits()));
    95102}
     103
     104// Generate the implementations of the functions above for UnaryArithProfile/BinaryArithProfile
     105// If changing the size of either, add the corresponding lines here.
     106template class ArithProfile<uint16_t>;
    96107#endif // ENABLE(JIT)
    97108
     
    102113using namespace JSC;
    103114
    104 void printInternal(PrintStream& out, const ArithProfile& profile)
     115template <typename T>
     116void printInternal(PrintStream& out, const ArithProfile<T>& profile)
    105117{
    106118    const char* separator = "";
     
    136148        }
    137149    }
     150    out.print(">");
     151}
     152
     153void printInternal(PrintStream& out, const UnaryArithProfile& profile)
     154{
     155    printInternal(out, static_cast<ArithProfile<UnaryArithProfileBase>>(profile));
     156
     157    out.print(" Arg ObservedType:<");
     158    out.print(profile.argObservedType());
     159    out.print(">");
     160}
     161
     162void printInternal(PrintStream& out, const BinaryArithProfile& profile)
     163{
     164    printInternal(out, static_cast<ArithProfile<UnaryArithProfileBase>>(profile));
     165
    138166    if (profile.tookSpecialFastPath())
    139         out.print(separator, "Took special fast path.");
    140     out.print(">");
     167        out.print(" Took special fast path.");
    141168
    142169    out.print(" LHS ObservedType:<");
     
    144171    out.print("> RHS ObservedType:<");
    145172    out.print(profile.rhsObservedType());
    146     out.print(">");
    147 
    148     out.print(" LHS ResultType:<", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.lhsResultType().bits()))));
    149     out.print("> RHS ResultType:<", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.rhsResultType().bits()))));
    150173    out.print(">");
    151174}
Note: See TracChangeset for help on using the changeset viewer.