Changeset 204112 in webkit
- Timestamp:
- Aug 3, 2016, 8:43:51 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
-
ChangeLog (modified) (1 diff)
-
b3/B3SparseCollection.h (modified) (1 diff)
-
dfg/DFGGraph.cpp (modified) (1 diff)
-
dfg/DFGGraph.h (modified) (2 diffs)
-
dfg/DFGInPlaceAbstractState.cpp (modified) (2 diffs)
-
dfg/DFGInPlaceAbstractState.h (modified) (2 diffs)
-
dfg/DFGLivenessAnalysisPhase.cpp (modified) (1 diff)
-
dfg/DFGNode.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r204111 r204112 1 2016-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 1 43 2016-08-03 Caitlin Potter <caitp@igalia.com> 2 44 -
trunk/Source/JavaScriptCore/b3/B3SparseCollection.h
r203808 r204112 75 75 } 76 76 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 77 113 unsigned size() const { return m_vector.size(); } 78 114 bool isEmpty() const { return m_vector.isEmpty(); } -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r203923 r204112 577 577 } 578 578 m_nodes.remove(node); 579 } 580 581 void Graph::packNodeIndices() 582 { 583 m_nodes.packIndices(); 579 584 } 580 585 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r203921 r204112 198 198 unsigned maxNodeCount() const { return m_nodes.size(); } 199 199 Node* nodeAt(unsigned index) const { return m_nodes[index]; } 200 void packNodeIndices(); 201 202 Vector<AbstractValue>& abstractValuesCache() { return m_abstractValuesCache; } 200 203 201 204 void dethread(); … … 955 958 956 959 B3::SparseCollection<Node> m_nodes; 960 Vector<AbstractValue> m_abstractValuesCache; 957 961 }; 958 962 -
trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
r203921 r204112 42 42 InPlaceAbstractState::InPlaceAbstractState(Graph& graph) 43 43 : m_graph(graph) 44 , m_abstractValues(graph.abstractValuesCache()) 44 45 , m_variables(m_graph.m_codeBlock->numParameters(), graph.m_localVars) 45 46 , m_block(0) … … 56 57 ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals()); 57 58 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()); 58 64 59 65 for (size_t i = 0; i < basicBlock->size(); i++) -
trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h
r201182 r204112 49 49 AbstractValue& forNode(Node* node) 50 50 { 51 return node->value;51 return m_abstractValues[node->index()]; 52 52 } 53 53 … … 133 133 134 134 Graph& m_graph; 135 135 136 Vector<AbstractValue>& m_abstractValues; 136 137 Operands<AbstractValue> m_variables; 137 138 BasicBlock* m_block; -
trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp
r203921 r204112 196 196 bool performLivenessAnalysis(Graph& graph) 197 197 { 198 graph.packNodeIndices(); 199 198 200 return runPhase<LivenessAnalysisPhase>(graph); 199 201 } -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r203923 r204112 2363 2363 uintptr_t m_opInfo2; 2364 2364 2365 public:2366 // Fields used by various analyses.2367 AbstractValue value;2368 2369 2365 // Miscellaneous data that is usually meaningless, but can hold some analysis results 2370 2366 // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
Note:
See TracChangeset
for help on using the changeset viewer.