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