OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 } | 141 } |
142 | 142 |
143 // Nothing to do if we have no non-deprecated maps. | 143 // Nothing to do if we have no non-deprecated maps. |
144 if (access_infos.empty()) { | 144 if (access_infos.empty()) { |
145 return ReduceSoftDeoptimize( | 145 return ReduceSoftDeoptimize( |
146 node, DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 146 node, DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
147 } | 147 } |
148 | 148 |
149 // Ensure that {index} matches the specified {name} (if {index} is given). | 149 // Ensure that {index} matches the specified {name} (if {index} is given). |
150 if (index != nullptr) { | 150 if (index != nullptr) { |
151 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Name()), | 151 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), index, |
152 index, jsgraph()->HeapConstant(name)); | 152 jsgraph()->HeapConstant(name)); |
153 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); | 153 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
154 } | 154 } |
155 | 155 |
156 // Check for the monomorphic cases. | 156 // Check for the monomorphic cases. |
157 if (access_infos.size() == 1) { | 157 if (access_infos.size() == 1) { |
158 PropertyAccessInfo access_info = access_infos.front(); | 158 PropertyAccessInfo access_info = access_infos.front(); |
159 if (HasOnlyStringMaps(access_info.receiver_maps())) { | 159 if (HasOnlyStringMaps(access_info.receiver_maps())) { |
160 // Monormorphic string access (ignoring the fact that there are multiple | 160 // Monormorphic string access (ignoring the fact that there are multiple |
161 // String maps). | 161 // String maps). |
162 receiver = effect = graph()->NewNode(simplified()->CheckString(), | 162 receiver = effect = graph()->NewNode(simplified()->CheckString(), |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 // Perform map check on {receiver}. | 226 // Perform map check on {receiver}. |
227 MapList const& receiver_maps = access_info.receiver_maps(); | 227 MapList const& receiver_maps = access_info.receiver_maps(); |
228 { | 228 { |
229 // Emit a (sequence of) map checks for other {receiver}s. | 229 // Emit a (sequence of) map checks for other {receiver}s. |
230 ZoneVector<Node*> this_controls(zone()); | 230 ZoneVector<Node*> this_controls(zone()); |
231 ZoneVector<Node*> this_effects(zone()); | 231 ZoneVector<Node*> this_effects(zone()); |
232 size_t num_classes = receiver_maps.size(); | 232 size_t num_classes = receiver_maps.size(); |
233 for (auto map : receiver_maps) { | 233 for (auto map : receiver_maps) { |
234 DCHECK_LT(0u, num_classes); | 234 DCHECK_LT(0u, num_classes); |
235 Node* check = | 235 Node* check = |
236 graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()), | 236 graph()->NewNode(simplified()->ReferenceEqual(), receiver_map, |
237 receiver_map, jsgraph()->Constant(map)); | 237 jsgraph()->Constant(map)); |
238 if (--num_classes == 0 && j == access_infos.size() - 1) { | 238 if (--num_classes == 0 && j == access_infos.size() - 1) { |
239 check = graph()->NewNode(simplified()->CheckIf(), check, | 239 check = graph()->NewNode(simplified()->CheckIf(), check, |
240 this_effect, fallthrough_control); | 240 this_effect, fallthrough_control); |
241 this_controls.push_back(fallthrough_control); | 241 this_controls.push_back(fallthrough_control); |
242 this_effects.push_back(check); | 242 this_effects.push_back(check); |
243 fallthrough_control = nullptr; | 243 fallthrough_control = nullptr; |
244 } else { | 244 } else { |
245 Node* branch = graph()->NewNode(common()->Branch(), check, | 245 Node* branch = graph()->NewNode(common()->Branch(), check, |
246 fallthrough_control); | 246 fallthrough_control); |
247 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); | 247 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 | 524 |
525 // Perform map check(s) on {receiver}. | 525 // Perform map check(s) on {receiver}. |
526 MapList const& receiver_maps = access_info.receiver_maps(); | 526 MapList const& receiver_maps = access_info.receiver_maps(); |
527 { | 527 { |
528 ZoneVector<Node*> this_controls(zone()); | 528 ZoneVector<Node*> this_controls(zone()); |
529 ZoneVector<Node*> this_effects(zone()); | 529 ZoneVector<Node*> this_effects(zone()); |
530 size_t num_classes = receiver_maps.size(); | 530 size_t num_classes = receiver_maps.size(); |
531 for (Handle<Map> map : receiver_maps) { | 531 for (Handle<Map> map : receiver_maps) { |
532 DCHECK_LT(0u, num_classes); | 532 DCHECK_LT(0u, num_classes); |
533 Node* check = | 533 Node* check = |
534 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), | 534 graph()->NewNode(simplified()->ReferenceEqual(), receiver_map, |
535 receiver_map, jsgraph()->Constant(map)); | 535 jsgraph()->Constant(map)); |
536 if (--num_classes == 0 && j == access_infos.size() - 1) { | 536 if (--num_classes == 0 && j == access_infos.size() - 1) { |
537 // Last map check on the fallthrough control path, do a conditional | 537 // Last map check on the fallthrough control path, do a conditional |
538 // eager deoptimization exit here. | 538 // eager deoptimization exit here. |
539 // TODO(turbofan): This is ugly as hell! We should probably | 539 // TODO(turbofan): This is ugly as hell! We should probably |
540 // introduce macro-ish operators for property access that | 540 // introduce macro-ish operators for property access that |
541 // encapsulate this whole mess. | 541 // encapsulate this whole mess. |
542 check = graph()->NewNode(simplified()->CheckIf(), check, | 542 check = graph()->NewNode(simplified()->CheckIf(), check, |
543 this_effect, this_control); | 543 this_effect, this_control); |
544 this_controls.push_back(this_control); | 544 this_controls.push_back(this_control); |
545 this_effects.push_back(check); | 545 this_effects.push_back(check); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 AssumePrototypesStable(access_info.receiver_maps(), native_context, holder); | 746 AssumePrototypesStable(access_info.receiver_maps(), native_context, holder); |
747 } | 747 } |
748 | 748 |
749 // Generate the actual property access. | 749 // Generate the actual property access. |
750 if (access_info.IsNotFound()) { | 750 if (access_info.IsNotFound()) { |
751 DCHECK_EQ(AccessMode::kLoad, access_mode); | 751 DCHECK_EQ(AccessMode::kLoad, access_mode); |
752 value = jsgraph()->UndefinedConstant(); | 752 value = jsgraph()->UndefinedConstant(); |
753 } else if (access_info.IsDataConstant()) { | 753 } else if (access_info.IsDataConstant()) { |
754 value = jsgraph()->Constant(access_info.constant()); | 754 value = jsgraph()->Constant(access_info.constant()); |
755 if (access_mode == AccessMode::kStore) { | 755 if (access_mode == AccessMode::kStore) { |
756 Node* check = graph()->NewNode( | 756 Node* check = |
757 simplified()->ReferenceEqual(Type::Tagged()), value, value); | 757 graph()->NewNode(simplified()->ReferenceEqual(), value, value); |
758 effect = | 758 effect = |
759 graph()->NewNode(simplified()->CheckIf(), check, effect, control); | 759 graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
760 } | 760 } |
761 } else if (access_info.IsAccessorConstant()) { | 761 } else if (access_info.IsAccessorConstant()) { |
762 // TODO(bmeurer): Properly rewire the IfException edge here if there's any. | 762 // TODO(bmeurer): Properly rewire the IfException edge here if there's any. |
763 Node* target = jsgraph()->Constant(access_info.constant()); | 763 Node* target = jsgraph()->Constant(access_info.constant()); |
764 FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state); | 764 FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state); |
765 Handle<SharedFunctionInfo> shared_info = | 765 Handle<SharedFunctionInfo> shared_info = |
766 frame_info.shared_info().ToHandleChecked(); | 766 frame_info.shared_info().ToHandleChecked(); |
767 switch (access_mode) { | 767 switch (access_mode) { |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 } | 1417 } |
1418 | 1418 |
1419 | 1419 |
1420 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1420 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1421 return jsgraph()->simplified(); | 1421 return jsgraph()->simplified(); |
1422 } | 1422 } |
1423 | 1423 |
1424 } // namespace compiler | 1424 } // namespace compiler |
1425 } // namespace internal | 1425 } // namespace internal |
1426 } // namespace v8 | 1426 } // namespace v8 |
OLD | NEW |