Commit efd7c594 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[turbofan] Use AllocationBuilder helper class everywhere.

This makes all inline allocation constructions go through the existing
{AllocationBuilder} helper class. It hence ensures there is a single
place for all sanity checking and and makes use-sites easier to read.

R=jarin@chromium.org

Change-Id: Ib5daf48acd93c631fccdfa095eda1afda7048115
Reviewed-on: https://chromium-review.googlesource.com/709056
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48502}
parent debec016
......@@ -1317,6 +1317,7 @@ v8_source_set("v8_base") {
"src/compiler/access-info.h",
"src/compiler/all-nodes.cc",
"src/compiler/all-nodes.h",
"src/compiler/allocation-builder.h",
"src/compiler/basic-block-instrumentor.cc",
"src/compiler/basic-block-instrumentor.h",
"src/compiler/branch-elimination.cc",
......
// Copyright 2017 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_ALLOCATION_BUILDER_H_
#define V8_COMPILER_ALLOCATION_BUILDER_H_
#include "src/compiler/js-graph.h"
#include "src/compiler/node.h"
#include "src/compiler/simplified-operator.h"
namespace v8 {
namespace internal {
namespace compiler {
// A helper class to construct inline allocations on the simplified operator
// level. This keeps track of the effect chain for initial stores on a newly
// allocated object and also provides helpers for commonly allocated objects.
class AllocationBuilder final {
public:
AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control)
: jsgraph_(jsgraph),
allocation_(nullptr),
effect_(effect),
control_(control) {}
// Primitive allocation of static size.
void Allocate(int size, PretenureFlag pretenure = NOT_TENURED,
Type* type = Type::Any()) {
DCHECK_LE(size, kMaxRegularHeapObjectSize);
effect_ = graph()->NewNode(
common()->BeginRegion(RegionObservability::kNotObservable), effect_);
allocation_ =
graph()->NewNode(simplified()->Allocate(type, pretenure),
jsgraph()->Constant(size), effect_, control_);
effect_ = allocation_;
}
// Primitive store into a field.
void Store(const FieldAccess& access, Node* value) {
effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
value, effect_, control_);
}
// Primitive store into an element.
void Store(ElementAccess const& access, Node* index, Node* value) {
effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_,
index, value, effect_, control_);
}
// Compound allocation of a FixedArray.
void AllocateArray(int length, Handle<Map> map,
PretenureFlag pretenure = NOT_TENURED) {
DCHECK(map->instance_type() == FIXED_ARRAY_TYPE ||
map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE);
int size = (map->instance_type() == FIXED_ARRAY_TYPE)
? FixedArray::SizeFor(length)
: FixedDoubleArray::SizeFor(length);
Allocate(size, pretenure, Type::OtherInternal());
Store(AccessBuilder::ForMap(), map);
Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
}
// Compound store of a constant into a field.
void Store(const FieldAccess& access, Handle<Object> value) {
Store(access, jsgraph()->Constant(value));
}
void FinishAndChange(Node* node) {
NodeProperties::SetType(allocation_, NodeProperties::GetType(node));
node->ReplaceInput(0, allocation_);
node->ReplaceInput(1, effect_);
node->TrimInputCount(2);
NodeProperties::ChangeOp(node, common()->FinishRegion());
}
Node* Finish() {
return graph()->NewNode(common()->FinishRegion(), allocation_, effect_);
}
protected:
JSGraph* jsgraph() { return jsgraph_; }
Graph* graph() { return jsgraph_->graph(); }
CommonOperatorBuilder* common() { return jsgraph_->common(); }
SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); }
private:
JSGraph* const jsgraph_;
Node* allocation_;
Node* effect_;
Node* control_;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_ALLOCATION_BUILDER_H_
This diff is collapsed.
......@@ -8,6 +8,7 @@
#include "src/code-factory.h"
#include "src/compilation-dependencies.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/allocation-builder.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
......@@ -25,84 +26,6 @@ namespace compiler {
namespace {
// A helper class to construct inline allocations on the simplified operator
// level. This keeps track of the effect chain for initial stores on a newly
// allocated object and also provides helpers for commonly allocated objects.
class AllocationBuilder final {
public:
AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control)
: jsgraph_(jsgraph),
allocation_(nullptr),
effect_(effect),
control_(control) {}
// Primitive allocation of static size.
void Allocate(int size, PretenureFlag pretenure = NOT_TENURED,
Type* type = Type::Any()) {
DCHECK_LE(size, kMaxRegularHeapObjectSize);
effect_ = graph()->NewNode(
common()->BeginRegion(RegionObservability::kNotObservable), effect_);
allocation_ =
graph()->NewNode(simplified()->Allocate(type, pretenure),
jsgraph()->Constant(size), effect_, control_);
effect_ = allocation_;
}
// Primitive store into a field.
void Store(const FieldAccess& access, Node* value) {
effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
value, effect_, control_);
}
// Primitive store into an element.
void Store(ElementAccess const& access, Node* index, Node* value) {
effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_,
index, value, effect_, control_);
}
// Compound allocation of a FixedArray.
void AllocateArray(int length, Handle<Map> map,
PretenureFlag pretenure = NOT_TENURED) {
DCHECK(map->instance_type() == FIXED_ARRAY_TYPE ||
map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE);
int size = (map->instance_type() == FIXED_ARRAY_TYPE)
? FixedArray::SizeFor(length)
: FixedDoubleArray::SizeFor(length);
Allocate(size, pretenure, Type::OtherInternal());
Store(AccessBuilder::ForMap(), map);
Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
}
// Compound store of a constant into a field.
void Store(const FieldAccess& access, Handle<Object> value) {
Store(access, jsgraph()->Constant(value));
}
void FinishAndChange(Node* node) {
NodeProperties::SetType(allocation_, NodeProperties::GetType(node));
node->ReplaceInput(0, allocation_);
node->ReplaceInput(1, effect_);
node->TrimInputCount(2);
NodeProperties::ChangeOp(node, common()->FinishRegion());
}
Node* Finish() {
return graph()->NewNode(common()->FinishRegion(), allocation_, effect_);
}
protected:
JSGraph* jsgraph() { return jsgraph_; }
Graph* graph() { return jsgraph_->graph(); }
CommonOperatorBuilder* common() { return jsgraph_->common(); }
SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); }
private:
JSGraph* const jsgraph_;
Node* allocation_;
Node* effect_;
Node* control_;
};
// Retrieves the frame state holding actual argument values.
Node* GetArgumentsFrameState(Node* frame_state) {
Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state);
......
......@@ -10,6 +10,7 @@
#include "src/compilation-dependencies.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/access-info.h"
#include "src/compiler/allocation-builder.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/linkage.h"
......@@ -1820,21 +1821,12 @@ JSNativeContextSpecialization::BuildPropertyStore(
!FLAG_unbox_double_fields) {
if (access_info.HasTransitionMap()) {
// Allocate a MutableHeapNumber for the new property.
effect = graph()->NewNode(
common()->BeginRegion(RegionObservability::kNotObservable),
effect);
Node* box = effect = graph()->NewNode(
simplified()->Allocate(Type::OtherInternal(), NOT_TENURED),
jsgraph()->Constant(HeapNumber::kSize), effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForMap()), box,
jsgraph()->HeapConstant(factory()->mutable_heap_number_map()),
effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForHeapNumberValue()),
box, value, effect, control);
value = effect =
graph()->NewNode(common()->FinishRegion(), box, effect);
AllocationBuilder a(jsgraph(), effect, control);
a.Allocate(HeapNumber::kSize, NOT_TENURED, Type::OtherInternal());
a.Store(AccessBuilder::ForMap(),
factory()->mutable_heap_number_map());
a.Store(AccessBuilder::ForHeapNumberValue(), value);
value = effect = a.Finish();
field_access.type = Type::Any();
field_access.machine_type = MachineType::TaggedPointer();
......@@ -2427,11 +2419,9 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore(
values.push_back(jsgraph()->UndefinedConstant());
}
// Allocate and initialize the new properties.
// Compute new length and hash.
Node* hash;
if (length == 0) {
effect = graph()->NewNode(
common()->BeginRegion(RegionObservability::kNotObservable), effect);
hash = graph()->NewNode(
common()->Select(MachineRepresentation::kTaggedSigned),
graph()->NewNode(simplified()->ObjectIsSmi(), properties), properties,
......@@ -2445,30 +2435,23 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore(
hash = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForPropertyArrayLengthAndHash()),
properties, effect, control);
effect = graph()->NewNode(
common()->BeginRegion(RegionObservability::kNotObservable), effect);
hash =
graph()->NewNode(simplified()->NumberBitwiseAnd(), hash,
jsgraph()->Constant(PropertyArray::HashField::kMask));
}
Node* new_length_and_hash = graph()->NewNode(
simplified()->NumberBitwiseOr(), jsgraph()->Constant(new_length), hash);
Node* new_properties = effect = graph()->NewNode(
simplified()->Allocate(Type::OtherInternal(), NOT_TENURED),
jsgraph()->Constant(PropertyArray::SizeFor(new_length)), effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForMap()), new_properties,
jsgraph()->PropertyArrayMapConstant(), effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForPropertyArrayLengthAndHash()),
new_properties, new_length_and_hash, effect, control);
// Allocate and initialize the new properties.
AllocationBuilder a(jsgraph(), effect, control);
a.Allocate(PropertyArray::SizeFor(new_length), NOT_TENURED,
Type::OtherInternal());
a.Store(AccessBuilder::ForMap(), jsgraph()->PropertyArrayMapConstant());
a.Store(AccessBuilder::ForPropertyArrayLengthAndHash(), new_length_and_hash);
for (int i = 0; i < new_length; ++i) {
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)),
new_properties, values[i], effect, control);
a.Store(AccessBuilder::ForFixedArraySlot(i), values[i]);
}
return graph()->NewNode(common()->FinishRegion(), new_properties, effect);
return a.Finish();
}
bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
......
......@@ -8,6 +8,7 @@
#include "src/builtins/builtins-utils.h"
#include "src/code-factory.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/allocation-builder.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
......@@ -646,33 +647,18 @@ Reduction JSTypedLowering::ReduceCreateConsString(Node* node) {
Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map());
// Allocate the resulting ConsString.
effect = graph()->NewNode(
common()->BeginRegion(RegionObservability::kNotObservable), effect);
Node* value = effect =
graph()->NewNode(simplified()->Allocate(Type::OtherString(), NOT_TENURED),
jsgraph()->Constant(ConsString::kSize), effect, control);
effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
value, value_map, effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForNameHashField()), value,
jsgraph()->Constant(Name::kEmptyHashField), effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForStringLength()), value, length,
effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForConsStringFirst()), value,
first, effect, control);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForConsStringSecond()), value,
second, effect, control);
AllocationBuilder a(jsgraph(), effect, control);
a.Allocate(ConsString::kSize, NOT_TENURED, Type::OtherString());
a.Store(AccessBuilder::ForMap(), value_map);
a.Store(AccessBuilder::ForNameHashField(),
jsgraph()->Constant(Name::kEmptyHashField));
a.Store(AccessBuilder::ForStringLength(), length);
a.Store(AccessBuilder::ForConsStringFirst(), first);
a.Store(AccessBuilder::ForConsStringSecond(), second);
// Morph the {node} into a {FinishRegion}.
ReplaceWithValue(node, node, node, control);
NodeProperties::SetType(value, NodeProperties::GetType(node));
node->ReplaceInput(0, value);
node->ReplaceInput(1, effect);
node->TrimInputCount(2);
NodeProperties::ChangeOp(node, common()->FinishRegion());
a.FinishAndChange(node);
return Changed(node);
}
......
......@@ -688,6 +688,7 @@
'compiler/access-info.h',
'compiler/all-nodes.cc',
'compiler/all-nodes.h',
'compiler/allocation-builder.h',
'compiler/basic-block-instrumentor.cc',
'compiler/basic-block-instrumentor.h',
'compiler/branch-elimination.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment