| 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 |