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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 // Perform the hole check on the result. | 704 // Perform the hole check on the result. |
705 Node* check = | 705 Node* check = |
706 graph()->NewNode(simplified()->ReferenceEqual(element_access.type), | 706 graph()->NewNode(simplified()->ReferenceEqual(element_access.type), |
707 this_value, jsgraph()->TheHoleConstant()); | 707 this_value, jsgraph()->TheHoleConstant()); |
708 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 708 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
709 check, this_control); | 709 check, this_control); |
710 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 710 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
711 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 711 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
712 // Check if we are allowed to turn the hole into undefined. | 712 // Check if we are allowed to turn the hole into undefined. |
713 Type* initial_holey_array_type = Type::Class( | 713 Type* initial_holey_array_type = Type::Class( |
714 handle(isolate()->get_initial_js_array_map(FAST_HOLEY_ELEMENTS)), | 714 handle(isolate()->get_initial_js_array_map(elements_kind)), |
715 graph()->zone()); | 715 graph()->zone()); |
716 if (receiver_type->NowIs(initial_holey_array_type) && | 716 if (receiver_type->NowIs(initial_holey_array_type) && |
717 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 717 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
718 // Add a code dependency on the array protector cell. | 718 // Add a code dependency on the array protector cell. |
719 AssumePrototypesStable(receiver_type, | 719 AssumePrototypesStable(receiver_type, |
720 isolate()->initial_object_prototype()); | 720 isolate()->initial_object_prototype()); |
721 dependencies()->AssumePropertyCell(factory()->array_protector()); | 721 dependencies()->AssumePropertyCell(factory()->array_protector()); |
722 // Turn the hole into undefined. | 722 // Turn the hole into undefined. |
723 this_control = | 723 this_control = |
724 graph()->NewNode(common()->Merge(2), if_true, if_false); | 724 graph()->NewNode(common()->Merge(2), if_true, if_false); |
725 this_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), | 725 this_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), |
726 jsgraph()->UndefinedConstant(), | 726 jsgraph()->UndefinedConstant(), |
727 this_value, this_control); | 727 this_value, this_control); |
728 element_type = | 728 element_type = |
729 Type::Union(element_type, Type::Undefined(), graph()->zone()); | 729 Type::Union(element_type, Type::Undefined(), graph()->zone()); |
730 } else { | 730 } else { |
731 // Deoptimize in case of the hole. | 731 // Deoptimize in case of the hole. |
732 exit_controls.push_back(if_true); | 732 exit_controls.push_back(if_true); |
733 this_control = if_false; | 733 this_control = if_false; |
734 } | 734 } |
735 // Rename the result to represent the actual type (not polluted by the | 735 // Rename the result to represent the actual type (not polluted by the |
736 // hole). | 736 // hole). |
737 this_value = graph()->NewNode(common()->Guard(element_type), this_value, | 737 this_value = graph()->NewNode(common()->Guard(element_type), this_value, |
738 this_control); | 738 this_control); |
| 739 } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { |
| 740 // Perform the hole check on the result. |
| 741 Node* check = |
| 742 graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value); |
| 743 // Check if we are allowed to return the hole directly. |
| 744 Type* initial_holey_array_type = Type::Class( |
| 745 handle(isolate()->get_initial_js_array_map(elements_kind)), |
| 746 graph()->zone()); |
| 747 if (receiver_type->NowIs(initial_holey_array_type) && |
| 748 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
| 749 // Add a code dependency on the array protector cell. |
| 750 AssumePrototypesStable(receiver_type, |
| 751 isolate()->initial_object_prototype()); |
| 752 dependencies()->AssumePropertyCell(factory()->array_protector()); |
| 753 // Turn the hole into undefined. |
| 754 this_value = graph()->NewNode( |
| 755 common()->Select(kMachAnyTagged, BranchHint::kFalse), check, |
| 756 jsgraph()->UndefinedConstant(), this_value); |
| 757 } else { |
| 758 // Deoptimize in case of the hole. |
| 759 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 760 check, this_control); |
| 761 this_control = graph()->NewNode(common()->IfFalse(), branch); |
| 762 exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); |
| 763 } |
739 } | 764 } |
740 } else { | 765 } else { |
741 DCHECK_EQ(AccessMode::kStore, access_mode); | 766 DCHECK_EQ(AccessMode::kStore, access_mode); |
742 if (IsFastSmiElementsKind(elements_kind)) { | 767 if (IsFastSmiElementsKind(elements_kind)) { |
743 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value); | 768 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |
744 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 769 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
745 check, this_control); | 770 check, this_control); |
746 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); | 771 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); |
747 this_control = graph()->NewNode(common()->IfTrue(), branch); | 772 this_control = graph()->NewNode(common()->IfTrue(), branch); |
748 } else if (IsFastDoubleElementsKind(elements_kind)) { | 773 } else if (IsFastDoubleElementsKind(elements_kind)) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 } | 986 } |
962 | 987 |
963 | 988 |
964 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 989 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
965 return jsgraph()->simplified(); | 990 return jsgraph()->simplified(); |
966 } | 991 } |
967 | 992 |
968 } // namespace compiler | 993 } // namespace compiler |
969 } // namespace internal | 994 } // namespace internal |
970 } // namespace v8 | 995 } // namespace v8 |
OLD | NEW |