• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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