• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/compiler/memory-lowering.h"
10 #include "src/zone/zone-containers.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 class TickCounter;
16 
17 namespace compiler {
18 
19 class JSGraph;
20 class Graph;
21 
22 // NodeIds are identifying numbers for nodes that can be used to index auxiliary
23 // out-of-line data associated with each node.
24 using NodeId = uint32_t;
25 
26 // Performs allocation folding and store write barrier elimination
27 // implicitly, while lowering all simplified memory access and allocation
28 // related nodes (i.e. Allocate, LoadField, StoreField and friends) to machine
29 // operators.
30 class MemoryOptimizer final {
31  public:
32   MemoryOptimizer(JSGraph* jsgraph, Zone* zone,
33                   PoisoningMitigationLevel poisoning_level,
34                   MemoryLowering::AllocationFolding allocation_folding,
35                   const char* function_debug_name, TickCounter* tick_counter);
36   ~MemoryOptimizer() = default;
37 
38   void Optimize();
39 
40  private:
41   using AllocationState = MemoryLowering::AllocationState;
42 
43   // An array of allocation states used to collect states on merges.
44   using AllocationStates = ZoneVector<AllocationState const*>;
45 
46   // We thread through tokens to represent the current state on a given effect
47   // path through the graph.
48   struct Token {
49     Node* node;
50     AllocationState const* state;
51   };
52 
53   void VisitNode(Node*, AllocationState const*);
54   void VisitAllocateRaw(Node*, AllocationState const*);
55   void VisitCall(Node*, AllocationState const*);
56   void VisitLoadFromObject(Node*, AllocationState const*);
57   void VisitLoadElement(Node*, AllocationState const*);
58   void VisitLoadField(Node*, AllocationState const*);
59   void VisitStoreToObject(Node*, AllocationState const*);
60   void VisitStoreElement(Node*, AllocationState const*);
61   void VisitStoreField(Node*, AllocationState const*);
62   void VisitStore(Node*, AllocationState const*);
63   void VisitOtherEffect(Node*, AllocationState const*);
64 
65   AllocationState const* MergeStates(AllocationStates const& states);
66 
67   void EnqueueMerge(Node*, int, AllocationState const*);
68   void EnqueueUses(Node*, AllocationState const*);
69   void EnqueueUse(Node*, int, AllocationState const*);
70 
71   // Returns true if the AllocationType of the current AllocateRaw node that we
72   // are visiting needs to be updated to kOld, due to propagation of tenuring
73   // from outer to inner allocations.
74   bool AllocationTypeNeedsUpdateToOld(Node* const user, const Edge edge);
75 
empty_state()76   AllocationState const* empty_state() const { return empty_state_; }
memory_lowering()77   MemoryLowering* memory_lowering() { return &memory_lowering_; }
78   Graph* graph() const;
jsgraph()79   JSGraph* jsgraph() const { return jsgraph_; }
zone()80   Zone* zone() const { return zone_; }
81 
82   JSGraphAssembler graph_assembler_;
83   MemoryLowering memory_lowering_;
84   JSGraph* jsgraph_;
85   AllocationState const* const empty_state_;
86   ZoneMap<NodeId, AllocationStates> pending_;
87   ZoneQueue<Token> tokens_;
88   Zone* const zone_;
89   TickCounter* const tick_counter_;
90 
91   DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer);
92 };
93 
94 }  // namespace compiler
95 }  // namespace internal
96 }  // namespace v8
97 
98 #endif  // V8_COMPILER_MEMORY_OPTIMIZER_H_
99