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