⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 204112 in webkit


Ignore:
Timestamp:
Aug 3, 2016, 8:43:51 PM (10 years ago)
Author:
commit-queue@webkit.org
Message:

[JSC] Improve the memory locality of DFG Node's AbstractValues
​https://bugs.webkit.org/show_bug.cgi?id=160443

Patch by Benjamin Poulain <​bpoulain@apple.com> on 2016-08-03
Reviewed by Mark Lam.

The AbstractInterpreter spends a lot of time on memory operations
for AbstractValues. This patch attempts to improve the situation
by putting the values closer together in memory.

First, AbstractValue is moved out of DFG::Node and it kept in
a vector addressed by node indices.

I initially moved them to InPlaceAbstractState but I quickly discovered
initializing the values in the vector was costly.
I moved the vector to Graph as a cache shared by every instantiation of
InPlaceAbstractState. It is mainly there to avoid constructors and destructors
of AbstractValue. The patch of ​https://bugs.webkit.org/show_bug.cgi?id=160370
should also help eventually.

I instrumented CFA to find how packed is SparseCollection.
The answer is it can be very sparse, which is bad for CFA.
I added packIndices() to repack the collection before running
liveness since that's where we start using the memory intensively.
This is a measurable improvement but it implies we can no longer
keep indices on a side channel between phases since they may change.

  • b3/B3SparseCollection.h:

(JSC::B3::SparseCollection::packIndices):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::packNodeIndices):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::abstractValuesCache):

  • dfg/DFGInPlaceAbstractState.cpp:

(JSC::DFG::InPlaceAbstractState::InPlaceAbstractState):

  • dfg/DFGInPlaceAbstractState.h:

(JSC::DFG::InPlaceAbstractState::forNode):

  • dfg/DFGLivenessAnalysisPhase.cpp:

(JSC::DFG::performLivenessAnalysis):

  • dfg/DFGNode.h:
Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r204111 r204112  
     12016-08-03  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Improve the memory locality of DFG Node's AbstractValues
     4        https://bugs.webkit.org/show_bug.cgi?id=160443
     5
     6        Reviewed by Mark Lam.
     7
     8        The AbstractInterpreter spends a lot of time on memory operations
     9        for AbstractValues. This patch attempts to improve the situation
     10        by putting the values closer together in memory.
     11
     12        First, AbstractValue is moved out of DFG::Node and it kept in
     13        a vector addressed by node indices.
     14
     15        I initially moved them to InPlaceAbstractState but I quickly discovered
     16        initializing the values in the vector was costly.
     17        I moved the vector to Graph as a cache shared by every instantiation of
     18        InPlaceAbstractState. It is mainly there to avoid constructors and destructors
     19        of AbstractValue. The patch of https://bugs.webkit.org/show_bug.cgi?id=160370
     20        should also help eventually.
     21
     22        I instrumented CFA to find how packed is SparseCollection.
     23        The answer is it can be very sparse, which is bad for CFA.
     24        I added packIndices() to repack the collection before running
     25        liveness since that's where we start using the memory intensively.
     26        This is a measurable improvement but it implies we can no longer
     27        keep indices on a side channel between phases since they may change.
     28
     29        * b3/B3SparseCollection.h:
     30        (JSC::B3::SparseCollection::packIndices):
     31        * dfg/DFGGraph.cpp:
     32        (JSC::DFG::Graph::packNodeIndices):
     33        * dfg/DFGGraph.h:
     34        (JSC::DFG::Graph::abstractValuesCache):
     35        * dfg/DFGInPlaceAbstractState.cpp:
     36        (JSC::DFG::InPlaceAbstractState::InPlaceAbstractState):
     37        * dfg/DFGInPlaceAbstractState.h:
     38        (JSC::DFG::InPlaceAbstractState::forNode):
     39        * dfg/DFGLivenessAnalysisPhase.cpp:
     40        (JSC::DFG::performLivenessAnalysis):
     41        * dfg/DFGNode.h:
     42
    1432016-08-03  Caitlin Potter  <caitp@igalia.com>
    244
  • trunk/Source/JavaScriptCore/b3/B3SparseCollection.h

    r203808 r204112  
    7575    }
    7676
     77    void packIndices()
     78    {
     79        if (m_indexFreeList.isEmpty())
     80            return;
     81
     82        unsigned holeIndex = 0;
     83        unsigned endIndex = m_vector.size();
     84
     85        while (true) {
     86            while (holeIndex < endIndex && m_vector[holeIndex])
     87                ++holeIndex;
     88
     89            if (holeIndex == endIndex)
     90                break;
     91            ASSERT(holeIndex < m_vector.size());
     92            ASSERT(!m_vector[holeIndex]);
     93
     94            do {
     95                --endIndex;
     96            } while (!m_vector[endIndex] && endIndex > holeIndex);
     97
     98            if (holeIndex == endIndex)
     99                break;
     100            ASSERT(endIndex > holeIndex);
     101            ASSERT(m_vector[endIndex]);
     102
     103            auto& value = m_vector[endIndex];
     104            value->m_index = holeIndex;
     105            m_vector[holeIndex] = WTFMove(value);
     106            ++holeIndex;
     107        }
     108
     109        m_indexFreeList.resize(0);
     110        m_vector.resize(endIndex);
     111    }
     112
    77113    unsigned size() const { return m_vector.size(); }
    78114    bool isEmpty() const { return m_vector.isEmpty(); }
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r203923 r204112  
    577577    }
    578578    m_nodes.remove(node);
     579}
     580
     581void Graph::packNodeIndices()
     582{
     583    m_nodes.packIndices();
    579584}
    580585
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r203921 r204112  
    198198    unsigned maxNodeCount() const { return m_nodes.size(); }
    199199    Node* nodeAt(unsigned index) const { return m_nodes[index]; }
     200    void packNodeIndices();
     201
     202    Vector<AbstractValue>& abstractValuesCache() { return m_abstractValuesCache; }
    200203
    201204    void dethread();
    … …  
    955958
    956959    B3::SparseCollection<Node> m_nodes;
     960    Vector<AbstractValue> m_abstractValuesCache;
    957961};
    958962
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp

    r203921 r204112  
    4242InPlaceAbstractState::InPlaceAbstractState(Graph& graph)
    4343    : m_graph(graph)
     44    , m_abstractValues(graph.abstractValuesCache())
    4445    , m_variables(m_graph.m_codeBlock->numParameters(), graph.m_localVars)
    4546    , m_block(0)
    … …  
    5657    ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals());
    5758    ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->variablesAtTail.numberOfLocals());
     59
     60    // Certain phases insert nodes in a block after running through it.
     61    // We cannot reserve the space for AbstractValues when initializing AbstractState because the number of values
     62    // can increase as we execute. Instead, we increase the size as needed before processing each block.
     63    m_abstractValues.resize(m_graph.maxNodeCount());
    5864   
    5965    for (size_t i = 0; i < basicBlock->size(); i++)
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h

    r201182 r204112  
    4949    AbstractValue& forNode(Node* node)
    5050    {
    51         return node->value;
     51        return m_abstractValues[node->index()];
    5252    }
    5353   
    … …  
    133133   
    134134    Graph& m_graph;
    135    
     135
     136    Vector<AbstractValue>& m_abstractValues;
    136137    Operands<AbstractValue> m_variables;
    137138    BasicBlock* m_block;
  • trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp

    r203921 r204112  
    196196bool performLivenessAnalysis(Graph& graph)
    197197{
     198    graph.packNodeIndices();
     199
    198200    return runPhase<LivenessAnalysisPhase>(graph);
    199201}
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r203923 r204112  
    23632363    uintptr_t m_opInfo2;
    23642364
    2365 public:
    2366     // Fields used by various analyses.
    2367     AbstractValue value;
    2368    
    23692365    // Miscellaneous data that is usually meaningless, but can hold some analysis results
    23702366    // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
Note: See TracChangeset for help on using the changeset viewer.