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 12 namespace v8 { 13 namespace internal { 14 namespace 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. 19 class AllocationBuilder final { 20 public: AllocationBuilder(JSGraph * jsgraph,Node * effect,Node * control)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, PretenureFlag pretenure = NOT_TENURED, 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, pretenure), 35 jsgraph()->Constant(size), effect_, control_); 36 effect_ = allocation_; 37 } 38 39 // Primitive store into a field. Store(const FieldAccess & access,Node * value)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. Store(ElementAccess const & access,Node * index,Node * value)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. AllocateContext(int length,Handle<Map> map)52 void AllocateContext(int length, Handle<Map> map) { 53 DCHECK(map->instance_type() >= BLOCK_CONTEXT_TYPE && 54 map->instance_type() <= WITH_CONTEXT_TYPE); 55 int size = FixedArray::SizeFor(length); 56 Allocate(size, NOT_TENURED, Type::OtherInternal()); 57 Store(AccessBuilder::ForMap(), map); 58 Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); 59 } 60 61 // Compound allocation of a FixedArray. 62 void AllocateArray(int length, Handle<Map> map, 63 PretenureFlag pretenure = NOT_TENURED) { 64 DCHECK(map->instance_type() == FIXED_ARRAY_TYPE || 65 map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE); 66 int size = (map->instance_type() == FIXED_ARRAY_TYPE) 67 ? FixedArray::SizeFor(length) 68 : FixedDoubleArray::SizeFor(length); 69 Allocate(size, pretenure, Type::OtherInternal()); 70 Store(AccessBuilder::ForMap(), map); 71 Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); 72 } 73 74 // Compound store of a constant into a field. Store(const FieldAccess & access,Handle<Object> value)75 void Store(const FieldAccess& access, Handle<Object> value) { 76 Store(access, jsgraph()->Constant(value)); 77 } 78 // Compound store of a constant into a field. Store(const FieldAccess & access,const ObjectRef & value)79 void Store(const FieldAccess& access, const ObjectRef& value) { 80 Store(access, jsgraph()->Constant(value)); 81 } 82 FinishAndChange(Node * node)83 void FinishAndChange(Node* node) { 84 NodeProperties::SetType(allocation_, NodeProperties::GetType(node)); 85 node->ReplaceInput(0, allocation_); 86 node->ReplaceInput(1, effect_); 87 node->TrimInputCount(2); 88 NodeProperties::ChangeOp(node, common()->FinishRegion()); 89 } 90 Finish()91 Node* Finish() { 92 return graph()->NewNode(common()->FinishRegion(), allocation_, effect_); 93 } 94 95 protected: jsgraph()96 JSGraph* jsgraph() { return jsgraph_; } isolate()97 Isolate* isolate() const { return jsgraph_->isolate(); } graph()98 Graph* graph() { return jsgraph_->graph(); } common()99 CommonOperatorBuilder* common() { return jsgraph_->common(); } simplified()100 SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); } 101 102 private: 103 JSGraph* const jsgraph_; 104 Node* allocation_; 105 Node* effect_; 106 Node* control_; 107 }; 108 109 } // namespace compiler 110 } // namespace internal 111 } // namespace v8 112 113 #endif // V8_COMPILER_ALLOCATION_BUILDER_H_ 114