Ignore:
Timestamp:
Nov 4, 2019, 2:20:37 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/jit/JITArithmetic.cpp

    r251886 r252015  
    454454void JIT::emit_op_negate(const Instruction* currentInstruction)
    455455{
    456     ArithProfile* arithProfile = &currentInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;
     456    UnaryArithProfile* arithProfile = &currentInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;
    457457    JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile);
    458458    m_instructionToMathIC.add(currentInstruction, negateIC);
     
    635635}
    636636
    637 ALWAYS_INLINE static OperandTypes getOperandTypes(const ArithProfile& arithProfile)
    638 {
    639     return OperandTypes(arithProfile.lhsResultType(), arithProfile.rhsResultType());
    640 }
    641 
    642637void JIT::emit_op_add(const Instruction* currentInstruction)
    643638{
    644     ArithProfile* arithProfile = &currentInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;
     639    BinaryArithProfile* arithProfile = &currentInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;
    645640    JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile);
    646641    m_instructionToMathIC.add(currentInstruction, addIC);
     
    687682    bool generatedInlineCode = mathIC->generateInline(*this, mathICGenerationState);
    688683    if (!generatedInlineCode) {
    689         ArithProfile* arithProfile = mathIC->arithProfile();
     684        UnaryArithProfile* arithProfile = mathIC->arithProfile();
    690685        if (arithProfile && shouldEmitProfiling())
    691686            callOperationWithResult(profiledFunction, resultRegs, TrustedImmPtr(m_codeBlock->globalObject()), srcRegs, arithProfile);
     
    710705{
    711706    auto bytecode = currentInstruction->as<Op>();
    712     OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));
    713707    int result = bytecode.m_dst.offset();
    714708    int op1 = bytecode.m_lhs.offset();
     
    729723#endif
    730724
    731     SnippetOperand leftOperand(types.first());
    732     SnippetOperand rightOperand(types.second());
     725    SnippetOperand leftOperand(bytecode.m_operandTypes.first());
     726    SnippetOperand rightOperand(bytecode.m_operandTypes.second());
    733727
    734728    if (isOperandConstantInt(op1))
     
    760754        else if (rightOperand.isConst())
    761755            emitGetVirtualRegister(op2, rightRegs);
    762         ArithProfile* arithProfile = mathIC->arithProfile();
     756        BinaryArithProfile* arithProfile = mathIC->arithProfile();
    763757        if (arithProfile && shouldEmitProfiling())
    764758            callOperationWithResult(profiledFunction, resultRegs, TrustedImmPtr(m_codeBlock->globalObject()), leftRegs, rightRegs, arithProfile);
     
    800794#endif
    801795
    802     ArithProfile* arithProfile = mathIC->arithProfile();
     796    UnaryArithProfile* arithProfile = mathIC->arithProfile();
    803797    if (arithProfile && shouldEmitProfiling()) {
    804798        if (mathICGenerationState.shouldSlowPathRepatch)
     
    832826
    833827    auto bytecode = currentInstruction->as<Op>();
    834     OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));
    835828    int result = bytecode.m_dst.offset();
    836829    int op1 = bytecode.m_lhs.offset();
     
    847840#endif
    848841   
    849     SnippetOperand leftOperand(types.first());
    850     SnippetOperand rightOperand(types.second());
     842    SnippetOperand leftOperand(bytecode.m_operandTypes.first());
     843    SnippetOperand rightOperand(bytecode.m_operandTypes.second());
    851844
    852845    if (isOperandConstantInt(op1))
     
    866859#endif
    867860
    868     ArithProfile* arithProfile = mathIC->arithProfile();
     861    BinaryArithProfile* arithProfile = mathIC->arithProfile();
    869862    if (arithProfile && shouldEmitProfiling()) {
    870863        if (mathICGenerationState.shouldSlowPathRepatch)
     
    894887{
    895888    auto bytecode = currentInstruction->as<OpDiv>();
    896     auto& metadata = bytecode.metadata(m_codeBlock);
    897889    int result = bytecode.m_dst.offset();
    898890    int op1 = bytecode.m_lhs.offset();
     
    900892
    901893#if USE(JSVALUE64)
    902     OperandTypes types = getOperandTypes(metadata.m_arithProfile);
    903894    JSValueRegs leftRegs = JSValueRegs(regT0);
    904895    JSValueRegs rightRegs = JSValueRegs(regT1);
     
    906897    GPRReg scratchGPR = regT2;
    907898#else
    908     OperandTypes types = getOperandTypes(metadata.m_arithProfile);
    909899    JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
    910900    JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
     
    914904    FPRReg scratchFPR = fpRegT2;
    915905
    916     ArithProfile* arithProfile = nullptr;
     906    BinaryArithProfile* arithProfile = nullptr;
    917907    if (shouldEmitProfiling())
    918908        arithProfile = &currentInstruction->as<OpDiv>().metadata(m_codeBlock).m_arithProfile;
    919909
    920     SnippetOperand leftOperand(types.first());
    921     SnippetOperand rightOperand(types.second());
     910    SnippetOperand leftOperand(bytecode.m_operandTypes.first());
     911    SnippetOperand rightOperand(bytecode.m_operandTypes.second());
    922912
    923913    if (isOperandConstantInt(op1))
     
    961951void JIT::emit_op_mul(const Instruction* currentInstruction)
    962952{
    963     ArithProfile* arithProfile = &currentInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;
     953    BinaryArithProfile* arithProfile = &currentInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;
    964954    JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile);
    965955    m_instructionToMathIC.add(currentInstruction, mulIC);
     
    977967void JIT::emit_op_sub(const Instruction* currentInstruction)
    978968{
    979     ArithProfile* arithProfile = &currentInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;
     969    BinaryArithProfile* arithProfile = &currentInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;
    980970    JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile);
    981971    m_instructionToMathIC.add(currentInstruction, subIC);
Note: See TracChangeset for help on using the changeset viewer.