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

Unified Diff: src/compiler/js-native-context-specialization.cc

Issue 1425293004: [turbofan] Add support for named access to Number primitives. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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-native-context-specialization.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-native-context-specialization.cc
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index 82346b588b8b2ee8622da4e51a32f5bb9c250110..0fa6fe76118c3bd5aac2a184bc69fa59c3a6575e 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -354,10 +354,10 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
// Ensure that {receiver} is a heap object.
Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
- Node* branch =
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
- exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+ Node* branch = graph()->NewNode(common()->Branch(), check, control);
control = graph()->NewNode(common()->IfFalse(), branch);
+ Node* receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch);
+ Node* receiverissmi_effect = effect;
// Load the {receiver} map. The resulting effect is the dominating effect for
// all (polymorphic) branches.
@@ -388,8 +388,9 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
this_control = graph()->NewNode(common()->IfTrue(), branch);
} else {
- // Emit a (sequence of) map checks for other properties.
+ // Emit a (sequence of) map checks for other {receiver}s.
ZoneVector<Node*> this_controls(zone());
+ ZoneVector<Node*> this_effects(zone());
for (auto i = access_info.receiver_type()->Classes(); !i.Done();
i.Advance()) {
Handle<Map> map = i.Current();
@@ -398,15 +399,37 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
receiver_map, jsgraph()->Constant(map));
Node* branch =
graph()->NewNode(common()->Branch(), check, fallthrough_control);
- this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
+ this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+ this_effects.push_back(this_effect);
}
+
+ // The Number case requires special treatment to also deal with Smis.
+ if (receiver_type->Is(Type::Number())) {
+ // Join this check with the "receiver is smi" check above, and mark the
+ // "receiver is smi" check as "consumed" so that we don't deoptimize if
+ // the {receiver} is actually a Smi.
+ if (receiverissmi_control != nullptr) {
+ this_controls.push_back(receiverissmi_control);
+ this_effects.push_back(receiverissmi_effect);
+ receiverissmi_control = receiverissmi_effect = nullptr;
+ }
+ }
+
+ // Create dominating Merge+EffectPhi for this {receiver} type.
int const this_control_count = static_cast<int>(this_controls.size());
this_control =
(this_control_count == 1)
? this_controls.front()
: graph()->NewNode(common()->Merge(this_control_count),
this_control_count, &this_controls.front());
+ this_effects.push_back(this_control);
+ int const this_effect_count = static_cast<int>(this_effects.size());
+ this_effect =
+ (this_control_count == 1)
+ ? this_effects.front()
+ : graph()->NewNode(common()->EffectPhi(this_control_count),
+ this_effect_count, &this_effects.front());
}
// Determine actual holder and perform prototype chain checks.
@@ -584,17 +607,19 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
// Collect the fallthrough control as final "exit" control.
if (fallthrough_control != control) {
// Mark the last fallthrough branch as deferred.
- Node* branch = NodeProperties::GetControlInput(fallthrough_control);
- DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
- if (fallthrough_control->opcode() == IrOpcode::kIfTrue) {
- NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kFalse));
- } else {
- DCHECK_EQ(IrOpcode::kIfFalse, fallthrough_control->opcode());
- NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kTrue));
- }
+ MarkAsDeferred(fallthrough_control);
}
exit_controls.push_back(fallthrough_control);
+ // Also collect the "receiver is smi" control if we didn't handle the case of
+ // Number primitives in the polymorphic branches above.
+ if (receiverissmi_control != nullptr) {
+ // Mark the "receiver is smi" case as deferred.
+ MarkAsDeferred(receiverissmi_control);
+ DCHECK_EQ(exit_effect, receiverissmi_effect);
+ exit_controls.push_back(receiverissmi_control);
+ }
+
// Generate the single "exit" point, where we get if either all map/instance
// type checks failed, or one of the assumptions inside one of the cases
// failes (i.e. failing prototype chain check).
@@ -876,14 +901,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
// Collect the fallthrough control as final "exit" control.
if (fallthrough_control != control) {
// Mark the last fallthrough branch as deferred.
- Node* branch = NodeProperties::GetControlInput(fallthrough_control);
- DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
- if (fallthrough_control->opcode() == IrOpcode::kIfTrue) {
- NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kFalse));
- } else {
- DCHECK_EQ(IrOpcode::kIfFalse, fallthrough_control->opcode());
- NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kTrue));
- }
+ MarkAsDeferred(fallthrough_control);
}
exit_controls.push_back(fallthrough_control);
@@ -1053,6 +1071,18 @@ void JSNativeContextSpecialization::AssumePrototypesStable(
}
+void JSNativeContextSpecialization::MarkAsDeferred(Node* if_projection) {
+ Node* branch = NodeProperties::GetControlInput(if_projection);
+ DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
+ if (if_projection->opcode() == IrOpcode::kIfTrue) {
+ NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kFalse));
+ } else {
+ DCHECK_EQ(IrOpcode::kIfFalse, if_projection->opcode());
+ NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kTrue));
+ }
+}
+
+
Graph* JSNativeContextSpecialization::graph() const {
return jsgraph()->graph();
}
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698