1 // Copyright 2017 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_ 6 #define V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_ 7 8 #include "src/base/compiler-specific.h" 9 #include "src/compiler/escape-analysis.h" 10 #include "src/compiler/graph-reducer.h" 11 #include "src/globals.h" 12 13 namespace v8 { 14 namespace internal { 15 namespace compiler { 16 17 class Deduplicator; 18 class JSGraph; 19 20 // Perform hash-consing when creating or mutating nodes. Used to avoid duplicate 21 // nodes when creating ObjectState, StateValues and FrameState nodes 22 class NodeHashCache { 23 public: NodeHashCache(Graph * graph,Zone * zone)24 NodeHashCache(Graph* graph, Zone* zone) 25 : graph_(graph), cache_(zone), temp_nodes_(zone) {} 26 27 // Handle to a conceptually new mutable node. Tries to re-use existing nodes 28 // and to recycle memory if possible. 29 class Constructor { 30 public: 31 // Construct a new node as a clone of [from]. Constructor(NodeHashCache * cache,Node * from)32 Constructor(NodeHashCache* cache, Node* from) 33 : node_cache_(cache), from_(from), tmp_(nullptr) {} 34 // Construct a new node from scratch. 35 Constructor(NodeHashCache* cache, const Operator* op, int input_count, 36 Node** inputs, Type type); 37 38 // Modify the new node. ReplaceValueInput(Node * input,int i)39 void ReplaceValueInput(Node* input, int i) { 40 if (!tmp_ && input == NodeProperties::GetValueInput(from_, i)) return; 41 Node* node = MutableNode(); 42 NodeProperties::ReplaceValueInput(node, input, i); 43 } ReplaceInput(Node * input,int i)44 void ReplaceInput(Node* input, int i) { 45 if (!tmp_ && input == from_->InputAt(i)) return; 46 Node* node = MutableNode(); 47 node->ReplaceInput(i, input); 48 } 49 50 // Obtain the mutated node or a cached copy. Invalidates the [Constructor]. 51 Node* Get(); 52 53 private: 54 Node* MutableNode(); 55 56 NodeHashCache* node_cache_; 57 // Original node, copied on write. 58 Node* from_; 59 // Temporary node used for mutations, can be recycled if cache is hit. 60 Node* tmp_; 61 }; 62 63 private: 64 Node* Query(Node* node); Insert(Node * node)65 void Insert(Node* node) { cache_.insert(node); } 66 67 Graph* graph_; 68 struct NodeEquals { operatorNodeEquals69 bool operator()(Node* a, Node* b) const { 70 return NodeProperties::Equals(a, b); 71 } 72 }; 73 struct NodeHashCode { operatorNodeHashCode74 size_t operator()(Node* n) const { return NodeProperties::HashCode(n); } 75 }; 76 ZoneUnorderedSet<Node*, NodeHashCode, NodeEquals> cache_; 77 // Unused nodes whose memory can be recycled. 78 ZoneVector<Node*> temp_nodes_; 79 }; 80 81 // Modify the graph according to the information computed in the previous phase. 82 class V8_EXPORT_PRIVATE EscapeAnalysisReducer final NON_EXPORTED_BASE(AdvancedReducer)83 : public NON_EXPORTED_BASE(AdvancedReducer) { 84 public: 85 EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph, 86 EscapeAnalysisResult analysis_result, Zone* zone); 87 88 Reduction Reduce(Node* node) override; 89 const char* reducer_name() const override { return "EscapeAnalysisReducer"; } 90 void Finalize() override; 91 92 // Verifies that all virtual allocation nodes have been dealt with. Run it 93 // after this reducer has been applied. 94 void VerifyReplacement() const; 95 96 private: 97 void ReduceFrameStateInputs(Node* node); 98 Node* ReduceDeoptState(Node* node, Node* effect, Deduplicator* deduplicator); 99 Node* ObjectIdNode(const VirtualObject* vobject); 100 Reduction ReplaceNode(Node* original, Node* replacement); 101 102 JSGraph* jsgraph() const { return jsgraph_; } 103 Isolate* isolate() const { return jsgraph_->isolate(); } 104 EscapeAnalysisResult analysis_result() const { return analysis_result_; } 105 Zone* zone() const { return zone_; } 106 107 JSGraph* const jsgraph_; 108 EscapeAnalysisResult analysis_result_; 109 ZoneVector<Node*> object_id_cache_; 110 NodeHashCache node_cache_; 111 ZoneSet<Node*> arguments_elements_; 112 Zone* const zone_; 113 114 DISALLOW_COPY_AND_ASSIGN(EscapeAnalysisReducer); 115 }; 116 117 } // namespace compiler 118 } // namespace internal 119 } // namespace v8 120 121 #endif // V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_ 122