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 12namespace v8 { 13namespace internal { 14 15class TickCounter; 16 17namespace compiler { 18 19class JSGraph; 20class 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. 24using 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. 30class MemoryOptimizer final { 31 public: 32 MemoryOptimizer(JSGraph* jsgraph, Zone* zone, 33 MemoryLowering::AllocationFolding allocation_folding, 34 const char* function_debug_name, TickCounter* tick_counter); 35 ~MemoryOptimizer() = default; 36 37 void Optimize(); 38 39 private: 40 using AllocationState = MemoryLowering::AllocationState; 41 42 // An array of allocation states used to collect states on merges. 43 using AllocationStates = ZoneVector<AllocationState const*>; 44 45 // We thread through tokens to represent the current state on a given effect 46 // path through the graph. 47 struct Token { 48 Node* node; 49 AllocationState const* state; 50 }; 51 52 void VisitNode(Node*, AllocationState const*); 53 void VisitAllocateRaw(Node*, AllocationState const*); 54 void VisitCall(Node*, AllocationState const*); 55 void VisitLoadFromObject(Node*, AllocationState const*); 56 void VisitLoadElement(Node*, AllocationState const*); 57 void VisitLoadField(Node*, AllocationState const*); 58 void VisitStoreToObject(Node*, AllocationState const*); 59 void VisitStoreElement(Node*, AllocationState const*); 60 void VisitStoreField(Node*, AllocationState const*); 61 void VisitStore(Node*, AllocationState const*); 62 void VisitOtherEffect(Node*, AllocationState const*); 63 64 AllocationState const* MergeStates(AllocationStates const& states); 65 66 void EnqueueMerge(Node*, int, AllocationState const*); 67 void EnqueueUses(Node*, AllocationState const*); 68 void EnqueueUse(Node*, int, AllocationState const*); 69 70 void ReplaceUsesAndKillNode(Node* node, Node* replacement); 71 72 // Returns true if the AllocationType of the current AllocateRaw node that we 73 // are visiting needs to be updated to kOld, due to propagation of tenuring 74 // from outer to inner allocations. 75 bool AllocationTypeNeedsUpdateToOld(Node* const user, const Edge edge); 76 77 AllocationState const* empty_state() const { return empty_state_; } 78 MemoryLowering* memory_lowering() { return &memory_lowering_; } 79 Graph* graph() const; 80 JSGraph* jsgraph() const { return jsgraph_; } 81 Zone* zone() const { return zone_; } 82 83 JSGraphAssembler graph_assembler_; 84 MemoryLowering memory_lowering_; 85 JSGraph* jsgraph_; 86 AllocationState const* const empty_state_; 87 ZoneMap<NodeId, AllocationStates> pending_; 88 ZoneQueue<Token> tokens_; 89 Zone* const zone_; 90 TickCounter* const tick_counter_; 91 92 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer); 93}; 94 95} // namespace compiler 96} // namespace internal 97} // namespace v8 98 99#endif // V8_COMPILER_MEMORY_OPTIMIZER_H_ 100