Index: src/compiler/js-builtin-reducer.cc |
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc |
index 6b0c3aceeba7facd9730383173682dba7014b596..a1c83ce1b639b733205909e760f79e672e49b081 100644 |
--- a/src/compiler/js-builtin-reducer.cc |
+++ b/src/compiler/js-builtin-reducer.cc |
@@ -912,20 +912,42 @@ Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) { |
// 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)) { |
+ ZoneHandleSet<Map> receiver_maps; |
+ NodeProperties::InferReceiverMapsResult result = |
+ NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps); |
+ if (receiver_maps.size() != 1) return NoChange(); |
+ DCHECK_NE(NodeProperties::kNoReceiverMaps, result); |
+ |
+ // TODO(turbofan): Relax this to deal with multiple {receiver} maps. |
+ Handle<Map> receiver_map = receiver_maps[0]; |
+ if (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); |
+ // If the {receiver_maps} information is not reliable, we need |
+ // to check that the {receiver} still has one of these maps. |
+ if (result == NodeProperties::kUnreliableReceiverMaps) { |
+ if (receiver_map->is_stable()) { |
+ dependencies()->AssumeMapStable(receiver_map); |
+ } else { |
+ // TODO(turbofan): This is a potential - yet unlikely - deoptimization |
+ // loop, since we might not learn from this deoptimization in baseline |
+ // code. We need a way to learn from deoptimizations in optimized to |
+ // address these problems. |
+ effect = graph()->NewNode( |
+ simplified()->CheckMaps(CheckMapsFlag::kNone, receiver_maps), |
+ receiver, effect, control); |
+ } |
+ } |
+ |
// 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 |