Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Unified Diff: src/compiler/js-create-lowering.cc

Issue 2821273002: [turbofan] Inline Array constructor calls with multiple parameters. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/js-create-lowering.h ('k') | test/mjsunit/array-constructor-feedback.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-create-lowering.cc
diff --git a/src/compiler/js-create-lowering.cc b/src/compiler/js-create-lowering.cc
index 5869234ec35d8b0c817de1805878a4608cdf68df..6a726b9f645b0b33e471a0d9a3392fa7b6f6906d 100644
--- a/src/compiler/js-create-lowering.cc
+++ b/src/compiler/js-create-lowering.cc
@@ -594,6 +594,66 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
return Changed(node);
}
+Reduction JSCreateLowering::ReduceNewArray(Node* node,
+ std::vector<Node*> values,
+ Handle<AllocationSite> site) {
+ DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
+ Node* effect = NodeProperties::GetEffectInput(node);
+ Node* control = NodeProperties::GetControlInput(node);
+
+ // Extract transition and tenuring feedback from the {site} and add
+ // appropriate code dependencies on the {site} if deoptimization is
+ // enabled.
+ PretenureFlag pretenure = site->GetPretenureMode();
+ ElementsKind elements_kind = site->GetElementsKind();
+ DCHECK(IsFastElementsKind(elements_kind));
+ dependencies()->AssumeTenuringDecision(site);
+ dependencies()->AssumeTransitionStable(site);
+
+ // Check {values} based on the {elements_kind}. These checks are guarded
+ // by the {elements_kind} feedback on the {site}, so it's safe to just
+ // deoptimize in this case.
+ if (IsFastSmiElementsKind(elements_kind)) {
+ for (auto& value : values) {
+ if (!NodeProperties::GetType(value)->Is(Type::SignedSmall())) {
+ value = effect =
+ graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
+ }
+ }
+ } else if (IsFastDoubleElementsKind(elements_kind)) {
+ for (auto& value : values) {
+ if (!NodeProperties::GetType(value)->Is(Type::Number())) {
+ value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
+ effect, control);
+ }
+ // Make sure we do not store signaling NaNs into double arrays.
+ value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
+ }
+ }
+
+ // Retrieve the initial map for the array.
+ int const array_map_index = Context::ArrayMapIndex(elements_kind);
+ Node* js_array_map = jsgraph()->HeapConstant(
+ handle(Map::cast(native_context()->get(array_map_index)), isolate()));
+
+ // Setup elements, properties and length.
+ Node* elements = effect =
+ AllocateElements(effect, control, elements_kind, values, pretenure);
+ Node* properties = jsgraph()->EmptyFixedArrayConstant();
+ Node* length = jsgraph()->Constant(static_cast<int>(values.size()));
+
+ // Perform the allocation of the actual JSArray object.
+ AllocationBuilder a(jsgraph(), effect, control);
+ a.Allocate(JSArray::kSize, pretenure);
+ a.Store(AccessBuilder::ForMap(), js_array_map);
+ a.Store(AccessBuilder::ForJSObjectProperties(), properties);
+ a.Store(AccessBuilder::ForJSObjectElements(), elements);
+ a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
+ RelaxControls(node);
+ a.FinishAndChange(node);
+ return Changed(node);
+}
+
Reduction JSCreateLowering::ReduceNewArrayToStubCall(
Node* node, Handle<AllocationSite> site) {
CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
@@ -755,12 +815,25 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
} else if (p.arity() == 1) {
Node* length = NodeProperties::GetValueInput(node, 2);
Type* length_type = NodeProperties::GetType(length);
+ if (!length_type->Maybe(Type::Unsigned32())) {
+ // Handle the single argument case, where we know that the value
+ // cannot be a valid Array length.
+ return ReduceNewArray(node, {length}, site);
+ }
if (length_type->Is(Type::SignedSmall()) && length_type->Min() >= 0 &&
length_type->Max() <= kElementLoopUnrollLimit &&
length_type->Min() == length_type->Max()) {
int capacity = static_cast<int>(length_type->Max());
return ReduceNewArray(node, length, capacity, site);
}
+ } else if (p.arity() <= JSArray::kInitialMaxFastElementArray) {
+ std::vector<Node*> values;
+ values.reserve(p.arity());
+ for (size_t i = 0; i < p.arity(); ++i) {
+ values.push_back(
+ NodeProperties::GetValueInput(node, static_cast<int>(2 + i)));
+ }
+ return ReduceNewArray(node, values, site);
}
}
@@ -1125,6 +1198,31 @@ Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
return a.Finish();
}
+Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
+ ElementsKind elements_kind,
+ std::vector<Node*> const& values,
+ PretenureFlag pretenure) {
+ int const capacity = static_cast<int>(values.size());
+ DCHECK_LE(1, capacity);
+ DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
+
+ Handle<Map> elements_map = IsFastDoubleElementsKind(elements_kind)
+ ? factory()->fixed_double_array_map()
+ : factory()->fixed_array_map();
+ ElementAccess access = IsFastDoubleElementsKind(elements_kind)
+ ? AccessBuilder::ForFixedDoubleArrayElement()
+ : AccessBuilder::ForFixedArrayElement();
+
+ // Actually allocate the backing store.
+ AllocationBuilder a(jsgraph(), effect, control);
+ a.AllocateArray(capacity, elements_map, pretenure);
+ for (int i = 0; i < capacity; ++i) {
+ Node* index = jsgraph()->Constant(i);
+ a.Store(access, index, values[i]);
+ }
+ return a.Finish();
+}
+
Node* JSCreateLowering::AllocateFastLiteral(
Node* effect, Node* control, Handle<JSObject> boilerplate,
AllocationSiteUsageContext* site_context) {
« no previous file with comments | « src/compiler/js-create-lowering.h ('k') | test/mjsunit/array-constructor-feedback.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698