| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/js-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
| 10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 } | 905 } |
| 906 | 906 |
| 907 ReplaceWithValue(node, value, effect, control); | 907 ReplaceWithValue(node, value, effect, control); |
| 908 return Replace(value); | 908 return Replace(value); |
| 909 } | 909 } |
| 910 return NoChange(); | 910 return NoChange(); |
| 911 } | 911 } |
| 912 | 912 |
| 913 // ES6 section 22.1.3.18 Array.prototype.push ( ) | 913 // ES6 section 22.1.3.18 Array.prototype.push ( ) |
| 914 Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) { | 914 Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) { |
| 915 Handle<Map> receiver_map; | |
| 916 // We need exactly target, receiver and value parameters. | 915 // We need exactly target, receiver and value parameters. |
| 917 if (node->op()->ValueInputCount() != 3) return NoChange(); | 916 if (node->op()->ValueInputCount() != 3) return NoChange(); |
| 918 Node* receiver = NodeProperties::GetValueInput(node, 1); | 917 Node* receiver = NodeProperties::GetValueInput(node, 1); |
| 919 Node* effect = NodeProperties::GetEffectInput(node); | 918 Node* effect = NodeProperties::GetEffectInput(node); |
| 920 Node* control = NodeProperties::GetControlInput(node); | 919 Node* control = NodeProperties::GetControlInput(node); |
| 921 Node* value = NodeProperties::GetValueInput(node, 2); | 920 Node* value = NodeProperties::GetValueInput(node, 2); |
| 922 if (GetMapWitness(node).ToHandle(&receiver_map) && | 921 ZoneHandleSet<Map> receiver_maps; |
| 923 CanInlineArrayResizeOperation(receiver_map)) { | 922 NodeProperties::InferReceiverMapsResult result = |
| 923 NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps); |
| 924 if (receiver_maps.size() != 1) return NoChange(); |
| 925 DCHECK_NE(NodeProperties::kNoReceiverMaps, result); |
| 926 |
| 927 // TODO(turbofan): Relax this to deal with multiple {receiver} maps. |
| 928 Handle<Map> receiver_map = receiver_maps[0]; |
| 929 if (CanInlineArrayResizeOperation(receiver_map)) { |
| 924 // Install code dependencies on the {receiver} prototype maps and the | 930 // Install code dependencies on the {receiver} prototype maps and the |
| 925 // global array protector cell. | 931 // global array protector cell. |
| 926 dependencies()->AssumePropertyCell(factory()->array_protector()); | 932 dependencies()->AssumePropertyCell(factory()->array_protector()); |
| 927 dependencies()->AssumePrototypeMapsStable(receiver_map); | 933 dependencies()->AssumePrototypeMapsStable(receiver_map); |
| 928 | 934 |
| 935 // If the {receiver_maps} information is not reliable, we need |
| 936 // to check that the {receiver} still has one of these maps. |
| 937 if (result == NodeProperties::kUnreliableReceiverMaps) { |
| 938 if (receiver_map->is_stable()) { |
| 939 dependencies()->AssumeMapStable(receiver_map); |
| 940 } else { |
| 941 // TODO(turbofan): This is a potential - yet unlikely - deoptimization |
| 942 // loop, since we might not learn from this deoptimization in baseline |
| 943 // code. We need a way to learn from deoptimizations in optimized to |
| 944 // address these problems. |
| 945 effect = graph()->NewNode( |
| 946 simplified()->CheckMaps(CheckMapsFlag::kNone, receiver_maps), |
| 947 receiver, effect, control); |
| 948 } |
| 949 } |
| 950 |
| 929 // TODO(turbofan): Perform type checks on the {value}. We are not guaranteed | 951 // TODO(turbofan): Perform type checks on the {value}. We are not guaranteed |
| 930 // to learn from these checks in case they fail, as the witness (i.e. the | 952 // to learn from these checks in case they fail, as the witness (i.e. the |
| 931 // map check from the LoadIC for a.push) might not be executed in baseline | 953 // map check from the LoadIC for a.push) might not be executed in baseline |
| 932 // code (after we stored the value in the builtin and thereby changed the | 954 // code (after we stored the value in the builtin and thereby changed the |
| 933 // elements kind of a) before be decide to optimize this function again. We | 955 // elements kind of a) before be decide to optimize this function again. We |
| 934 // currently don't have a proper way to deal with this; the proper solution | 956 // currently don't have a proper way to deal with this; the proper solution |
| 935 // here is to learn on deopt, i.e. disable Array.prototype.push inlining | 957 // here is to learn on deopt, i.e. disable Array.prototype.push inlining |
| 936 // for this function. | 958 // for this function. |
| 937 if (IsFastSmiElementsKind(receiver_map->elements_kind())) { | 959 if (IsFastSmiElementsKind(receiver_map->elements_kind())) { |
| 938 value = effect = | 960 value = effect = |
| (...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2310 return jsgraph()->simplified(); | 2332 return jsgraph()->simplified(); |
| 2311 } | 2333 } |
| 2312 | 2334 |
| 2313 JSOperatorBuilder* JSBuiltinReducer::javascript() const { | 2335 JSOperatorBuilder* JSBuiltinReducer::javascript() const { |
| 2314 return jsgraph()->javascript(); | 2336 return jsgraph()->javascript(); |
| 2315 } | 2337 } |
| 2316 | 2338 |
| 2317 } // namespace compiler | 2339 } // namespace compiler |
| 2318 } // namespace internal | 2340 } // namespace internal |
| 2319 } // namespace v8 | 2341 } // namespace v8 |
| OLD | NEW |