Ignore:
Timestamp:
Apr 14, 2021, 8:29:18 PM (4 years ago)
Author:
[email protected]
Message:

[JSC] Do not copy SimpleJumpTable
https://bugs.webkit.org/show_bug.cgi?id=224472

Reviewed by Mark Lam.

This patch avoids copying UnlinkedSimpleJumpTable to SimpleJumpTable by decoupling CTI addresses from jump offset in SimpleJumpTable.
SimpleJumpTable and UnlinkedSimpleJumpTable are almost identical. SimpleJumpTable adds JIT jump target for each branch.
We should use data from UnlinkedSimpleJumpTable and jump via SimpleJumpTable. Do not need to have copy of branches from UnlinkedSimpleJumpTable.

This way removes Vector<SimpleJumpTable> from CodeBlock::RareData. And this is moved to CodeBlock::JITData. And it only includes jump target addresses,
and branch offset information is kept in UnlinkedSimpleJumpTable side. We no longer need to carefully copy these vectors in CodeBlock including DFG / FTL ones.

In LLInt, we instead use UnlinkedSimpleJumpTable for jumping.

In Baseline, we first allocate enough FixedVector<SimpleJumpTable> and fill content via SimpleJumpTable::ensureCTITable() call when compiling corresponding
switch opcode. Finally we fill these data structures with actual code locations in JIT::link function.

In DFG, we first collect UnlinkedSimpleJumpTable without copying. This is OK since it is kept by UnlinkedCodeBlock, and UnlinkedCodeBlock is kept by baseline CodeBlocks that
are handled by this DFG compilation. We hold Vector<const UnlinkedSimpleJumpTable*> in DFG::Graph and we materialize Vector<SimpleJumpTable> in DFG::Graph.
During DFG compilation, we touch this DFG::Graph's jump tables, and JIT compiler generates code via these tables. And when linking, we move the content to CodeBlock.

In FTL, while we use UnlinkedSimpleJumpTable in FTL code generation, FTL do not use SimpleJumpTable and instead FTL uses Switch in B3.

  • bytecode/BytecodeDumper.cpp:

(JSC::CodeBlockBytecodeDumper<Block>::dumpSwitchJumpTables):

  • bytecode/BytecodeDumper.h:
  • bytecode/BytecodeGeneratorification.cpp:

(JSC::BytecodeGeneratorification::run):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::shrinkToFit):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::switchJumpTable):
(JSC::CodeBlock::numberOfUnlinkedSwitchJumpTables const):
(JSC::CodeBlock::unlinkedSwitchJumpTable):
(JSC::CodeBlock::numberOfSwitchJumpTables const): Deleted.
(JSC::CodeBlock::clearSwitchJumpTables): Deleted.
(JSC::CodeBlock::addSwitchJumpTableFromProfiledCodeBlock): Deleted.

  • bytecode/JumpTable.cpp:

(JSC::SimpleJumpTable::offsetForValue): Deleted.

  • bytecode/JumpTable.h:

(JSC::SimpleJumpTable::ensureCTITable):
(JSC::SimpleJumpTable::ctiForValue const):
(JSC::SimpleJumpTable::isEmpty const):
(): Deleted.
(JSC::SimpleJumpTable::cloneNonJITPart const): Deleted.
(JSC::SimpleJumpTable::ctiForValue): Deleted.
(JSC::SimpleJumpTable::clear): Deleted.

  • bytecode/PreciseJumpTargetsInlines.h:
  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedSimpleJumpTable::offsetForValue const):
(JSC::UnlinkedSimpleJumpTable::add):
(JSC::UnlinkedCodeBlock::numberOfUnlinkedSwitchJumpTables const):
(JSC::UnlinkedCodeBlock::unlinkedSwitchJumpTable const):
(JSC::UnlinkedCodeBlock::unlinkedStringSwitchJumpTable const):
(JSC::UnlinkedCodeBlock::numberOfSwitchJumpTables const): Deleted.
(JSC::UnlinkedCodeBlock::switchJumpTable): Deleted.
(JSC::UnlinkedCodeBlock::unlinkedStringSwitchJumpTable): Deleted.

  • bytecode/UnlinkedCodeBlockGenerator.cpp:

(JSC::UnlinkedCodeBlockGenerator::finalize):

  • bytecode/UnlinkedCodeBlockGenerator.h:

(JSC::UnlinkedCodeBlockGenerator::numberOfUnlinkedSwitchJumpTables const):
(JSC::UnlinkedCodeBlockGenerator::addUnlinkedSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::unlinkedSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::numberOfSwitchJumpTables const): Deleted.
(JSC::UnlinkedCodeBlockGenerator::addSwitchJumpTable): Deleted.
(JSC::UnlinkedCodeBlockGenerator::switchJumpTable): Deleted.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::beginSwitch):
(JSC::prepareJumpTableForSwitch):
(JSC::BytecodeGenerator::endSwitch):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGGraph.h:
  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGOperations.cpp:

(JSC::DFG::JSC_DEFINE_JIT_OPERATION):

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

(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::emitSwitchString):

  • ftl/FTLLink.cpp:

(JSC::FTL::link):

  • jit/JIT.cpp:

(JSC::JIT::compileWithoutLinking):
(JSC::JIT::link):

  • jit/JIT.h:

(JSC::SwitchRecord::SwitchRecord):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):

  • jit/JITOperations.cpp:

(JSC::JSC_DEFINE_JIT_OPERATION):

  • jit/JITOperations.h:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

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

(JSC::CachedSimpleJumpTable::encode):
(JSC::CachedSimpleJumpTable::decode const):
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r275840 r275995  
    715715    }
    716716
     717    if (m_codeBlock->numberOfUnlinkedSwitchJumpTables() || m_codeBlock->numberOfUnlinkedStringSwitchJumpTables()) {
     718        ConcurrentJSLocker locker(m_codeBlock->m_lock);
     719        if (m_codeBlock->numberOfUnlinkedSwitchJumpTables())
     720            m_codeBlock->ensureJITData(locker).m_switchJumpTables = FixedVector<SimpleJumpTable>(m_codeBlock->numberOfUnlinkedSwitchJumpTables());
     721        if (m_codeBlock->numberOfUnlinkedStringSwitchJumpTables())
     722            m_codeBlock->ensureJITData(locker).m_stringSwitchJumpTables = FixedVector<StringJumpTable>(m_codeBlock->numberOfUnlinkedStringSwitchJumpTables());
     723    }
     724
    717725    if (UNLIKELY(Options::dumpDisassembly() || (m_vm->m_perBytecodeProfiler && Options::disassembleBaselineForProfiler())))
    718726        m_disassembler = makeUnique<JITDisassembler>(m_codeBlock);
     
    858866        return CompilationFailed;
    859867
    860     if (m_codeBlock->numberOfUnlinkedStringSwitchJumpTables()) {
    861         ConcurrentJSLocker locker(m_codeBlock->m_lock);
    862         m_codeBlock->ensureJITData(locker).m_stringSwitchJumpTables = FixedVector<StringJumpTable>(m_codeBlock->numberOfUnlinkedStringSwitchJumpTables());
    863     }
    864 
    865868    // Translate vPC offsets into addresses in JIT generated code, for switch tables.
    866869    for (auto& record : m_switches) {
     
    869872        if (record.type != SwitchRecord::String) {
    870873            ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character);
    871             ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size());
    872 
    873             auto* simpleJumpTable = record.jumpTable.simpleJumpTable;
    874             simpleJumpTable->ctiDefault = patchBuffer.locationOf<JSSwitchPtrTag>(m_labels[bytecodeOffset + record.defaultOffset]);
    875 
    876             for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) {
    877                 unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j];
    878                 simpleJumpTable->ctiOffsets[j] = offset
     874
     875            unsigned tableIndex = record.tableIndex;
     876            const UnlinkedSimpleJumpTable& unlinkedTable = m_codeBlock->unlinkedSwitchJumpTable(tableIndex);
     877            SimpleJumpTable& linkedTable = m_codeBlock->switchJumpTable(tableIndex);
     878            linkedTable.m_ctiDefault = patchBuffer.locationOf<JSSwitchPtrTag>(m_labels[bytecodeOffset + record.defaultOffset]);
     879
     880            for (unsigned j = 0; j < unlinkedTable.m_branchOffsets.size(); ++j) {
     881                unsigned offset = unlinkedTable.m_branchOffsets[j];
     882                linkedTable.m_ctiOffsets[j] = offset
    879883                    ? patchBuffer.locationOf<JSSwitchPtrTag>(m_labels[bytecodeOffset + offset])
    880                     : simpleJumpTable->ctiDefault;
     884                    : linkedTable.m_ctiDefault;
    881885            }
    882886        } else {
    883887            ASSERT(record.type == SwitchRecord::String);
    884888
    885             unsigned tableIndex = record.jumpTable.tableIndex;
     889            unsigned tableIndex = record.tableIndex;
    886890            const UnlinkedStringJumpTable& unlinkedTable = m_codeBlock->unlinkedStringSwitchJumpTable(tableIndex);
    887891            StringJumpTable& linkedTable = m_codeBlock->stringSwitchJumpTable(tableIndex);
Note: See TracChangeset for help on using the changeset viewer.