| // Copyright 2016 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_COMPILER_MEMORY_OPTIMIZER_H_ |
| #define V8_COMPILER_MEMORY_OPTIMIZER_H_ |
| |
| #include "src/compiler/graph-assembler.h" |
| #include "src/compiler/memory-lowering.h" |
| #include "src/zone/zone-containers.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| class TickCounter; |
| |
| namespace compiler { |
| |
| class JSGraph; |
| class Graph; |
| |
| // NodeIds are identifying numbers for nodes that can be used to index auxiliary |
| // out-of-line data associated with each node. |
| using NodeId = uint32_t; |
| |
| // Performs allocation folding and store write barrier elimination |
| // implicitly, while lowering all simplified memory access and allocation |
| // related nodes (i.e. Allocate, LoadField, StoreField and friends) to machine |
| // operators. |
| class MemoryOptimizer final { |
| public: |
| MemoryOptimizer(JSGraph* jsgraph, Zone* zone, |
| PoisoningMitigationLevel poisoning_level, |
| MemoryLowering::AllocationFolding allocation_folding, |
| const char* function_debug_name, TickCounter* tick_counter); |
| ~MemoryOptimizer() = default; |
| |
| void Optimize(); |
| |
| private: |
| using AllocationState = MemoryLowering::AllocationState; |
| |
| // An array of allocation states used to collect states on merges. |
| using AllocationStates = ZoneVector<AllocationState const*>; |
| |
| // We thread through tokens to represent the current state on a given effect |
| // path through the graph. |
| struct Token { |
| Node* node; |
| AllocationState const* state; |
| }; |
| |
| void VisitNode(Node*, AllocationState const*); |
| void VisitAllocateRaw(Node*, AllocationState const*); |
| void VisitCall(Node*, AllocationState const*); |
| void VisitLoadFromObject(Node*, AllocationState const*); |
| void VisitLoadElement(Node*, AllocationState const*); |
| void VisitLoadField(Node*, AllocationState const*); |
| void VisitStoreToObject(Node*, AllocationState const*); |
| void VisitStoreElement(Node*, AllocationState const*); |
| void VisitStoreField(Node*, AllocationState const*); |
| void VisitStore(Node*, AllocationState const*); |
| void VisitOtherEffect(Node*, AllocationState const*); |
| |
| AllocationState const* MergeStates(AllocationStates const& states); |
| |
| void EnqueueMerge(Node*, int, AllocationState const*); |
| void EnqueueUses(Node*, AllocationState const*); |
| void EnqueueUse(Node*, int, AllocationState const*); |
| |
| // Returns true if the AllocationType of the current AllocateRaw node that we |
| // are visiting needs to be updated to kOld, due to propagation of tenuring |
| // from outer to inner allocations. |
| bool AllocationTypeNeedsUpdateToOld(Node* const user, const Edge edge); |
| |
| AllocationState const* empty_state() const { return empty_state_; } |
| MemoryLowering* memory_lowering() { return &memory_lowering_; } |
| Graph* graph() const; |
| JSGraph* jsgraph() const { return jsgraph_; } |
| Zone* zone() const { return zone_; } |
| |
| JSGraphAssembler graph_assembler_; |
| MemoryLowering memory_lowering_; |
| JSGraph* jsgraph_; |
| AllocationState const* const empty_state_; |
| ZoneMap<NodeId, AllocationStates> pending_; |
| ZoneQueue<Token> tokens_; |
| Zone* const zone_; |
| TickCounter* const tick_counter_; |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer); |
| }; |
| |
| } // namespace compiler |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_COMPILER_MEMORY_OPTIMIZER_H_ |