Title: [224138] trunk/Source/_javascript_Core
Revision
224138
Author
sbar...@apple.com
Date
2017-10-27 18:03:22 -0700 (Fri, 27 Oct 2017)

Log Message

Bytecode liveness should live on UnlinkedCodeBlock so it can be shared amongst CodeBlocks
https://bugs.webkit.org/show_bug.cgi?id=178949

Reviewed by Keith Miller.

This patch stores BytecodeLiveness on UnlinkedCodeBlock instead of CodeBlock
so that we don't need to recompute liveness for the same UnlinkedCodeBlock
more than once. To do this, this patch solidifies the invariant that CodeBlock
linking can't do anything that would change the result of liveness. For example,
it can't introduce new locals. This invariant was met my JSC before, because we
didn't do anything in bytecode linking that would change liveness. However, it is
now a correctness requirement that we don't do anything that would change the
result of running liveness. To support this change, I've refactored BytecodeGraph
to not be tied to a CodeBlockType*. Things that perform liveness will pass in
CodeBlockType* and the instruction stream as needed. This means that we may
compute liveness with one CodeBlock*'s instruction stream, and then perform
queries on that analysis with a different CodeBlock*'s instruction stream.

This seems to be a 2% JSBench progression.

* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::BytecodeGeneratorification):
(JSC::BytecodeGeneratorification::graph):
(JSC::BytecodeGeneratorification::storageForGeneratorLocal):
(JSC::GeneratorLivenessAnalysis::run):
(JSC::BytecodeGeneratorification::run):
* bytecode/BytecodeGraph.h:
(JSC::BytecodeGraph::BytecodeGraph):
(JSC::BytecodeGraph::codeBlock const): Deleted.
(JSC::BytecodeGraph::instructions): Deleted.
(JSC::BytecodeGraph<Block>::BytecodeGraph): Deleted.
* bytecode/BytecodeLivenessAnalysis.cpp:
(JSC::BytecodeLivenessAnalysis::BytecodeLivenessAnalysis):
(JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::computeFullLiveness):
(JSC::BytecodeLivenessAnalysis::computeKills):
(JSC::BytecodeLivenessAnalysis::dumpResults):
(JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset): Deleted.
(JSC::BytecodeLivenessAnalysis::compute): Deleted.
* bytecode/BytecodeLivenessAnalysis.h:
* bytecode/BytecodeLivenessAnalysisInlines.h:
(JSC::BytecodeLivenessPropagation::stepOverInstruction):
(JSC::BytecodeLivenessPropagation::computeLocalLivenessForBytecodeOffset):
(JSC::BytecodeLivenessPropagation::computeLocalLivenessForBlock):
(JSC::BytecodeLivenessPropagation::getLivenessInfoAtBytecodeOffset):
(JSC::BytecodeLivenessPropagation::runLivenessFixpoint):
* bytecode/BytecodeRewriter.cpp:
(JSC::BytecodeRewriter::applyModification):
(JSC::BytecodeRewriter::execute):
(JSC::BytecodeRewriter::adjustJumpTargetsInFragment):
* bytecode/BytecodeRewriter.h:
(JSC::BytecodeRewriter::BytecodeRewriter):
(JSC::BytecodeRewriter::removeBytecode):
(JSC::BytecodeRewriter::graph):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::ensureCatchLivenessIsComputedForBytecodeOffsetSlow):
(JSC::CodeBlock::validate):
(JSC::CodeBlock::livenessAnalysisSlow): Deleted.
* bytecode/CodeBlock.h:
(JSC::CodeBlock::livenessAnalysis):
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::applyModification):
(JSC::UnlinkedCodeBlock::livenessAnalysisSlow):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::livenessAnalysis):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::livenessFor):
(JSC::DFG::Graph::killsFor):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::cleanMustHandleValuesIfNecessary):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (224137 => 224138)


--- trunk/Source/_javascript_Core/ChangeLog	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-10-28 01:03:22 UTC (rev 224138)
@@ -1,3 +1,79 @@
+2017-10-27  Saam Barati  <sbar...@apple.com>
+
+        Bytecode liveness should live on UnlinkedCodeBlock so it can be shared amongst CodeBlocks
+        https://bugs.webkit.org/show_bug.cgi?id=178949
+
+        Reviewed by Keith Miller.
+
+        This patch stores BytecodeLiveness on UnlinkedCodeBlock instead of CodeBlock
+        so that we don't need to recompute liveness for the same UnlinkedCodeBlock
+        more than once. To do this, this patch solidifies the invariant that CodeBlock
+        linking can't do anything that would change the result of liveness. For example,
+        it can't introduce new locals. This invariant was met my JSC before, because we
+        didn't do anything in bytecode linking that would change liveness. However, it is
+        now a correctness requirement that we don't do anything that would change the
+        result of running liveness. To support this change, I've refactored BytecodeGraph
+        to not be tied to a CodeBlockType*. Things that perform liveness will pass in
+        CodeBlockType* and the instruction stream as needed. This means that we may
+        compute liveness with one CodeBlock*'s instruction stream, and then perform
+        queries on that analysis with a different CodeBlock*'s instruction stream.
+
+        This seems to be a 2% JSBench progression.
+
+        * bytecode/BytecodeGeneratorification.cpp:
+        (JSC::BytecodeGeneratorification::BytecodeGeneratorification):
+        (JSC::BytecodeGeneratorification::graph):
+        (JSC::BytecodeGeneratorification::storageForGeneratorLocal):
+        (JSC::GeneratorLivenessAnalysis::run):
+        (JSC::BytecodeGeneratorification::run):
+        * bytecode/BytecodeGraph.h:
+        (JSC::BytecodeGraph::BytecodeGraph):
+        (JSC::BytecodeGraph::codeBlock const): Deleted.
+        (JSC::BytecodeGraph::instructions): Deleted.
+        (JSC::BytecodeGraph<Block>::BytecodeGraph): Deleted.
+        * bytecode/BytecodeLivenessAnalysis.cpp:
+        (JSC::BytecodeLivenessAnalysis::BytecodeLivenessAnalysis):
+        (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
+        (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
+        (JSC::BytecodeLivenessAnalysis::computeKills):
+        (JSC::BytecodeLivenessAnalysis::dumpResults):
+        (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset): Deleted.
+        (JSC::BytecodeLivenessAnalysis::compute): Deleted.
+        * bytecode/BytecodeLivenessAnalysis.h:
+        * bytecode/BytecodeLivenessAnalysisInlines.h:
+        (JSC::BytecodeLivenessPropagation::stepOverInstruction):
+        (JSC::BytecodeLivenessPropagation::computeLocalLivenessForBytecodeOffset):
+        (JSC::BytecodeLivenessPropagation::computeLocalLivenessForBlock):
+        (JSC::BytecodeLivenessPropagation::getLivenessInfoAtBytecodeOffset):
+        (JSC::BytecodeLivenessPropagation::runLivenessFixpoint):
+        * bytecode/BytecodeRewriter.cpp:
+        (JSC::BytecodeRewriter::applyModification):
+        (JSC::BytecodeRewriter::execute):
+        (JSC::BytecodeRewriter::adjustJumpTargetsInFragment):
+        * bytecode/BytecodeRewriter.h:
+        (JSC::BytecodeRewriter::BytecodeRewriter):
+        (JSC::BytecodeRewriter::removeBytecode):
+        (JSC::BytecodeRewriter::graph):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finishCreation):
+        (JSC::CodeBlock::ensureCatchLivenessIsComputedForBytecodeOffsetSlow):
+        (JSC::CodeBlock::validate):
+        (JSC::CodeBlock::livenessAnalysisSlow): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::livenessAnalysis):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::applyModification):
+        (JSC::UnlinkedCodeBlock::livenessAnalysisSlow):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::livenessAnalysis):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::livenessFor):
+        (JSC::DFG::Graph::killsFor):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+
 2017-10-27  Keith Miller  <keith_mil...@apple.com>
 
         Add unified source list files and build scripts to Xcode project navigator

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -53,13 +53,15 @@
     typedef Vector<YieldData> Yields;
 
     BytecodeGeneratorification(UnlinkedCodeBlock* codeBlock, UnlinkedCodeBlock::UnpackedInstructions& instructions, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex)
-        : m_graph(codeBlock, instructions)
+        : m_codeBlock(codeBlock)
+        , m_instructions(instructions)
+        , m_graph(m_codeBlock, m_instructions)
         , m_generatorFrameSymbolTable(*codeBlock->vm(), generatorFrameSymbolTable)
         , m_generatorFrameSymbolTableIndex(generatorFrameSymbolTableIndex)
     {
         for (BytecodeBasicBlock* block : m_graph) {
             for (unsigned bytecodeOffset : block->offsets()) {
-                const UnlinkedInstruction* pc = &m_graph.instructions()[bytecodeOffset];
+                const UnlinkedInstruction* pc = &instructions[bytecodeOffset];
                 switch (pc->u.opcode) {
                 case op_enter: {
                     m_enterPoint = bytecodeOffset;
@@ -91,7 +93,7 @@
 
     void run();
 
-    BytecodeGraph<UnlinkedCodeBlock>& graph() { return m_graph; }
+    BytecodeGraph& graph() { return m_graph; }
 
     const Yields& yields() const
     {
@@ -121,10 +123,9 @@
         if (std::optional<Storage> storage = m_storages[index])
             return *storage;
 
-        UnlinkedCodeBlock* codeBlock = m_graph.codeBlock();
         Identifier identifier = Identifier::fromUid(PrivateName());
-        unsigned identifierIndex = codeBlock->numberOfIdentifiers();
-        codeBlock->addIdentifier(identifier);
+        unsigned identifierIndex = m_codeBlock->numberOfIdentifiers();
+        m_codeBlock->addIdentifier(identifier);
         ScopeOffset scopeOffset = m_generatorFrameSymbolTable->takeNextScopeOffset(NoLockingNecessary);
         m_generatorFrameSymbolTable->set(NoLockingNecessary, identifier.impl(), SymbolTableEntry(VarOffset(scopeOffset)));
 
@@ -138,7 +139,9 @@
     }
 
     unsigned m_enterPoint { 0 };
-    BytecodeGraph<UnlinkedCodeBlock> m_graph;
+    UnlinkedCodeBlock* m_codeBlock;
+    UnlinkedCodeBlock::UnpackedInstructions& m_instructions;
+    BytecodeGraph m_graph;
     Vector<std::optional<Storage>> m_storages;
     Yields m_yields;
     Strong<SymbolTable> m_generatorFrameSymbolTable;
@@ -152,15 +155,15 @@
     {
     }
 
-    void run()
+    void run(UnlinkedCodeBlock* codeBlock, UnlinkedCodeBlock::UnpackedInstructions& instructions)
     {
         // Perform modified liveness analysis to determine which locals are live at the merge points.
         // This produces the conservative results for the question, "which variables should be saved and resumed?".
 
-        runLivenessFixpoint(m_generatorification.graph());
+        runLivenessFixpoint(codeBlock, instructions, m_generatorification.graph());
 
         for (YieldData& data : m_generatorification.yields())
-            data.liveness = getLivenessInfoAtBytecodeOffset(m_generatorification.graph(), data.point + opcodeLength(op_yield));
+            data.liveness = getLivenessInfoAtBytecodeOffset(codeBlock, instructions, m_generatorification.graph(), data.point + opcodeLength(op_yield));
     }
 
 private:
@@ -173,18 +176,17 @@
 
     {
         GeneratorLivenessAnalysis pass(*this);
-        pass.run();
+        pass.run(m_codeBlock, m_instructions);
     }
 
-    UnlinkedCodeBlock* codeBlock = m_graph.codeBlock();
-    BytecodeRewriter rewriter(m_graph);
+    BytecodeRewriter rewriter(m_graph, m_codeBlock, m_instructions);
 
     // Setup the global switch for the generator.
     {
         unsigned nextToEnterPoint = enterPoint() + opcodeLength(op_enter);
-        unsigned switchTableIndex = m_graph.codeBlock()->numberOfSwitchJumpTables();
+        unsigned switchTableIndex = m_codeBlock->numberOfSwitchJumpTables();
         VirtualRegister state = virtualRegisterForArgument(static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::State));
-        auto& jumpTable = m_graph.codeBlock()->addSwitchJumpTable();
+        auto& jumpTable = m_codeBlock->addSwitchJumpTable();
         jumpTable.min = 0;
         jumpTable.branchOffsets.resize(m_yields.size() + 1);
         jumpTable.branchOffsets.fill(0);
@@ -227,7 +229,7 @@
                 VirtualRegister operand = virtualRegisterForLocal(index);
                 Storage storage = storageForGeneratorLocal(index);
 
-                UnlinkedValueProfile profile = ""
+                UnlinkedValueProfile profile = ""
                 fragment.appendInstruction(
                     op_get_from_scope,
                     operand.offset(), // dst

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeGraph.h (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeGraph.h	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeGraph.h	2017-10-28 01:03:22 UTC (rev 224138)
@@ -35,23 +35,17 @@
 
 class BytecodeBasicBlock;
 
-template<typename Block>
 class BytecodeGraph {
     WTF_MAKE_FAST_ALLOCATED;
     WTF_MAKE_NONCOPYABLE(BytecodeGraph);
 public:
-    typedef Block CodeBlock;
-    typedef typename Block::Instruction Instruction;
     typedef Vector<std::unique_ptr<BytecodeBasicBlock>> BasicBlocksVector;
 
-    typedef WTF::IndexedContainerIterator<BytecodeGraph<Block>> iterator;
+    typedef WTF::IndexedContainerIterator<BytecodeGraph> iterator;
 
-    inline BytecodeGraph(Block*, typename Block::UnpackedInstructions&);
+    template <typename CodeBlockType>
+    inline BytecodeGraph(CodeBlockType*, typename CodeBlockType::UnpackedInstructions&);
 
-    Block* codeBlock() const { return m_codeBlock; }
-
-    typename Block::UnpackedInstructions& instructions() { return m_instructions; }
-
     WTF::IteratorRange<BasicBlocksVector::reverse_iterator> basicBlocksInReverseOrder()
     {
         return WTF::makeIteratorRange(m_basicBlocks.rbegin(), m_basicBlocks.rend());
@@ -106,19 +100,14 @@
     BytecodeBasicBlock* last() { return at(size() - 1); }
 
 private:
-    Block* m_codeBlock;
     BasicBlocksVector m_basicBlocks;
-    typename Block::UnpackedInstructions& m_instructions;
 };
 
 
-template<typename Block>
-BytecodeGraph<Block>::BytecodeGraph(Block* codeBlock, typename Block::UnpackedInstructions& instructions)
-    : m_codeBlock(codeBlock)
-    , m_instructions(instructions)
+template<typename CodeBlockType>
+BytecodeGraph::BytecodeGraph(CodeBlockType* codeBlock, typename CodeBlockType::UnpackedInstructions& instructions)
 {
-    ASSERT(m_codeBlock);
-    BytecodeBasicBlock::compute(m_codeBlock, instructions.begin(), instructions.size(), m_basicBlocks);
+    BytecodeBasicBlock::compute(codeBlock, instructions.begin(), instructions.size(), m_basicBlocks);
     ASSERT(m_basicBlocks.size());
 }
 

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysis.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysis.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysis.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -40,10 +40,13 @@
 BytecodeLivenessAnalysis::BytecodeLivenessAnalysis(CodeBlock* codeBlock)
     : m_graph(codeBlock, codeBlock->instructions())
 {
-    compute();
+    runLivenessFixpoint(codeBlock, codeBlock->instructions(), m_graph);
+
+    if (Options::dumpBytecodeLivenessResults())
+        dumpResults(codeBlock);
 }
 
-void BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
+void BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, FastBitVector& result)
 {
     BytecodeBasicBlock* block = m_graph.findBasicBlockForBytecodeOffset(bytecodeOffset);
     ASSERT(block);
@@ -50,30 +53,20 @@
     ASSERT(!block->isEntryBlock());
     ASSERT(!block->isExitBlock());
     result.resize(block->out().numBits());
-    computeLocalLivenessForBytecodeOffset(m_graph, block, bytecodeOffset, result);
+    computeLocalLivenessForBytecodeOffset(codeBlock, codeBlock->instructions(), m_graph, block, bytecodeOffset, result);
 }
 
-bool BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset)
+FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset)
 {
-    if (operandIsAlwaysLive(operand))
-        return true;
-    FastBitVector result;
-    getLivenessInfoAtBytecodeOffset(bytecodeOffset, result);
-    return operandThatIsNotAlwaysLiveIsLive(result, operand);
-}
-
-FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset)
-{
     FastBitVector out;
-    getLivenessInfoAtBytecodeOffset(bytecodeOffset, out);
+    getLivenessInfoAtBytecodeOffset(codeBlock, bytecodeOffset, out);
     return out;
 }
 
-void BytecodeLivenessAnalysis::computeFullLiveness(FullBytecodeLiveness& result)
+void BytecodeLivenessAnalysis::computeFullLiveness(CodeBlock* codeBlock, FullBytecodeLiveness& result)
 {
     FastBitVector out;
-    CodeBlock* codeBlock = m_graph.codeBlock();
-    
+
     result.m_map.resize(codeBlock->instructions().size());
     
     for (std::unique_ptr<BytecodeBasicBlock>& block : m_graph.basicBlocksInReverseOrder()) {
@@ -84,17 +77,17 @@
         
         for (unsigned i = block->offsets().size(); i--;) {
             unsigned bytecodeOffset = block->offsets()[i];
-            stepOverInstruction(m_graph, bytecodeOffset, out);
+            stepOverInstruction(codeBlock, codeBlock->instructions(), m_graph, bytecodeOffset, out);
             result.m_map[bytecodeOffset] = out;
         }
     }
 }
 
-void BytecodeLivenessAnalysis::computeKills(BytecodeKills& result)
+void BytecodeLivenessAnalysis::computeKills(CodeBlock* codeBlock, BytecodeKills& result)
 {
+    UNUSED_PARAM(result);
     FastBitVector out;
-    
-    CodeBlock* codeBlock = m_graph.codeBlock();
+
     result.m_codeBlock = codeBlock;
     result.m_killSets = std::make_unique<BytecodeKills::KillSet[]>(codeBlock->instructions().size());
     
@@ -107,7 +100,7 @@
         for (unsigned i = block->offsets().size(); i--;) {
             unsigned bytecodeOffset = block->offsets()[i];
             stepOverInstruction(
-                m_graph, bytecodeOffset,
+                codeBlock, codeBlock->instructions(), m_graph, bytecodeOffset,
                 [&] (unsigned index) {
                     // This is for uses.
                     if (out[index])
@@ -123,9 +116,8 @@
     }
 }
 
-void BytecodeLivenessAnalysis::dumpResults()
+void BytecodeLivenessAnalysis::dumpResults(CodeBlock* codeBlock)
 {
-    CodeBlock* codeBlock = m_graph.codeBlock();
     dataLog("\nDumping bytecode liveness for ", *codeBlock, ":\n");
     Instruction* instructionsBegin = codeBlock->instructions().begin();
     unsigned i = 0;
@@ -178,7 +170,7 @@
             const Instruction* currentInstruction = &instructionsBegin[bytecodeOffset];
 
             dataLogF("Live variables:");
-            FastBitVector liveBefore = getLivenessInfoAtBytecodeOffset(bytecodeOffset);
+            FastBitVector liveBefore = getLivenessInfoAtBytecodeOffset(codeBlock, bytecodeOffset);
             dumpBitVector(liveBefore);
             dataLogF("\n");
             codeBlock->dumpBytecode(WTF::dataFile(), instructionsBegin, currentInstruction);
@@ -195,12 +187,4 @@
     }
 }
 
-void BytecodeLivenessAnalysis::compute()
-{
-    runLivenessFixpoint(m_graph);
-
-    if (Options::dumpBytecodeLivenessResults())
-        dumpResults();
-}
-
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysis.h (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysis.h	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysis.h	2017-10-28 01:03:22 UTC (rev 224138)
@@ -37,17 +37,17 @@
 
 class BytecodeLivenessPropagation {
 protected:
-    template<typename Graph, typename UseFunctor, typename DefFunctor> void stepOverInstruction(Graph&, unsigned bytecodeOffset, const UseFunctor&, const DefFunctor&);
+    template<typename CodeBlockType, typename Instructions, typename UseFunctor, typename DefFunctor> void stepOverInstruction(CodeBlockType*, const Instructions&, BytecodeGraph&, unsigned bytecodeOffset, const UseFunctor&, const DefFunctor&);
 
-    template<typename Graph> void stepOverInstruction(Graph&, unsigned bytecodeOffset, FastBitVector& out);
+    template<typename CodeBlockType, typename Instructions> void stepOverInstruction(CodeBlockType*, const Instructions&, BytecodeGraph&, unsigned bytecodeOffset, FastBitVector& out);
 
-    template<typename Graph> bool computeLocalLivenessForBytecodeOffset(Graph&, BytecodeBasicBlock*, unsigned targetOffset, FastBitVector& result);
+    template<typename CodeBlockType, typename Instructions> bool computeLocalLivenessForBytecodeOffset(CodeBlockType*, const Instructions&, BytecodeGraph&, BytecodeBasicBlock*, unsigned targetOffset, FastBitVector& result);
 
-    template<typename Graph> bool computeLocalLivenessForBlock(Graph&, BytecodeBasicBlock*);
+    template<typename CodeBlockType, typename Instructions> bool computeLocalLivenessForBlock(CodeBlockType*, const Instructions&, BytecodeGraph&, BytecodeBasicBlock*);
 
-    template<typename Graph> FastBitVector getLivenessInfoAtBytecodeOffset(Graph&, unsigned bytecodeOffset);
+    template<typename CodeBlockType, typename Instructions> FastBitVector getLivenessInfoAtBytecodeOffset(CodeBlockType*, const Instructions&, BytecodeGraph&, unsigned bytecodeOffset);
 
-    template<typename Graph> void runLivenessFixpoint(Graph&);
+    template<typename CodeBlockType, typename Instructions> void runLivenessFixpoint(CodeBlockType*, const Instructions&, BytecodeGraph&);
 };
 
 class BytecodeLivenessAnalysis : private BytecodeLivenessPropagation {
@@ -57,19 +57,17 @@
     friend class BytecodeLivenessPropagation;
     BytecodeLivenessAnalysis(CodeBlock*);
     
-    bool operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset);
-    FastBitVector getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset);
+    FastBitVector getLivenessInfoAtBytecodeOffset(CodeBlock*, unsigned bytecodeOffset);
     
-    void computeFullLiveness(FullBytecodeLiveness& result);
-    void computeKills(BytecodeKills& result);
+    void computeFullLiveness(CodeBlock*, FullBytecodeLiveness& result);
+    void computeKills(CodeBlock*, BytecodeKills& result);
 
 private:
-    void compute();
-    void dumpResults();
+    void dumpResults(CodeBlock*);
 
-    void getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
+    void getLivenessInfoAtBytecodeOffset(CodeBlock*, unsigned bytecodeOffset, FastBitVector&);
 
-    BytecodeGraph<CodeBlock> m_graph;
+    BytecodeGraph m_graph;
 };
 
 inline bool operandIsAlwaysLive(int operand);

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysisInlines.h (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysisInlines.h	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeLivenessAnalysisInlines.h	2017-10-28 01:03:22 UTC (rev 224138)
@@ -61,8 +61,8 @@
 
 // Simplified interface to bytecode use/def, which determines defs first and then uses, and includes
 // exception handlers in the uses.
-template<typename Graph, typename UseFunctor, typename DefFunctor>
-inline void BytecodeLivenessPropagation::stepOverInstruction(Graph& graph, unsigned bytecodeOffset, const UseFunctor& use, const DefFunctor& def)
+template<typename CodeBlockType, typename Instructions, typename UseFunctor, typename DefFunctor>
+inline void BytecodeLivenessPropagation::stepOverInstruction(CodeBlockType* codeBlock, const Instructions& instructions, BytecodeGraph& graph, unsigned bytecodeOffset, const UseFunctor& use, const DefFunctor& def)
 {
     // This abstractly execute the instruction in reverse. Instructions logically first use operands and
     // then define operands. This logical ordering is necessary for operations that use and def the same
@@ -79,14 +79,13 @@
     // uses before defs, then the add operation above would appear to not have loc1 live, since we'd
     // first add it to the out set (the use), and then we'd remove it (the def).
 
-    auto* codeBlock = graph.codeBlock();
-    auto* instructionsBegin = graph.instructions().begin();
+    auto* instructionsBegin = instructions.begin();
     auto* instruction = &instructionsBegin[bytecodeOffset];
     OpcodeID opcodeID = Interpreter::getOpcodeID(*instruction);
 
     computeDefsForBytecodeOffset(
         codeBlock, opcodeID, instruction,
-        [&] (typename Graph::CodeBlock*, typename Graph::Instruction*, OpcodeID, int operand) {
+        [&] (CodeBlockType*, const typename CodeBlockType::Instruction*, OpcodeID, int operand) {
             if (isValidRegisterForLiveness(operand))
                 def(VirtualRegister(operand).toLocal());
         });
@@ -93,7 +92,7 @@
 
     computeUsesForBytecodeOffset(
         codeBlock, opcodeID, instruction,
-        [&] (typename Graph::CodeBlock*, typename Graph::Instruction*, OpcodeID, int operand) {
+        [&] (CodeBlockType*, const typename CodeBlockType::Instruction*, OpcodeID, int operand) {
             if (isValidRegisterForLiveness(operand))
                 use(VirtualRegister(operand).toLocal());
         });
@@ -107,11 +106,11 @@
     }
 }
 
-template<typename Graph>
-inline void BytecodeLivenessPropagation::stepOverInstruction(Graph& graph, unsigned bytecodeOffset, FastBitVector& out)
+template<typename CodeBlockType, typename Instructions>
+inline void BytecodeLivenessPropagation::stepOverInstruction(CodeBlockType* codeBlock, const Instructions& instructions, BytecodeGraph& graph, unsigned bytecodeOffset, FastBitVector& out)
 {
     stepOverInstruction(
-        graph, bytecodeOffset,
+        codeBlock, instructions, graph, bytecodeOffset,
         [&] (unsigned bitIndex) {
             // This is the use functor, so we set the bit.
             out[bitIndex] = true;
@@ -122,8 +121,8 @@
         });
 }
 
-template<typename Graph>
-inline bool BytecodeLivenessPropagation::computeLocalLivenessForBytecodeOffset(Graph& graph, BytecodeBasicBlock* block, unsigned targetOffset, FastBitVector& result)
+template<typename CodeBlockType, typename Instructions>
+inline bool BytecodeLivenessPropagation::computeLocalLivenessForBytecodeOffset(CodeBlockType* codeBlock, const Instructions& instructions, BytecodeGraph& graph, BytecodeBasicBlock* block, unsigned targetOffset, FastBitVector& result)
 {
     ASSERT(!block->isExitBlock());
     ASSERT(!block->isEntryBlock());
@@ -134,22 +133,22 @@
         unsigned bytecodeOffset = block->offsets()[i];
         if (targetOffset > bytecodeOffset)
             break;
-        stepOverInstruction(graph, bytecodeOffset, out);
+        stepOverInstruction(codeBlock, instructions, graph, bytecodeOffset, out);
     }
 
     return result.setAndCheck(out);
 }
 
-template<typename Graph>
-inline bool BytecodeLivenessPropagation::computeLocalLivenessForBlock(Graph& graph, BytecodeBasicBlock* block)
+template<typename CodeBlockType, typename Instructions>
+inline bool BytecodeLivenessPropagation::computeLocalLivenessForBlock(CodeBlockType* codeBlock, const Instructions& instructions, BytecodeGraph& graph, BytecodeBasicBlock* block)
 {
     if (block->isExitBlock() || block->isEntryBlock())
         return false;
-    return computeLocalLivenessForBytecodeOffset(graph, block, block->leaderOffset(), block->in());
+    return computeLocalLivenessForBytecodeOffset(codeBlock, instructions, graph, block, block->leaderOffset(), block->in());
 }
 
-template<typename Graph>
-inline FastBitVector BytecodeLivenessPropagation::getLivenessInfoAtBytecodeOffset(Graph& graph, unsigned bytecodeOffset)
+template<typename CodeBlockType, typename Instructions>
+inline FastBitVector BytecodeLivenessPropagation::getLivenessInfoAtBytecodeOffset(CodeBlockType* codeBlock, const Instructions& instructions, BytecodeGraph& graph, unsigned bytecodeOffset)
 {
     BytecodeBasicBlock* block = graph.findBasicBlockForBytecodeOffset(bytecodeOffset);
     ASSERT(block);
@@ -157,14 +156,13 @@
     ASSERT(!block->isExitBlock());
     FastBitVector out;
     out.resize(block->out().numBits());
-    computeLocalLivenessForBytecodeOffset(graph, block, bytecodeOffset, out);
+    computeLocalLivenessForBytecodeOffset(codeBlock, instructions, graph, block, bytecodeOffset, out);
     return out;
 }
 
-template<typename Graph>
-inline void BytecodeLivenessPropagation::runLivenessFixpoint(Graph& graph)
+template<typename CodeBlockType, typename Instructions>
+inline void BytecodeLivenessPropagation::runLivenessFixpoint(CodeBlockType* codeBlock, const Instructions& instructions, BytecodeGraph& graph)
 {
-    auto* codeBlock = graph.codeBlock();
     unsigned numberOfVariables = codeBlock->numCalleeLocals();
     for (BytecodeBasicBlock* block : graph) {
         block->in().resize(numberOfVariables);
@@ -186,7 +184,7 @@
             for (BytecodeBasicBlock* successor : block->successors())
                 newOut |= successor->in();
             block->out() = newOut;
-            changed |= computeLocalLivenessForBlock(graph, block.get());
+            changed |= computeLocalLivenessForBlock(codeBlock, instructions, graph, block.get());
         }
     } while (changed);
 }

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -38,13 +38,13 @@
     for (size_t insertionIndex = m_insertions.size(); insertionIndex--;) {
         Insertion& insertion = m_insertions[insertionIndex];
         if (insertion.type == Insertion::Type::Remove)
-            m_graph.instructions().remove(insertion.index.bytecodeOffset, insertion.length());
+            m_instructions.remove(insertion.index.bytecodeOffset, insertion.length());
         else {
             if (insertion.includeBranch == IncludeBranch::Yes) {
                 int finalOffset = insertion.index.bytecodeOffset + calculateDifference(m_insertions.begin(), m_insertions.begin() + insertionIndex);
                 adjustJumpTargetsInFragment(finalOffset, insertion);
             }
-            m_graph.instructions().insertVector(insertion.index.bytecodeOffset, insertion.instructions);
+            m_instructions.insertVector(insertion.index.bytecodeOffset, insertion.instructions);
         }
     }
     m_insertions.clear();
@@ -56,8 +56,7 @@
         return lhs.index < rhs.index;
     });
 
-    UnlinkedCodeBlock* codeBlock = m_graph.codeBlock();
-    codeBlock->applyModification(*this);
+    m_codeBlock->applyModification(*this, m_instructions);
 }
 
 void BytecodeRewriter::adjustJumpTargetsInFragment(unsigned finalOffset, Insertion& insertion)
@@ -69,8 +68,7 @@
         OpcodeID opcodeID = instruction.u.opcode;
         if (isBranch(opcodeID)) {
             unsigned bytecodeOffset = finalOffset + fragmentOffset;
-            UnlinkedCodeBlock* codeBlock = m_graph.codeBlock();
-            extractStoredJumpTargetsForBytecodeOffset(codeBlock, instructionsBegin, fragmentOffset, [&](int32_t& label) {
+            extractStoredJumpTargetsForBytecodeOffset(m_codeBlock, instructionsBegin, fragmentOffset, [&](int32_t& label) {
                 int absoluteOffset = adjustAbsoluteOffset(label);
                 label = absoluteOffset - static_cast<int>(bytecodeOffset);
             });

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.h (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.h	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.h	2017-10-28 01:03:22 UTC (rev 224138)
@@ -161,8 +161,10 @@
         IncludeBranch& m_includeBranch;
     };
 
-    BytecodeRewriter(BytecodeGraph<UnlinkedCodeBlock>& graph)
+    BytecodeRewriter(BytecodeGraph& graph, UnlinkedCodeBlock* codeBlock, UnlinkedCodeBlock::UnpackedInstructions& instructions)
         : m_graph(graph)
+        , m_codeBlock(codeBlock)
+        , m_instructions(instructions)
     {
     }
 
@@ -188,12 +190,12 @@
 
     void removeBytecode(unsigned bytecodeOffset)
     {
-        m_insertions.append(Insertion { InsertionPoint(bytecodeOffset, Position::OriginalBytecodePoint), Insertion::Type::Remove, IncludeBranch::No, opcodeLength(m_graph.instructions()[bytecodeOffset].u.opcode), { } });
+        m_insertions.append(Insertion { InsertionPoint(bytecodeOffset, Position::OriginalBytecodePoint), Insertion::Type::Remove, IncludeBranch::No, opcodeLength(m_instructions[bytecodeOffset].u.opcode), { } });
     }
 
     void execute();
 
-    BytecodeGraph<UnlinkedCodeBlock>& graph() { return m_graph; }
+    BytecodeGraph& graph() { return m_graph; }
 
     int adjustAbsoluteOffset(int absoluteOffset)
     {
@@ -215,7 +217,9 @@
     int adjustJumpTarget(InsertionPoint startPoint, InsertionPoint jumpTargetPoint);
     template<typename Iterator> int calculateDifference(Iterator begin, Iterator end);
 
-    BytecodeGraph<UnlinkedCodeBlock>& m_graph;
+    BytecodeGraph& m_graph;
+    UnlinkedCodeBlock* m_codeBlock;
+    UnlinkedCodeBlock::UnpackedInstructions& m_instructions;
     Vector<Insertion, 8> m_insertions;
 };
 

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -398,10 +398,19 @@
     setNumParameters(unlinkedCodeBlock->numParameters());
 }
 
+// The main purpose of this function is to generate linked bytecode from unlinked bytecode. The process
+// of linking is taking an abstract representation of bytecode and tying it to a GlobalObject and scope
+// chain. For example, this process allows us to cache the depth of lexical environment reads that reach
+// outside of this CodeBlock's compilation unit. It also allows us to generate particular constants that
+// we can't generate during unlinked bytecode generation. This process is not allowed to generate control
+// flow or introduce new locals. The reason for this is we rely on liveness analysis to be the same for
+// all the CodeBlocks of an UnlinkedCodeBlock. We rely on this fact by caching the liveness analysis
+// inside UnlinkedCodeBlock.
 bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
     JSScope* scope)
 {
     Base::finishCreation(vm);
+
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
     if (vm.typeProfiler() || vm.controlFlowProfiler())
@@ -1719,7 +1728,7 @@
     // is because the variables that the op_catch defines might be dead, and
     // we can avoid profiling them and extracting them when doing OSR entry
     // into the DFG.
-    FastBitVector liveLocals = bytecodeLiveness.getLivenessInfoAtBytecodeOffset(bytecodeOffset + OPCODE_LENGTH(op_catch));
+    FastBitVector liveLocals = bytecodeLiveness.getLivenessInfoAtBytecodeOffset(this, bytecodeOffset + OPCODE_LENGTH(op_catch));
     Vector<VirtualRegister> liveOperands;
     liveOperands.reserveInitialCapacity(liveLocals.bitCount());
     liveLocals.forEachSetBit([&] (unsigned liveLocal) {
@@ -2852,7 +2861,7 @@
 {
     BytecodeLivenessAnalysis liveness(this); // Compute directly from scratch so it doesn't effect CodeBlock footprint.
     
-    FastBitVector liveAtHead = liveness.getLivenessInfoAtBytecodeOffset(0);
+    FastBitVector liveAtHead = liveness.getLivenessInfoAtBytecodeOffset(this, 0);
     
     if (liveAtHead.numBits() != static_cast<size_t>(m_numCalleeLocals)) {
         beginValidationDidFail();
@@ -3226,17 +3235,6 @@
 #endif
 }
 
-BytecodeLivenessAnalysis& CodeBlock::livenessAnalysisSlow()
-{
-    std::unique_ptr<BytecodeLivenessAnalysis> analysis = std::make_unique<BytecodeLivenessAnalysis>(this);
-    {
-        ConcurrentJSLocker locker(m_lock);
-        if (!m_livenessAnalysis)
-            m_livenessAnalysis = WTFMove(analysis);
-        return *m_livenessAnalysis;
-    }
-}
-
 void setPrinter(Printer::PrintRecord& record, CodeBlock* codeBlock)
 {
     Printer::setPrinter(record, toCString(codeBlock));

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2017-10-28 01:03:22 UTC (rev 224138)
@@ -115,6 +115,7 @@
     };
 
 public:
+
     enum CopyParsedBlockTag { CopyParsedBlock };
 
     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
@@ -600,12 +601,7 @@
 
     BytecodeLivenessAnalysis& livenessAnalysis()
     {
-        {
-            ConcurrentJSLocker locker(m_lock);
-            if (!!m_livenessAnalysis)
-                return *m_livenessAnalysis;
-        }
-        return livenessAnalysisSlow();
+        return m_unlinkedCode->livenessAnalysis(this);
     }
     
     void validate();
@@ -1059,8 +1055,6 @@
 
     std::chrono::steady_clock::time_point m_creationTime;
 
-    std::unique_ptr<BytecodeLivenessAnalysis> m_livenessAnalysis;
-
     std::unique_ptr<RareData> m_rareData;
 
     UnconditionalFinalizer m_unconditionalFinalizer;

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -28,6 +28,7 @@
 #include "UnlinkedCodeBlock.h"
 
 #include "BytecodeGenerator.h"
+#include "BytecodeLivenessAnalysis.h"
 #include "BytecodeRewriter.h"
 #include "ClassInfo.h"
 #include "CodeCache.h"
@@ -339,15 +340,14 @@
     return UnlinkedHandlerInfo::handlerForIndex(m_rareData->m_exceptionHandlers, index, requiredHandler);
 }
 
-void UnlinkedCodeBlock::applyModification(BytecodeRewriter& rewriter)
+void UnlinkedCodeBlock::applyModification(BytecodeRewriter& rewriter, UnpackedInstructions& instructions)
 {
     // Before applying the changes, we adjust the jumps based on the original bytecode offset, the offset to the jump target, and
     // the insertion information.
 
-    BytecodeGraph<UnlinkedCodeBlock>& graph = rewriter.graph();
-    UnlinkedInstruction* instructionsBegin = graph.instructions().begin();
+    UnlinkedInstruction* instructionsBegin = instructions.begin(); // OOPS: make this an accessor on rewriter.
 
-    for (int bytecodeOffset = 0, instructionCount = graph.instructions().size(); bytecodeOffset < instructionCount;) {
+    for (int bytecodeOffset = 0, instructionCount = instructions.size(); bytecodeOffset < instructionCount;) {
         UnlinkedInstruction* current = instructionsBegin + bytecodeOffset;
         OpcodeID opcodeID = current[0].u.opcode;
         extractStoredJumpTargetsForBytecodeOffset(this, instructionsBegin, bytecodeOffset, [&](int32_t& relativeOffset) {
@@ -386,7 +386,7 @@
 
     // And recompute the jump target based on the modified unlinked instructions.
     m_jumpTargets.clear();
-    recomputePreciseJumpTargets(this, graph.instructions().begin(), graph.instructions().size(), m_jumpTargets);
+    recomputePreciseJumpTargets(this, instructions.begin(), instructions.size(), m_jumpTargets);
 }
 
 void UnlinkedCodeBlock::shrinkToFit()
@@ -418,4 +418,21 @@
 {
 }
 
+BytecodeLivenessAnalysis& UnlinkedCodeBlock::livenessAnalysisSlow(CodeBlock* codeBlock)
+{
+    RELEASE_ASSERT(codeBlock->unlinkedCodeBlock() == this);
+
+
+    {
+        auto locker = holdLock(m_lock);
+        if (!m_liveness) {
+            // There is a chance two compiler threads raced to the slow path.
+            // We defend against computing liveness twice.
+            m_liveness = std::make_unique<BytecodeLivenessAnalysis>(codeBlock);
+        }
+    }
+    
+    return *m_liveness;
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (224137 => 224138)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2017-10-28 01:03:22 UTC (rev 224138)
@@ -46,7 +46,9 @@
 
 namespace JSC {
 
+class BytecodeLivenessAnalysis;
 class BytecodeRewriter;
+class CodeBlock;
 class Debugger;
 class FunctionExecutable;
 class ParserError;
@@ -395,6 +397,13 @@
 
     void dump(PrintStream&) const;
 
+    BytecodeLivenessAnalysis& livenessAnalysis(CodeBlock* codeBlock)
+    {
+        if (m_liveness)
+            return *m_liveness;
+        return livenessAnalysisSlow(codeBlock);
+    }
+
 protected:
     UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&, DebuggerMode);
     ~UnlinkedCodeBlock();
@@ -406,7 +415,7 @@
 
 private:
     friend class BytecodeRewriter;
-    void applyModification(BytecodeRewriter&);
+    void applyModification(BytecodeRewriter&, UnpackedInstructions&);
 
     void createRareDataIfNecessary()
     {
@@ -417,10 +426,12 @@
     }
 
     void getLineAndColumn(const ExpressionRangeInfo&, unsigned& line, unsigned& column) const;
+    BytecodeLivenessAnalysis& livenessAnalysisSlow(CodeBlock*);
 
     int m_numParameters;
 
     std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions;
+    std::unique_ptr<BytecodeLivenessAnalysis> m_liveness;
 
     VirtualRegister m_thisRegister;
     VirtualRegister m_scopeRegister;
@@ -445,6 +456,7 @@
     unsigned m_lineCount;
     unsigned m_endColumn;
 
+    Lock m_lock;
     TriState m_didOptimize;
     SourceParseMode m_parseMode;
     CodeFeatures m_features;

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -1086,7 +1086,7 @@
         return *iter->value;
     
     std::unique_ptr<FullBytecodeLiveness> liveness = std::make_unique<FullBytecodeLiveness>();
-    codeBlock->livenessAnalysis().computeFullLiveness(*liveness);
+    codeBlock->livenessAnalysis().computeFullLiveness(codeBlock, *liveness);
     FullBytecodeLiveness& result = *liveness;
     m_bytecodeLiveness.add(codeBlock, WTFMove(liveness));
     return result;
@@ -1104,7 +1104,7 @@
         return *iter->value;
     
     std::unique_ptr<BytecodeKills> kills = std::make_unique<BytecodeKills>();
-    codeBlock->livenessAnalysis().computeKills(*kills);
+    codeBlock->livenessAnalysis().computeKills(codeBlock, *kills);
     BytecodeKills& result = *kills;
     m_bytecodeKills.add(codeBlock, WTFMove(kills));
     return result;

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -697,7 +697,8 @@
     if (!mustHandleValues.numberOfLocals())
         return;
     
-    FastBitVector liveness = codeBlock->alternative()->livenessAnalysis().getLivenessInfoAtBytecodeOffset(osrEntryBytecodeIndex);
+    CodeBlock* alternative = codeBlock->alternative();
+    FastBitVector liveness = alternative->livenessAnalysis().getLivenessInfoAtBytecodeOffset(alternative, osrEntryBytecodeIndex);
     
     for (unsigned local = mustHandleValues.numberOfLocals(); local--;) {
         if (!liveness[local])

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (224137 => 224138)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2017-10-28 00:09:47 UTC (rev 224137)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2017-10-28 01:03:22 UTC (rev 224138)
@@ -195,7 +195,7 @@
             // Instead, we just find the minimum bytecode offset that is reachable, and
             // compile code from that bytecode offset onwards.
 
-            BytecodeGraph<CodeBlock> graph(m_codeBlock, m_instructions);
+            BytecodeGraph graph(m_codeBlock, m_instructions);
             BytecodeBasicBlock* block = graph.findBasicBlockForBytecodeOffset(m_loopOSREntryBytecodeOffset);
             RELEASE_ASSERT(block);
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to