[turbofan] Use CompareMaps/MapGuard to build polymorphic map check for element access.

Bug: v8:5267
Change-Id: I52d208d3520ad9c06c7e33378e2308631c598e33
Reviewed-on: https://chromium-review.googlesource.com/725386
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48679}
This commit is contained in:
Jaroslav Sevcik 2017-10-18 13:13:20 +02:00 committed by Commit Bot
parent d9357fff7a
commit 713da2d5f3

View File

@ -1173,11 +1173,6 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
receiver, this_effect, this_control);
}
// Load the {receiver} map.
Node* receiver_map = this_effect =
graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
receiver, this_effect, this_control);
// Perform map check(s) on {receiver}.
MapHandles const& receiver_maps = access_info.receiver_maps();
if (j == access_infos.size() - 1) {
@ -1187,34 +1182,22 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
receiver_maps);
fallthrough_control = nullptr;
} else {
ZoneVector<Node*> this_controls(zone());
ZoneVector<Node*> this_effects(zone());
// Explicitly branch on the {receiver_maps}.
ZoneHandleSet<Map> maps;
for (Handle<Map> map : receiver_maps) {
Node* check =
graph()->NewNode(simplified()->ReferenceEqual(), receiver_map,
jsgraph()->Constant(map));
Node* branch = graph()->NewNode(common()->Branch(), check,
fallthrough_control);
this_controls.push_back(
graph()->NewNode(common()->IfTrue(), branch));
this_effects.push_back(this_effect);
fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
maps.insert(map, graph()->zone());
}
Node* check = this_effect =
graph()->NewNode(simplified()->CompareMaps(maps), receiver,
this_effect, fallthrough_control);
Node* branch =
graph()->NewNode(common()->Branch(), check, fallthrough_control);
fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
this_control = graph()->NewNode(common()->IfTrue(), branch);
// Create single chokepoint for the control.
int const this_control_count = static_cast<int>(this_controls.size());
if (this_control_count == 1) {
this_control = this_controls.front();
this_effect = this_effects.front();
} else {
this_control =
graph()->NewNode(common()->Merge(this_control_count),
this_control_count, &this_controls.front());
this_effects.push_back(this_control);
this_effect =
graph()->NewNode(common()->EffectPhi(this_control_count),
this_control_count + 1, &this_effects.front());
}
// Introduce a MapGuard to learn from this on the effect chain.
this_effect = graph()->NewNode(common()->MapGuard(maps), receiver,
this_effect, this_control);
}
// Access the actual element.