OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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_MEMORY_OPTIMIZER_H_ | |
6 #define V8_COMPILER_MEMORY_OPTIMIZER_H_ | |
7 | |
8 #include "src/zone-containers.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 namespace compiler { | |
13 | |
14 // Forward declarations. | |
15 class CommonOperatorBuilder; | |
16 struct ElementAccess; | |
17 class Graph; | |
18 class JSGraph; | |
19 class MachineOperatorBuilder; | |
20 class Node; | |
21 class Operator; | |
22 | |
23 // NodeIds are identifying numbers for nodes that can be used to index auxiliary | |
24 // out-of-line data associated with each node. | |
25 typedef uint32_t NodeId; | |
26 | |
27 // Lowers all simplified memory access and allocation related nodes (i.e. | |
28 // Allocate, LoadField, StoreField and friends) to machine operators. | |
29 // Performs allocation folding and store write barrier elimination | |
30 // implicitly. | |
31 class MemoryOptimizer final { | |
32 public: | |
33 MemoryOptimizer(JSGraph* jsgraph, Zone* zone); | |
34 ~MemoryOptimizer() {} | |
35 | |
36 void Optimize(); | |
Jarin
2016/05/10 09:24:49
Don't we normally call these methods 'Run'?
Benedikt Meurer
2016/05/10 09:34:04
Followed the pattern of ControlFlowOptimizer here.
| |
37 | |
38 private: | |
39 // An allocation group represents a set of allocations that have been folded | |
40 // together. | |
41 class AllocationGroup final : public ZoneObject { | |
42 public: | |
43 AllocationGroup(Node* node, PretenureFlag pretenure, Zone* zone); | |
44 AllocationGroup(Node* node, PretenureFlag pretenure, Node* size, | |
45 Zone* zone); | |
46 ~AllocationGroup() {} | |
47 | |
48 void Add(Node* object); | |
49 bool Contains(Node* object) const; | |
50 bool IsNewSpaceAllocation() const { return pretenure() == NOT_TENURED; } | |
51 | |
52 PretenureFlag pretenure() const { return pretenure_; } | |
53 Node* size() const { return size_; } | |
54 | |
55 private: | |
56 ZoneSet<NodeId> node_ids_; | |
57 PretenureFlag const pretenure_; | |
58 Node* const size_; | |
59 | |
60 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationGroup); | |
61 }; | |
62 | |
63 // An allocation state is propagated on the effect paths through the graph. | |
64 class AllocationState final : public ZoneObject { | |
65 public: | |
66 AllocationState(); | |
67 explicit AllocationState(AllocationGroup* group); | |
68 AllocationState(AllocationGroup* group, int size, Node* top); | |
69 | |
70 bool IsNewSpaceAllocation() const; | |
71 | |
72 AllocationGroup* group() const { return group_; } | |
73 Node* top() const { return top_; } | |
74 int size() const { return size_; } | |
75 | |
76 private: | |
77 AllocationGroup* const group_; | |
78 // The upper bound of the combined allocated object size on the current path | |
79 // (max int if allocation folding is impossible on this path). | |
80 int const size_; | |
81 Node* const top_; | |
82 | |
83 DISALLOW_COPY_AND_ASSIGN(AllocationState); | |
84 }; | |
85 | |
86 // An array of allocation states used to collect states on merges. | |
87 typedef ZoneVector<AllocationState const*> AllocationStates; | |
88 | |
89 // We thread through tokens to represent the current state on a given effect | |
90 // path through the graph. | |
91 struct Token { | |
92 Node* node; | |
93 AllocationState const* state; | |
94 }; | |
95 | |
96 void VisitNode(Node*, AllocationState const*); | |
97 void VisitAllocate(Node*, AllocationState const*); | |
98 void VisitCall(Node*, AllocationState const*); | |
99 void VisitLoadElement(Node*, AllocationState const*); | |
100 void VisitLoadField(Node*, AllocationState const*); | |
101 void VisitStoreElement(Node*, AllocationState const*); | |
102 void VisitStoreField(Node*, AllocationState const*); | |
103 void VisitOtherEffect(Node*, AllocationState const*); | |
104 | |
105 Node* ComputeIndex(ElementAccess const&, Node*); | |
106 WriteBarrierKind ComputeWriteBarrierKind(Node* object, | |
107 AllocationState const* state, | |
108 WriteBarrierKind); | |
109 | |
110 AllocationState const* MergeStates(AllocationStates const& states); | |
111 | |
112 void EnqueueMerge(Node*, int, AllocationState const*); | |
113 void EnqueueUses(Node*, AllocationState const*); | |
114 void EnqueueUse(Node*, int, AllocationState const*); | |
115 | |
116 AllocationState const* empty_state() const { return empty_state_; } | |
117 Graph* graph() const; | |
118 Isolate* isolate() const; | |
119 JSGraph* jsgraph() const { return jsgraph_; } | |
120 CommonOperatorBuilder* common() const; | |
121 MachineOperatorBuilder* machine() const; | |
122 Zone* zone() const { return zone_; } | |
123 | |
124 SetOncePointer<const Operator> allocate_operator_; | |
125 JSGraph* const jsgraph_; | |
126 AllocationState const* const empty_state_; | |
127 ZoneMap<NodeId, AllocationStates> pending_; | |
128 ZoneQueue<Token> tokens_; | |
129 Zone* const zone_; | |
130 | |
131 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer); | |
132 }; | |
133 | |
134 } // namespace compiler | |
135 } // namespace internal | |
136 } // namespace v8 | |
137 | |
138 #endif // V8_COMPILER_MEMORY_OPTIMIZER_H_ | |
OLD | NEW |