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

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

Issue 2719023002: [turbofan] Inline Array.isArray in JSBuiltinReducer. (Closed)
Patch Set: Created 3 years, 10 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 a9af93c80ce9cb6e661d72ab5ff189ca6aa49884..e3bafadaef0ef1304680fa9553d4617000e3a57c 100644
--- a/src/compiler/js-builtin-reducer.cc
+++ b/src/compiler/js-builtin-reducer.cc
@@ -725,6 +725,104 @@ Reduction JSBuiltinReducer::ReduceArrayIteratorNext(Node* node) {
return NoChange();
}
+// ES6 section 22.1.2.2 Array.isArray ( arg )
+Reduction JSBuiltinReducer::ReduceArrayIsArray(Node* node) {
+ // We certainly know that undefined is not an array.
+ if (node->op()->ValueInputCount() < 3) {
+ Node* value = jsgraph()->FalseConstant();
+ ReplaceWithValue(node, value);
+ return Replace(value);
+ }
+ Node* value = NodeProperties::GetValueInput(node, 2);
+ Node* context = NodeProperties::GetContextInput(node);
+ Node* frame_state = NodeProperties::GetFrameStateInput(node);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ Node* control = NodeProperties::GetControlInput(node);
+
+ int count = 0;
+ Node* values[5];
+ Node* effects[5];
+ Node* controls[4];
+
+ // Check if the {value} is a Smi.
+ Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+ control =
+ graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+ // The {value} is a Smi.
+ controls[count] = graph()->NewNode(common()->IfTrue(), control);
+ effects[count] = effect;
+ values[count] = jsgraph()->FalseConstant();
+ count++;
+
+ control = graph()->NewNode(common()->IfFalse(), control);
+
+ // Load the {value}s instance type.
+ Node* value_map = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
+ Node* value_instance_type = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
+ effect, control);
+
+ // Check if the {value} is a JSArray.
+ check = graph()->NewNode(simplified()->NumberEqual(), value_instance_type,
+ jsgraph()->Constant(JS_ARRAY_TYPE));
+ control = graph()->NewNode(common()->Branch(), check, control);
+
+ // The {value} is a JSArray.
+ controls[count] = graph()->NewNode(common()->IfTrue(), control);
+ effects[count] = effect;
+ values[count] = jsgraph()->TrueConstant();
+ count++;
+
+ control = graph()->NewNode(common()->IfFalse(), control);
+
+ // Check if the {value} is a JSProxy.
+ check = graph()->NewNode(simplified()->NumberEqual(), value_instance_type,
+ jsgraph()->Constant(JS_PROXY_TYPE));
+ control =
+ graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+ // The {value} is neither a JSArray nor a JSProxy.
+ controls[count] = graph()->NewNode(common()->IfFalse(), control);
+ effects[count] = effect;
+ values[count] = jsgraph()->FalseConstant();
+ count++;
+
+ control = graph()->NewNode(common()->IfTrue(), control);
+
+ // Let the %ArrayIsArray runtime function deal with the JSProxy {value}.
+ value = effect =
+ graph()->NewNode(javascript()->CallRuntime(Runtime::kArrayIsArray), value,
+ context, frame_state, effect, control);
+ NodeProperties::SetType(value, Type::Boolean());
+ control = graph()->NewNode(common()->IfSuccess(), value);
+
+ // Rewire any IfException edges on {node} to {value}.
+ for (Edge edge : node->use_edges()) {
+ Node* const user = edge.from();
+ if (user->opcode() == IrOpcode::kIfException) {
+ edge.UpdateTo(value);
+ Revisit(user);
+ }
+ }
+
+ // The {value} is neither a JSArray nor a JSProxy.
+ controls[count] = control;
+ effects[count] = effect;
+ values[count] = value;
+ count++;
+
+ control = graph()->NewNode(common()->Merge(count), count, controls);
+ effects[count] = control;
+ values[count] = control;
+ effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
+ value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, count),
+ count + 1, values);
+ ReplaceWithValue(node, value, effect, control);
+ return Replace(value);
+}
+
// ES6 section 22.1.3.17 Array.prototype.pop ( )
Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) {
Handle<Map> receiver_map;
@@ -1969,6 +2067,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
return ReduceArrayIterator(node, IterationKind::kValues);
case kArrayIteratorNext:
return ReduceArrayIteratorNext(node);
+ case kArrayIsArray:
+ return ReduceArrayIsArray(node);
case kArrayPop:
return ReduceArrayPop(node);
case kArrayPush:
« 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