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

Unified Diff: src/compiler/js-builtin-reducer.cc

Issue 2245533003: [turbofan] Add inlined Array.prototype.push support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 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-builtin-reducer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-builtin-reducer.cc
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
index 94946a5279e9e6b8cc938239719886f70713871f..bbd5a92a7fd0400a6b82cbf2f747e747405a24cd 100644
--- a/src/compiler/js-builtin-reducer.cc
+++ b/src/compiler/js-builtin-reducer.cc
@@ -245,6 +245,75 @@ Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) {
return NoChange();
}
+// ES6 section 22.1.3.18 Array.prototype.push ( )
+Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) {
+ Handle<Map> receiver_map;
+ // We need exactly target, receiver and value parameters.
+ if (node->op()->ValueInputCount() != 3) return NoChange();
+ Node* receiver = NodeProperties::GetValueInput(node, 1);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ Node* control = NodeProperties::GetControlInput(node);
+ Node* value = NodeProperties::GetValueInput(node, 2);
+ if (GetMapWitness(node).ToHandle(&receiver_map) &&
+ CanInlineArrayResizeOperation(receiver_map)) {
+ // Install code dependencies on the {receiver} prototype maps and the
+ // global array protector cell.
+ dependencies()->AssumePropertyCell(factory()->array_protector());
+ dependencies()->AssumePrototypeMapsStable(receiver_map);
+
+ // TODO(turbofan): Perform type checks on the {value}. We are not guaranteed
+ // to learn from these checks in case they fail, as the witness (i.e. the
+ // map check from the LoadIC for a.push) might not be executed in baseline
+ // code (after we stored the value in the builtin and thereby changed the
+ // elements kind of a) before be decide to optimize this function again. We
+ // currently don't have a proper way to deal with this; the proper solution
+ // here is to learn on deopt, i.e. disable Array.prototype.push inlining
+ // for this function.
+ if (IsFastSmiElementsKind(receiver_map->elements_kind())) {
+ value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(),
+ value, effect, control);
+ } else if (IsFastDoubleElementsKind(receiver_map->elements_kind())) {
+ 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);
+ }
+
+ // Load the "length" property of the {receiver}.
+ Node* length = effect = graph()->NewNode(
+ simplified()->LoadField(
+ AccessBuilder::ForJSArrayLength(receiver_map->elements_kind())),
+ receiver, effect, control);
+
+ // Load the elements backing store of the {receiver}.
+ Node* elements = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver,
+ effect, control);
+
+ // TODO(turbofan): Check if we need to grow the {elements} backing store.
+ // This will deopt if we cannot grow the array further, and we currently
+ // don't necessarily learn from it. See the comment on the value type check
+ // above.
+ GrowFastElementsFlags flags = GrowFastElementsFlag::kArrayObject;
+ if (IsFastDoubleElementsKind(receiver_map->elements_kind())) {
+ flags |= GrowFastElementsFlag::kDoubleElements;
+ }
+ elements = effect =
+ graph()->NewNode(simplified()->MaybeGrowFastElements(flags), receiver,
+ elements, length, length, effect, control);
+
+ // Append the value to the {elements}.
+ effect = graph()->NewNode(
+ simplified()->StoreElement(
+ AccessBuilder::ForFixedArrayElement(receiver_map->elements_kind())),
+ elements, length, value, effect, control);
+
+ ReplaceWithValue(node, value, effect, control);
+ return Replace(value);
+ }
+ return NoChange();
+}
+
// ES6 section 20.2.2.1 Math.abs ( x )
Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) {
JSCallReduction r(node);
@@ -898,6 +967,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
switch (r.GetBuiltinFunctionId()) {
case kArrayPop:
return ReduceArrayPop(node);
+ case kArrayPush:
+ return ReduceArrayPush(node);
case kMathAbs:
reduction = ReduceMathAbs(node);
break;
« no previous file with comments | « src/compiler/js-builtin-reducer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698