[turbofan] Infer receiver maps from earlier map checks.

When trying to infer receiver maps for property accesses, go hunting in
the effect chain to find an earlier CheckMaps or StoreField for the
receiver.

BUG=v8:5267
R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2704563005
Cr-Commit-Position: refs/heads/master@{#43274}
This commit is contained in:
bmeurer 2017-02-17 02:48:32 -08:00 committed by Commit bot
parent 3503ddf0db
commit 4b07a97978

View File

@ -2178,7 +2178,34 @@ MaybeHandle<Map> JSNativeContextSpecialization::InferReceiverMap(Node* receiver,
}
}
}
// TODO(turbofan): Go hunting for CheckMaps(receiver) in the effect chain?
// Go hunting for a matching CheckMaps(receiver) or StoreField[Map](receiver)
// in the {effect} chain.
// TODO(turbofan): Propagate the information along the control/effect chains
// instead at some point to avoid this potentially inefficient hunting.
while (true) {
if (effect->opcode() == IrOpcode::kCheckMaps) {
ZoneHandleSet<Map> maps = CheckMapsParametersOf(effect->op()).maps();
if (maps.size() == 1u) {
Node* object = NodeProperties::GetValueInput(effect, 0);
if (NodeProperties::IsSame(receiver, object)) return maps[0];
}
} else if (effect->opcode() == IrOpcode::kStoreField) {
FieldAccess const access = FieldAccessOf(effect->op());
if (access.offset == HeapObject::kMapOffset) {
Node* object = NodeProperties::GetValueInput(effect, 0);
Node* value = NodeProperties::GetValueInput(effect, 1);
if (object == receiver) {
HeapObjectMatcher m(value);
if (m.HasValue()) return Handle<Map>::cast(m.Value());
}
break;
}
} else if (!effect->op()->HasProperty(Operator::kNoWrite) ||
effect->op()->EffectInputCount() != 1) {
break;
}
effect = NodeProperties::GetEffectInput(effect);
}
return MaybeHandle<Map>();
}