V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
memory-optimizer.h
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/compiler/graph-assembler.h"
9 #include "src/zone/zone-containers.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
15 // Forward declarations.
16 class CommonOperatorBuilder;
17 struct ElementAccess;
18 class Graph;
19 class JSGraph;
20 class MachineOperatorBuilder;
21 class Node;
22 class Operator;
23 
24 // NodeIds are identifying numbers for nodes that can be used to index auxiliary
25 // out-of-line data associated with each node.
26 typedef uint32_t NodeId;
27 
28 // Lowers all simplified memory access and allocation related nodes (i.e.
29 // Allocate, LoadField, StoreField and friends) to machine operators.
30 // Performs allocation folding and store write barrier elimination
31 // implicitly.
32 class MemoryOptimizer final {
33  public:
34  enum class AllocationFolding { kDoAllocationFolding, kDontAllocationFolding };
35 
36  MemoryOptimizer(JSGraph* jsgraph, Zone* zone,
37  PoisoningMitigationLevel poisoning_level,
38  AllocationFolding allocation_folding);
39  ~MemoryOptimizer() = default;
40 
41  void Optimize();
42 
43  private:
44  // An allocation group represents a set of allocations that have been folded
45  // together.
46  class AllocationGroup final : public ZoneObject {
47  public:
48  AllocationGroup(Node* node, PretenureFlag pretenure, Zone* zone);
49  AllocationGroup(Node* node, PretenureFlag pretenure, Node* size,
50  Zone* zone);
51  ~AllocationGroup() = default;
52 
53  void Add(Node* object);
54  bool Contains(Node* object) const;
55  bool IsNewSpaceAllocation() const { return pretenure() == NOT_TENURED; }
56 
57  PretenureFlag pretenure() const { return pretenure_; }
58  Node* size() const { return size_; }
59 
60  private:
61  ZoneSet<NodeId> node_ids_;
62  PretenureFlag const pretenure_;
63  Node* const size_;
64 
65  DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationGroup);
66  };
67 
68  // An allocation state is propagated on the effect paths through the graph.
69  class AllocationState final : public ZoneObject {
70  public:
71  static AllocationState const* Empty(Zone* zone) {
72  return new (zone) AllocationState();
73  }
74  static AllocationState const* Closed(AllocationGroup* group, Zone* zone) {
75  return new (zone) AllocationState(group);
76  }
77  static AllocationState const* Open(AllocationGroup* group, intptr_t size,
78  Node* top, Zone* zone) {
79  return new (zone) AllocationState(group, size, top);
80  }
81 
82  bool IsNewSpaceAllocation() const;
83 
84  AllocationGroup* group() const { return group_; }
85  Node* top() const { return top_; }
86  intptr_t size() const { return size_; }
87 
88  private:
89  AllocationState();
90  explicit AllocationState(AllocationGroup* group);
91  AllocationState(AllocationGroup* group, intptr_t size, Node* top);
92 
93  AllocationGroup* const group_;
94  // The upper bound of the combined allocated object size on the current path
95  // (max int if allocation folding is impossible on this path).
96  intptr_t const size_;
97  Node* const top_;
98 
99  DISALLOW_COPY_AND_ASSIGN(AllocationState);
100  };
101 
102  // An array of allocation states used to collect states on merges.
104 
105  // We thread through tokens to represent the current state on a given effect
106  // path through the graph.
107  struct Token {
108  Node* node;
109  AllocationState const* state;
110  };
111 
112  void VisitNode(Node*, AllocationState const*);
113  void VisitAllocateRaw(Node*, AllocationState const*);
114  void VisitCall(Node*, AllocationState const*);
115  void VisitCallWithCallerSavedRegisters(Node*, AllocationState const*);
116  void VisitLoadElement(Node*, AllocationState const*);
117  void VisitLoadField(Node*, AllocationState const*);
118  void VisitStoreElement(Node*, AllocationState const*);
119  void VisitStoreField(Node*, AllocationState const*);
120  void VisitOtherEffect(Node*, AllocationState const*);
121 
122  Node* ComputeIndex(ElementAccess const&, Node*);
123  WriteBarrierKind ComputeWriteBarrierKind(Node* object,
124  AllocationState const* state,
125  WriteBarrierKind);
126 
127  AllocationState const* MergeStates(AllocationStates const& states);
128 
129  void EnqueueMerge(Node*, int, AllocationState const*);
130  void EnqueueUses(Node*, AllocationState const*);
131  void EnqueueUse(Node*, int, AllocationState const*);
132 
133  bool NeedsPoisoning(LoadSensitivity load_sensitivity) const;
134 
135  AllocationState const* empty_state() const { return empty_state_; }
136  Graph* graph() const;
137  Isolate* isolate() const;
138  JSGraph* jsgraph() const { return jsgraph_; }
139  CommonOperatorBuilder* common() const;
140  MachineOperatorBuilder* machine() const;
141  Zone* zone() const { return zone_; }
142  GraphAssembler* gasm() { return &graph_assembler_; }
143 
144  SetOncePointer<const Operator> allocate_operator_;
145  JSGraph* const jsgraph_;
146  AllocationState const* const empty_state_;
148  ZoneQueue<Token> tokens_;
149  Zone* const zone_;
150  GraphAssembler graph_assembler_;
151  PoisoningMitigationLevel poisoning_level_;
152  AllocationFolding allocation_folding_;
153 
154  DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer);
155 };
156 
157 } // namespace compiler
158 } // namespace internal
159 } // namespace v8
160 
161 #endif // V8_COMPILER_MEMORY_OPTIMIZER_H_
Definition: libplatform.h:13