Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/compiler/memory-optimizer.h b/src/compiler/memory-optimizer.h
new file mode 100644
index 0000000..f0cd546
--- /dev/null
+++ b/src/compiler/memory-optimizer.h
@@ -0,0 +1,149 @@
+// 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/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+struct ElementAccess;
+class Graph;
+class JSGraph;
+class MachineOperatorBuilder;
+class Node;
+class Operator;
+
+// NodeIds are identifying numbers for nodes that can be used to index auxiliary
+// out-of-line data associated with each node.
+typedef uint32_t NodeId;
+
+// Lowers all simplified memory access and allocation related nodes (i.e.
+// Allocate, LoadField, StoreField and friends) to machine operators.
+// Performs allocation folding and store write barrier elimination
+// implicitly.
+class MemoryOptimizer final {
+ public:
+ MemoryOptimizer(JSGraph* jsgraph, Zone* zone);
+ ~MemoryOptimizer() {}
+
+ void Optimize();
+
+ private:
+ // An allocation group represents a set of allocations that have been folded
+ // together.
+ class AllocationGroup final : public ZoneObject {
+ public:
+ AllocationGroup(Node* node, PretenureFlag pretenure, Zone* zone);
+ AllocationGroup(Node* node, PretenureFlag pretenure, Node* size,
+ Zone* zone);
+ ~AllocationGroup() {}
+
+ void Add(Node* object);
+ bool Contains(Node* object) const;
+ bool IsNewSpaceAllocation() const { return pretenure() == NOT_TENURED; }
+
+ PretenureFlag pretenure() const { return pretenure_; }
+ Node* size() const { return size_; }
+
+ private:
+ ZoneSet<NodeId> node_ids_;
+ PretenureFlag const pretenure_;
+ Node* const size_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationGroup);
+ };
+
+ // An allocation state is propagated on the effect paths through the graph.
+ class AllocationState final : public ZoneObject {
+ public:
+ static AllocationState const* Empty(Zone* zone) {
+ return new (zone) AllocationState();
+ }
+ static AllocationState const* Closed(AllocationGroup* group, Zone* zone) {
+ return new (zone) AllocationState(group);
+ }
+ static AllocationState const* Open(AllocationGroup* group, int size,
+ Node* top, Zone* zone) {
+ return new (zone) AllocationState(group, size, top);
+ }
+
+ bool IsNewSpaceAllocation() const;
+
+ AllocationGroup* group() const { return group_; }
+ Node* top() const { return top_; }
+ int size() const { return size_; }
+
+ private:
+ AllocationState();
+ explicit AllocationState(AllocationGroup* group);
+ AllocationState(AllocationGroup* group, int size, Node* top);
+
+ AllocationGroup* const group_;
+ // The upper bound of the combined allocated object size on the current path
+ // (max int if allocation folding is impossible on this path).
+ int const size_;
+ Node* const top_;
+
+ DISALLOW_COPY_AND_ASSIGN(AllocationState);
+ };
+
+ // An array of allocation states used to collect states on merges.
+ typedef ZoneVector<AllocationState const*> AllocationStates;
+
+ // 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 VisitAllocate(Node*, AllocationState const*);
+ void VisitCall(Node*, AllocationState const*);
+ void VisitLoadElement(Node*, AllocationState const*);
+ void VisitLoadField(Node*, AllocationState const*);
+ void VisitStoreElement(Node*, AllocationState const*);
+ void VisitStoreField(Node*, AllocationState const*);
+ void VisitOtherEffect(Node*, AllocationState const*);
+
+ Node* ComputeIndex(ElementAccess const&, Node*);
+ WriteBarrierKind ComputeWriteBarrierKind(Node* object,
+ AllocationState const* state,
+ WriteBarrierKind);
+
+ AllocationState const* MergeStates(AllocationStates const& states);
+
+ void EnqueueMerge(Node*, int, AllocationState const*);
+ void EnqueueUses(Node*, AllocationState const*);
+ void EnqueueUse(Node*, int, AllocationState const*);
+
+ AllocationState const* empty_state() const { return empty_state_; }
+ Graph* graph() const;
+ Isolate* isolate() const;
+ JSGraph* jsgraph() const { return jsgraph_; }
+ CommonOperatorBuilder* common() const;
+ MachineOperatorBuilder* machine() const;
+ Zone* zone() const { return zone_; }
+
+ SetOncePointer<const Operator> allocate_operator_;
+ JSGraph* const jsgraph_;
+ AllocationState const* const empty_state_;
+ ZoneMap<NodeId, AllocationStates> pending_;
+ ZoneQueue<Token> tokens_;
+ Zone* const zone_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer);
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_COMPILER_MEMORY_OPTIMIZER_H_