Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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/zone-containers.h" | |
| 9 | |
| 10 namespace v8 { | |
| 11 namespace internal { | |
| 12 namespace compiler { | |
| 13 | |
| 14 // Forward declarations. | |
| 15 class CommonOperatorBuilder; | |
| 16 struct ElementAccess; | |
| 17 class Graph; | |
| 18 class JSGraph; | |
| 19 class MachineOperatorBuilder; | |
| 20 class Node; | |
| 21 class Operator; | |
| 22 | |
| 23 // NodeIds are identifying numbers for nodes that can be used to index auxiliary | |
| 24 // out-of-line data associated with each node. | |
| 25 typedef uint32_t NodeId; | |
| 26 | |
| 27 // Lowers all simplified memory access and allocation related nodes (i.e. | |
| 28 // Allocate, LoadField, StoreField and friends) to machine operators. | |
| 29 // Performs allocation folding and store write barrier elimination | |
| 30 // implicitly. | |
| 31 class MemoryOptimizer final { | |
| 32 public: | |
| 33 MemoryOptimizer(JSGraph* jsgraph, Zone* zone); | |
| 34 ~MemoryOptimizer() {} | |
| 35 | |
| 36 void Optimize(); | |
|
Jarin
2016/05/10 09:24:49
Don't we normally call these methods 'Run'?
Benedikt Meurer
2016/05/10 09:34:04
Followed the pattern of ControlFlowOptimizer here.
| |
| 37 | |
| 38 private: | |
| 39 // An allocation group represents a set of allocations that have been folded | |
| 40 // together. | |
| 41 class AllocationGroup final : public ZoneObject { | |
| 42 public: | |
| 43 AllocationGroup(Node* node, PretenureFlag pretenure, Zone* zone); | |
| 44 AllocationGroup(Node* node, PretenureFlag pretenure, Node* size, | |
| 45 Zone* zone); | |
| 46 ~AllocationGroup() {} | |
| 47 | |
| 48 void Add(Node* object); | |
| 49 bool Contains(Node* object) const; | |
| 50 bool IsNewSpaceAllocation() const { return pretenure() == NOT_TENURED; } | |
| 51 | |
| 52 PretenureFlag pretenure() const { return pretenure_; } | |
| 53 Node* size() const { return size_; } | |
| 54 | |
| 55 private: | |
| 56 ZoneSet<NodeId> node_ids_; | |
| 57 PretenureFlag const pretenure_; | |
| 58 Node* const size_; | |
| 59 | |
| 60 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationGroup); | |
| 61 }; | |
| 62 | |
| 63 // An allocation state is propagated on the effect paths through the graph. | |
| 64 class AllocationState final : public ZoneObject { | |
| 65 public: | |
| 66 AllocationState(); | |
| 67 explicit AllocationState(AllocationGroup* group); | |
| 68 AllocationState(AllocationGroup* group, int size, Node* top); | |
| 69 | |
| 70 bool IsNewSpaceAllocation() const; | |
| 71 | |
| 72 AllocationGroup* group() const { return group_; } | |
| 73 Node* top() const { return top_; } | |
| 74 int size() const { return size_; } | |
| 75 | |
| 76 private: | |
| 77 AllocationGroup* const group_; | |
| 78 // The upper bound of the combined allocated object size on the current path | |
| 79 // (max int if allocation folding is impossible on this path). | |
| 80 int const size_; | |
| 81 Node* const top_; | |
| 82 | |
| 83 DISALLOW_COPY_AND_ASSIGN(AllocationState); | |
| 84 }; | |
| 85 | |
| 86 // An array of allocation states used to collect states on merges. | |
| 87 typedef ZoneVector<AllocationState const*> AllocationStates; | |
| 88 | |
| 89 // We thread through tokens to represent the current state on a given effect | |
| 90 // path through the graph. | |
| 91 struct Token { | |
| 92 Node* node; | |
| 93 AllocationState const* state; | |
| 94 }; | |
| 95 | |
| 96 void VisitNode(Node*, AllocationState const*); | |
| 97 void VisitAllocate(Node*, AllocationState const*); | |
| 98 void VisitCall(Node*, AllocationState const*); | |
| 99 void VisitLoadElement(Node*, AllocationState const*); | |
| 100 void VisitLoadField(Node*, AllocationState const*); | |
| 101 void VisitStoreElement(Node*, AllocationState const*); | |
| 102 void VisitStoreField(Node*, AllocationState const*); | |
| 103 void VisitOtherEffect(Node*, AllocationState const*); | |
| 104 | |
| 105 Node* ComputeIndex(ElementAccess const&, Node*); | |
| 106 WriteBarrierKind ComputeWriteBarrierKind(Node* object, | |
| 107 AllocationState const* state, | |
| 108 WriteBarrierKind); | |
| 109 | |
| 110 AllocationState const* MergeStates(AllocationStates const& states); | |
| 111 | |
| 112 void EnqueueMerge(Node*, int, AllocationState const*); | |
| 113 void EnqueueUses(Node*, AllocationState const*); | |
| 114 void EnqueueUse(Node*, int, AllocationState const*); | |
| 115 | |
| 116 AllocationState const* empty_state() const { return empty_state_; } | |
| 117 Graph* graph() const; | |
| 118 Isolate* isolate() const; | |
| 119 JSGraph* jsgraph() const { return jsgraph_; } | |
| 120 CommonOperatorBuilder* common() const; | |
| 121 MachineOperatorBuilder* machine() const; | |
| 122 Zone* zone() const { return zone_; } | |
| 123 | |
| 124 SetOncePointer<const Operator> allocate_operator_; | |
| 125 JSGraph* const jsgraph_; | |
| 126 AllocationState const* const empty_state_; | |
| 127 ZoneMap<NodeId, AllocationStates> pending_; | |
| 128 ZoneQueue<Token> tokens_; | |
| 129 Zone* const zone_; | |
| 130 | |
| 131 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer); | |
| 132 }; | |
| 133 | |
| 134 } // namespace compiler | |
| 135 } // namespace internal | |
| 136 } // namespace v8 | |
| 137 | |
| 138 #endif // V8_COMPILER_MEMORY_OPTIMIZER_H_ | |
| OLD | NEW |