1// Copyright 2017 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_ALLOCATION_BUILDER_H_
6#define V8_COMPILER_ALLOCATION_BUILDER_H_
7
8#include "src/compiler/js-graph.h"
9#include "src/compiler/node.h"
10#include "src/compiler/simplified-operator.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
16// A helper class to construct inline allocations on the simplified operator
17// level. This keeps track of the effect chain for initial stores on a newly
18// allocated object and also provides helpers for commonly allocated objects.
19class AllocationBuilder final {
20 public:
21 AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control)
22 : jsgraph_(jsgraph),
23 allocation_(nullptr),
24 effect_(effect),
25 control_(control) {}
26
27 // Primitive allocation of static size.
28 void Allocate(int size, AllocationType allocation = AllocationType::kYoung,
29 Type type = Type::Any()) {
30 DCHECK_LE(size, kMaxRegularHeapObjectSize);
31 effect_ = graph()->NewNode(
32 common()->BeginRegion(RegionObservability::kNotObservable), effect_);
33 allocation_ =
34 graph()->NewNode(simplified()->Allocate(type, allocation),
35 jsgraph()->Constant(size), effect_, control_);
36 effect_ = allocation_;
37 }
38
39 // Primitive store into a field.
40 void Store(const FieldAccess& access, Node* value) {
41 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
42 value, effect_, control_);
43 }
44
45 // Primitive store into an element.
46 void Store(ElementAccess const& access, Node* index, Node* value) {
47 effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_,
48 index, value, effect_, control_);
49 }
50
51 // Compound allocation of a context.
52 inline void AllocateContext(int variadic_part_length, Handle<Map> map);
53
54 // Compound allocation of a FixedArray.
55 inline void AllocateArray(int length, Handle<Map> map,
56 AllocationType allocation = AllocationType::kYoung);
57
58 // Compound store of a constant into a field.
59 void Store(const FieldAccess& access, Handle<Object> value) {
60 Store(access, jsgraph()->Constant(value));
61 }
62 // Compound store of a constant into a field.
63 void Store(const FieldAccess& access, const ObjectRef& value) {
64 Store(access, jsgraph()->Constant(value));
65 }
66
67 void FinishAndChange(Node* node) {
68 NodeProperties::SetType(allocation_, NodeProperties::GetType(node));
69 node->ReplaceInput(0, allocation_);
70 node->ReplaceInput(1, effect_);
71 node->TrimInputCount(2);
72 NodeProperties::ChangeOp(node, common()->FinishRegion());
73 }
74
75 Node* Finish() {
76 return graph()->NewNode(common()->FinishRegion(), allocation_, effect_);
77 }
78
79 protected:
80 JSGraph* jsgraph() { return jsgraph_; }
81 Isolate* isolate() const { return jsgraph_->isolate(); }
82 Graph* graph() { return jsgraph_->graph(); }
83 CommonOperatorBuilder* common() { return jsgraph_->common(); }
84 SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); }
85
86 private:
87 JSGraph* const jsgraph_;
88 Node* allocation_;
89 Node* effect_;
90 Node* control_;
91};
92
93} // namespace compiler
94} // namespace internal
95} // namespace v8
96
97#endif // V8_COMPILER_ALLOCATION_BUILDER_H_
98