| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
| 7 #include "src/frames.h" | 7 #include "src/frames.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 return WordEqual(WordAnd(BitcastTaggedToWord(a), | 600 return WordEqual(WordAnd(BitcastTaggedToWord(a), |
| 601 IntPtrConstant(kSmiTagMask | kSmiSignMask)), | 601 IntPtrConstant(kSmiTagMask | kSmiSignMask)), |
| 602 IntPtrConstant(0)); | 602 IntPtrConstant(0)); |
| 603 } | 603 } |
| 604 | 604 |
| 605 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { | 605 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { |
| 606 return WordEqual(IntPtrConstant(0), | 606 return WordEqual(IntPtrConstant(0), |
| 607 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); | 607 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); |
| 608 } | 608 } |
| 609 | 609 |
| 610 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map, | |
| 611 Node* rhs, Node* rhs_map, | |
| 612 Label* if_equal, | |
| 613 Label* if_notequal) { | |
| 614 Label if_mapsame(this), if_mapnotsame(this); | |
| 615 Branch(WordEqual(lhs_map, rhs_map), &if_mapsame, &if_mapnotsame); | |
| 616 | |
| 617 Bind(&if_mapsame); | |
| 618 { | |
| 619 // Both {lhs} and {rhs} are Simd128Values with the same map, need special | |
| 620 // handling for Float32x4 because of NaN comparisons. | |
| 621 Label if_float32x4(this), if_notfloat32x4(this); | |
| 622 Node* float32x4_map = HeapConstant(factory()->float32x4_map()); | |
| 623 Branch(WordEqual(lhs_map, float32x4_map), &if_float32x4, &if_notfloat32x4); | |
| 624 | |
| 625 Bind(&if_float32x4); | |
| 626 { | |
| 627 // Both {lhs} and {rhs} are Float32x4, compare the lanes individually | |
| 628 // using a floating point comparison. | |
| 629 for (int offset = Float32x4::kValueOffset - kHeapObjectTag; | |
| 630 offset < Float32x4::kSize - kHeapObjectTag; | |
| 631 offset += sizeof(float)) { | |
| 632 // Load the floating point values for {lhs} and {rhs}. | |
| 633 Node* lhs_value = | |
| 634 Load(MachineType::Float32(), lhs, IntPtrConstant(offset)); | |
| 635 Node* rhs_value = | |
| 636 Load(MachineType::Float32(), rhs, IntPtrConstant(offset)); | |
| 637 | |
| 638 // Perform a floating point comparison. | |
| 639 Label if_valueequal(this), if_valuenotequal(this); | |
| 640 Branch(Float32Equal(lhs_value, rhs_value), &if_valueequal, | |
| 641 &if_valuenotequal); | |
| 642 Bind(&if_valuenotequal); | |
| 643 Goto(if_notequal); | |
| 644 Bind(&if_valueequal); | |
| 645 } | |
| 646 | |
| 647 // All 4 lanes match, {lhs} and {rhs} considered equal. | |
| 648 Goto(if_equal); | |
| 649 } | |
| 650 | |
| 651 Bind(&if_notfloat32x4); | |
| 652 { | |
| 653 // For other Simd128Values we just perform a bitwise comparison. | |
| 654 for (int offset = Simd128Value::kValueOffset - kHeapObjectTag; | |
| 655 offset < Simd128Value::kSize - kHeapObjectTag; | |
| 656 offset += kPointerSize) { | |
| 657 // Load the word values for {lhs} and {rhs}. | |
| 658 Node* lhs_value = | |
| 659 Load(MachineType::Pointer(), lhs, IntPtrConstant(offset)); | |
| 660 Node* rhs_value = | |
| 661 Load(MachineType::Pointer(), rhs, IntPtrConstant(offset)); | |
| 662 | |
| 663 // Perform a bitwise word-comparison. | |
| 664 Label if_valueequal(this), if_valuenotequal(this); | |
| 665 Branch(WordEqual(lhs_value, rhs_value), &if_valueequal, | |
| 666 &if_valuenotequal); | |
| 667 Bind(&if_valuenotequal); | |
| 668 Goto(if_notequal); | |
| 669 Bind(&if_valueequal); | |
| 670 } | |
| 671 | |
| 672 // Bitwise comparison succeeded, {lhs} and {rhs} considered equal. | |
| 673 Goto(if_equal); | |
| 674 } | |
| 675 } | |
| 676 | |
| 677 Bind(&if_mapnotsame); | |
| 678 Goto(if_notequal); | |
| 679 } | |
| 680 | |
| 681 void CodeStubAssembler::BranchIfPrototypesHaveNoElements( | 610 void CodeStubAssembler::BranchIfPrototypesHaveNoElements( |
| 682 Node* receiver_map, Label* definitely_no_elements, | 611 Node* receiver_map, Label* definitely_no_elements, |
| 683 Label* possibly_elements) { | 612 Label* possibly_elements) { |
| 684 Variable var_map(this, MachineRepresentation::kTagged, receiver_map); | 613 Variable var_map(this, MachineRepresentation::kTagged, receiver_map); |
| 685 Label loop_body(this, &var_map); | 614 Label loop_body(this, &var_map); |
| 686 Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | 615 Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex); |
| 687 Goto(&loop_body); | 616 Goto(&loop_body); |
| 688 | 617 |
| 689 Bind(&loop_body); | 618 Bind(&loop_body); |
| 690 { | 619 { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 | 741 |
| 813 Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, | 742 Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, |
| 814 AllocationFlags flags, | 743 AllocationFlags flags, |
| 815 Node* top_address, | 744 Node* top_address, |
| 816 Node* limit_address) { | 745 Node* limit_address) { |
| 817 Node* top = Load(MachineType::Pointer(), top_address); | 746 Node* top = Load(MachineType::Pointer(), top_address); |
| 818 Node* limit = Load(MachineType::Pointer(), limit_address); | 747 Node* limit = Load(MachineType::Pointer(), limit_address); |
| 819 Variable adjusted_size(this, MachineType::PointerRepresentation(), | 748 Variable adjusted_size(this, MachineType::PointerRepresentation(), |
| 820 size_in_bytes); | 749 size_in_bytes); |
| 821 if (flags & kDoubleAlignment) { | 750 if (flags & kDoubleAlignment) { |
| 822 // TODO(epertoso): Simd128 alignment. | |
| 823 Label aligned(this), not_aligned(this), merge(this, &adjusted_size); | 751 Label aligned(this), not_aligned(this), merge(this, &adjusted_size); |
| 824 Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), ¬_aligned, | 752 Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), ¬_aligned, |
| 825 &aligned); | 753 &aligned); |
| 826 | 754 |
| 827 Bind(¬_aligned); | 755 Bind(¬_aligned); |
| 828 Node* not_aligned_size = | 756 Node* not_aligned_size = |
| 829 IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); | 757 IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); |
| 830 adjusted_size.Bind(not_aligned_size); | 758 adjusted_size.Bind(not_aligned_size); |
| 831 Goto(&merge); | 759 Goto(&merge); |
| 832 | 760 |
| 833 Bind(&aligned); | 761 Bind(&aligned); |
| 834 Goto(&merge); | 762 Goto(&merge); |
| 835 | 763 |
| 836 Bind(&merge); | 764 Bind(&merge); |
| 837 } | 765 } |
| 838 | 766 |
| 839 Variable address( | 767 Variable address( |
| 840 this, MachineRepresentation::kTagged, | 768 this, MachineRepresentation::kTagged, |
| 841 AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit)); | 769 AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit)); |
| 842 | 770 |
| 843 Label needs_filler(this), doesnt_need_filler(this), | 771 Label needs_filler(this), doesnt_need_filler(this), |
| 844 merge_address(this, &address); | 772 merge_address(this, &address); |
| 845 Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler, | 773 Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler, |
| 846 &needs_filler); | 774 &needs_filler); |
| 847 | 775 |
| 848 Bind(&needs_filler); | 776 Bind(&needs_filler); |
| 849 // Store a filler and increase the address by kPointerSize. | 777 // Store a filler and increase the address by kPointerSize. |
| 850 // TODO(epertoso): this code assumes that we only align to kDoubleSize. Change | |
| 851 // it when Simd128 alignment is supported. | |
| 852 StoreNoWriteBarrier(MachineType::PointerRepresentation(), top, | 778 StoreNoWriteBarrier(MachineType::PointerRepresentation(), top, |
| 853 LoadRoot(Heap::kOnePointerFillerMapRootIndex)); | 779 LoadRoot(Heap::kOnePointerFillerMapRootIndex)); |
| 854 address.Bind(BitcastWordToTagged( | 780 address.Bind(BitcastWordToTagged( |
| 855 IntPtrAdd(address.value(), IntPtrConstant(kPointerSize)))); | 781 IntPtrAdd(address.value(), IntPtrConstant(kPointerSize)))); |
| 856 Goto(&merge_address); | 782 Goto(&merge_address); |
| 857 | 783 |
| 858 Bind(&doesnt_need_filler); | 784 Bind(&doesnt_need_filler); |
| 859 Goto(&merge_address); | 785 Goto(&merge_address); |
| 860 | 786 |
| 861 Bind(&merge_address); | 787 Bind(&merge_address); |
| (...skipping 3142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4004 Bind(&if_resultisnotnumber); | 3930 Bind(&if_resultisnotnumber); |
| 4005 { | 3931 { |
| 4006 // We now have a Primitive {result}, but it's not yet a Number. | 3932 // We now have a Primitive {result}, but it's not yet a Number. |
| 4007 var_input.Bind(result); | 3933 var_input.Bind(result); |
| 4008 Goto(&loop); | 3934 Goto(&loop); |
| 4009 } | 3935 } |
| 4010 } | 3936 } |
| 4011 | 3937 |
| 4012 Bind(&if_inputisother); | 3938 Bind(&if_inputisother); |
| 4013 { | 3939 { |
| 4014 // The {input} is something else (i.e. Symbol or Simd128Value), let the | 3940 // The {input} is something else (e.g. Symbol), let the runtime figure |
| 4015 // runtime figure out the correct exception. | 3941 // out the correct exception. |
| 4016 // Note: We cannot tail call to the runtime here, as js-to-wasm | 3942 // Note: We cannot tail call to the runtime here, as js-to-wasm |
| 4017 // trampolines also use this code currently, and they declare all | 3943 // trampolines also use this code currently, and they declare all |
| 4018 // outgoing parameters as untagged, while we would push a tagged | 3944 // outgoing parameters as untagged, while we would push a tagged |
| 4019 // object here. | 3945 // object here. |
| 4020 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input)); | 3946 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input)); |
| 4021 Goto(&end); | 3947 Goto(&end); |
| 4022 } | 3948 } |
| 4023 } | 3949 } |
| 4024 | 3950 |
| 4025 Bind(&end); | 3951 Bind(&end); |
| (...skipping 2805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6831 } | 6757 } |
| 6832 | 6758 |
| 6833 namespace { | 6759 namespace { |
| 6834 | 6760 |
| 6835 void GenerateEqual_Same(CodeStubAssembler* assembler, Node* value, | 6761 void GenerateEqual_Same(CodeStubAssembler* assembler, Node* value, |
| 6836 CodeStubAssembler::Label* if_equal, | 6762 CodeStubAssembler::Label* if_equal, |
| 6837 CodeStubAssembler::Label* if_notequal) { | 6763 CodeStubAssembler::Label* if_notequal) { |
| 6838 // In case of abstract or strict equality checks, we need additional checks | 6764 // In case of abstract or strict equality checks, we need additional checks |
| 6839 // for NaN values because they are not considered equal, even if both the | 6765 // for NaN values because they are not considered equal, even if both the |
| 6840 // left and the right hand side reference exactly the same value. | 6766 // left and the right hand side reference exactly the same value. |
| 6841 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it | |
| 6842 // seems to be what is tested in the current SIMD.js testsuite. | |
| 6843 | 6767 |
| 6844 typedef CodeStubAssembler::Label Label; | 6768 typedef CodeStubAssembler::Label Label; |
| 6845 | 6769 |
| 6846 // Check if {value} is a Smi or a HeapObject. | 6770 // Check if {value} is a Smi or a HeapObject. |
| 6847 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); | 6771 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); |
| 6848 assembler->Branch(assembler->TaggedIsSmi(value), &if_valueissmi, | 6772 assembler->Branch(assembler->TaggedIsSmi(value), &if_valueissmi, |
| 6849 &if_valueisnotsmi); | 6773 &if_valueisnotsmi); |
| 6850 | 6774 |
| 6851 assembler->Bind(&if_valueisnotsmi); | 6775 assembler->Bind(&if_valueisnotsmi); |
| 6852 { | 6776 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6867 assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal); | 6791 assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal); |
| 6868 } | 6792 } |
| 6869 | 6793 |
| 6870 assembler->Bind(&if_valueisnotnumber); | 6794 assembler->Bind(&if_valueisnotnumber); |
| 6871 assembler->Goto(if_equal); | 6795 assembler->Goto(if_equal); |
| 6872 } | 6796 } |
| 6873 | 6797 |
| 6874 assembler->Bind(&if_valueissmi); | 6798 assembler->Bind(&if_valueissmi); |
| 6875 assembler->Goto(if_equal); | 6799 assembler->Goto(if_equal); |
| 6876 } | 6800 } |
| 6877 | |
| 6878 void GenerateEqual_Simd128Value_HeapObject( | |
| 6879 CodeStubAssembler* assembler, Node* lhs, Node* lhs_map, Node* rhs, | |
| 6880 Node* rhs_map, CodeStubAssembler::Label* if_equal, | |
| 6881 CodeStubAssembler::Label* if_notequal) { | |
| 6882 assembler->BranchIfSimd128Equal(lhs, lhs_map, rhs, rhs_map, if_equal, | |
| 6883 if_notequal); | |
| 6884 } | |
| 6885 | |
| 6886 } // namespace | 6801 } // namespace |
| 6887 | 6802 |
| 6888 // ES6 section 7.2.12 Abstract Equality Comparison | 6803 // ES6 section 7.2.12 Abstract Equality Comparison |
| 6889 Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs, | 6804 Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs, |
| 6890 Node* context) { | 6805 Node* context) { |
| 6891 // This is a slightly optimized version of Object::Equals represented as | 6806 // This is a slightly optimized version of Object::Equals represented as |
| 6892 // scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you | 6807 // scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you |
| 6893 // change something functionality wise in here, remember to update the | 6808 // change something functionality wise in here, remember to update the |
| 6894 // Object::Equals method as well. | 6809 // Object::Equals method as well. |
| 6895 | 6810 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7033 // we can just swap them and use the Smi handling above (for {lhs} | 6948 // we can just swap them and use the Smi handling above (for {lhs} |
| 7034 // being a Smi). | 6949 // being a Smi). |
| 7035 var_lhs.Bind(rhs); | 6950 var_lhs.Bind(rhs); |
| 7036 var_rhs.Bind(lhs); | 6951 var_rhs.Bind(lhs); |
| 7037 Goto(&loop); | 6952 Goto(&loop); |
| 7038 } | 6953 } |
| 7039 | 6954 |
| 7040 Bind(&if_rhsisnotsmi); | 6955 Bind(&if_rhsisnotsmi); |
| 7041 { | 6956 { |
| 7042 Label if_lhsisstring(this), if_lhsisnumber(this), | 6957 Label if_lhsisstring(this), if_lhsisnumber(this), |
| 7043 if_lhsissymbol(this), if_lhsissimd128value(this), | 6958 if_lhsissymbol(this), if_lhsisoddball(this), |
| 7044 if_lhsisoddball(this), if_lhsisreceiver(this); | 6959 if_lhsisreceiver(this); |
| 7045 | 6960 |
| 7046 // Both {lhs} and {rhs} are HeapObjects, load their maps | 6961 // Both {lhs} and {rhs} are HeapObjects, load their maps |
| 7047 // and their instance types. | 6962 // and their instance types. |
| 7048 Node* lhs_map = LoadMap(lhs); | 6963 Node* lhs_map = LoadMap(lhs); |
| 7049 Node* rhs_map = LoadMap(rhs); | 6964 Node* rhs_map = LoadMap(rhs); |
| 7050 | 6965 |
| 7051 // Load the instance types of {lhs} and {rhs}. | 6966 // Load the instance types of {lhs} and {rhs}. |
| 7052 Node* lhs_instance_type = LoadMapInstanceType(lhs_map); | 6967 Node* lhs_instance_type = LoadMapInstanceType(lhs_map); |
| 7053 Node* rhs_instance_type = LoadMapInstanceType(rhs_map); | 6968 Node* rhs_instance_type = LoadMapInstanceType(rhs_map); |
| 7054 | 6969 |
| 7055 // Dispatch based on the instance type of {lhs}. | 6970 // Dispatch based on the instance type of {lhs}. |
| 7056 size_t const kNumCases = FIRST_NONSTRING_TYPE + 4; | 6971 size_t const kNumCases = FIRST_NONSTRING_TYPE + 3; |
| 7057 Label* case_labels[kNumCases]; | 6972 Label* case_labels[kNumCases]; |
| 7058 int32_t case_values[kNumCases]; | 6973 int32_t case_values[kNumCases]; |
| 7059 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { | 6974 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { |
| 7060 case_labels[i] = new Label(this); | 6975 case_labels[i] = new Label(this); |
| 7061 case_values[i] = i; | 6976 case_values[i] = i; |
| 7062 } | 6977 } |
| 7063 case_labels[FIRST_NONSTRING_TYPE + 0] = &if_lhsisnumber; | 6978 case_labels[FIRST_NONSTRING_TYPE + 0] = &if_lhsisnumber; |
| 7064 case_values[FIRST_NONSTRING_TYPE + 0] = HEAP_NUMBER_TYPE; | 6979 case_values[FIRST_NONSTRING_TYPE + 0] = HEAP_NUMBER_TYPE; |
| 7065 case_labels[FIRST_NONSTRING_TYPE + 1] = &if_lhsissymbol; | 6980 case_labels[FIRST_NONSTRING_TYPE + 1] = &if_lhsissymbol; |
| 7066 case_values[FIRST_NONSTRING_TYPE + 1] = SYMBOL_TYPE; | 6981 case_values[FIRST_NONSTRING_TYPE + 1] = SYMBOL_TYPE; |
| 7067 case_labels[FIRST_NONSTRING_TYPE + 2] = &if_lhsissimd128value; | 6982 case_labels[FIRST_NONSTRING_TYPE + 2] = &if_lhsisoddball; |
| 7068 case_values[FIRST_NONSTRING_TYPE + 2] = SIMD128_VALUE_TYPE; | 6983 case_values[FIRST_NONSTRING_TYPE + 2] = ODDBALL_TYPE; |
| 7069 case_labels[FIRST_NONSTRING_TYPE + 3] = &if_lhsisoddball; | |
| 7070 case_values[FIRST_NONSTRING_TYPE + 3] = ODDBALL_TYPE; | |
| 7071 Switch(lhs_instance_type, &if_lhsisreceiver, case_values, case_labels, | 6984 Switch(lhs_instance_type, &if_lhsisreceiver, case_values, case_labels, |
| 7072 arraysize(case_values)); | 6985 arraysize(case_values)); |
| 7073 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { | 6986 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { |
| 7074 Bind(case_labels[i]); | 6987 Bind(case_labels[i]); |
| 7075 Goto(&if_lhsisstring); | 6988 Goto(&if_lhsisstring); |
| 7076 delete case_labels[i]; | 6989 delete case_labels[i]; |
| 7077 } | 6990 } |
| 7078 | 6991 |
| 7079 Bind(&if_lhsisstring); | 6992 Bind(&if_lhsisstring); |
| 7080 { | 6993 { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7244 } | 7157 } |
| 7245 | 7158 |
| 7246 Bind(&if_rhsisnotreceiver); | 7159 Bind(&if_rhsisnotreceiver); |
| 7247 { | 7160 { |
| 7248 // The {rhs} is not a JSReceiver and also not the same Symbol | 7161 // The {rhs} is not a JSReceiver and also not the same Symbol |
| 7249 // as the {lhs}, so this is equality check is considered false. | 7162 // as the {lhs}, so this is equality check is considered false. |
| 7250 Goto(&if_notequal); | 7163 Goto(&if_notequal); |
| 7251 } | 7164 } |
| 7252 } | 7165 } |
| 7253 | 7166 |
| 7254 Bind(&if_lhsissimd128value); | |
| 7255 { | |
| 7256 // Check if the {rhs} is also a Simd128Value. | |
| 7257 Label if_rhsissimd128value(this), if_rhsisnotsimd128value(this); | |
| 7258 Branch(Word32Equal(lhs_instance_type, rhs_instance_type), | |
| 7259 &if_rhsissimd128value, &if_rhsisnotsimd128value); | |
| 7260 | |
| 7261 Bind(&if_rhsissimd128value); | |
| 7262 { | |
| 7263 // Both {lhs} and {rhs} is a Simd128Value. | |
| 7264 GenerateEqual_Simd128Value_HeapObject( | |
| 7265 this, lhs, lhs_map, rhs, rhs_map, &if_equal, &if_notequal); | |
| 7266 } | |
| 7267 | |
| 7268 Bind(&if_rhsisnotsimd128value); | |
| 7269 { | |
| 7270 // Check if the {rhs} is a JSReceiver. | |
| 7271 Label if_rhsisreceiver(this), if_rhsisnotreceiver(this); | |
| 7272 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); | |
| 7273 Branch(IsJSReceiverInstanceType(rhs_instance_type), | |
| 7274 &if_rhsisreceiver, &if_rhsisnotreceiver); | |
| 7275 | |
| 7276 Bind(&if_rhsisreceiver); | |
| 7277 { | |
| 7278 // The {lhs} is a Primitive and the {rhs} is a JSReceiver. | |
| 7279 // Swapping {lhs} and {rhs} is not observable and doesn't | |
| 7280 // matter for the result, so we can just swap them and use | |
| 7281 // the JSReceiver handling below (for {lhs} being a JSReceiver). | |
| 7282 var_lhs.Bind(rhs); | |
| 7283 var_rhs.Bind(lhs); | |
| 7284 Goto(&loop); | |
| 7285 } | |
| 7286 | |
| 7287 Bind(&if_rhsisnotreceiver); | |
| 7288 { | |
| 7289 // The {rhs} is some other Primitive. | |
| 7290 Goto(&if_notequal); | |
| 7291 } | |
| 7292 } | |
| 7293 } | |
| 7294 | |
| 7295 Bind(&if_lhsisreceiver); | 7167 Bind(&if_lhsisreceiver); |
| 7296 { | 7168 { |
| 7297 // Check if the {rhs} is also a JSReceiver. | 7169 // Check if the {rhs} is also a JSReceiver. |
| 7298 Label if_rhsisreceiver(this), if_rhsisnotreceiver(this); | 7170 Label if_rhsisreceiver(this), if_rhsisnotreceiver(this); |
| 7299 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); | 7171 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
| 7300 Branch(IsJSReceiverInstanceType(rhs_instance_type), | 7172 Branch(IsJSReceiverInstanceType(rhs_instance_type), |
| 7301 &if_rhsisreceiver, &if_rhsisnotreceiver); | 7173 &if_rhsisreceiver, &if_rhsisnotreceiver); |
| 7302 | 7174 |
| 7303 Bind(&if_rhsisreceiver); | 7175 Bind(&if_rhsisreceiver); |
| 7304 { | 7176 { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7403 // } else { | 7275 // } else { |
| 7404 // if (rhs->IsSmi()) { | 7276 // if (rhs->IsSmi()) { |
| 7405 // return false; | 7277 // return false; |
| 7406 // } else { | 7278 // } else { |
| 7407 // if (lhs->IsString()) { | 7279 // if (lhs->IsString()) { |
| 7408 // if (rhs->IsString()) { | 7280 // if (rhs->IsString()) { |
| 7409 // return %StringEqual(lhs, rhs); | 7281 // return %StringEqual(lhs, rhs); |
| 7410 // } else { | 7282 // } else { |
| 7411 // return false; | 7283 // return false; |
| 7412 // } | 7284 // } |
| 7413 // } else if (lhs->IsSimd128()) { | |
| 7414 // if (rhs->IsSimd128()) { | |
| 7415 // return %StrictEqual(lhs, rhs); | |
| 7416 // } | |
| 7417 // } else { | 7285 // } else { |
| 7418 // return false; | 7286 // return false; |
| 7419 // } | 7287 // } |
| 7420 // } | 7288 // } |
| 7421 // } | 7289 // } |
| 7422 // } else { | 7290 // } else { |
| 7423 // if (rhs->IsSmi()) { | 7291 // if (rhs->IsSmi()) { |
| 7424 // return false; | 7292 // return false; |
| 7425 // } else { | 7293 // } else { |
| 7426 // if (rhs->IsHeapNumber()) { | 7294 // if (rhs->IsHeapNumber()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7440 | 7308 |
| 7441 Bind(&if_same); | 7309 Bind(&if_same); |
| 7442 { | 7310 { |
| 7443 // The {lhs} and {rhs} reference the exact same value, yet we need special | 7311 // The {lhs} and {rhs} reference the exact same value, yet we need special |
| 7444 // treatment for HeapNumber, as NaN is not equal to NaN. | 7312 // treatment for HeapNumber, as NaN is not equal to NaN. |
| 7445 GenerateEqual_Same(this, lhs, &if_equal, &if_notequal); | 7313 GenerateEqual_Same(this, lhs, &if_equal, &if_notequal); |
| 7446 } | 7314 } |
| 7447 | 7315 |
| 7448 Bind(&if_notsame); | 7316 Bind(&if_notsame); |
| 7449 { | 7317 { |
| 7450 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber, | 7318 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber |
| 7451 // String and Simd128Value they can still be considered equal. | 7319 // and String they can still be considered equal. |
| 7452 | 7320 |
| 7453 // Check if {lhs} is a Smi or a HeapObject. | 7321 // Check if {lhs} is a Smi or a HeapObject. |
| 7454 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 7322 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
| 7455 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 7323 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
| 7456 | 7324 |
| 7457 Bind(&if_lhsisnotsmi); | 7325 Bind(&if_lhsisnotsmi); |
| 7458 { | 7326 { |
| 7459 // Load the map of {lhs}. | 7327 // Load the map of {lhs}. |
| 7460 Node* lhs_map = LoadMap(lhs); | 7328 Node* lhs_map = LoadMap(lhs); |
| 7461 | 7329 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7540 : CodeFactory::StringNotEqual(isolate()); | 7408 : CodeFactory::StringNotEqual(isolate()); |
| 7541 result.Bind(CallStub(callable, context, lhs, rhs)); | 7409 result.Bind(CallStub(callable, context, lhs, rhs)); |
| 7542 Goto(&end); | 7410 Goto(&end); |
| 7543 } | 7411 } |
| 7544 | 7412 |
| 7545 Bind(&if_rhsisnotstring); | 7413 Bind(&if_rhsisnotstring); |
| 7546 Goto(&if_notequal); | 7414 Goto(&if_notequal); |
| 7547 } | 7415 } |
| 7548 | 7416 |
| 7549 Bind(&if_lhsisnotstring); | 7417 Bind(&if_lhsisnotstring); |
| 7550 { | 7418 Goto(&if_notequal); |
| 7551 // Check if {lhs} is a Simd128Value. | |
| 7552 Label if_lhsissimd128value(this), if_lhsisnotsimd128value(this); | |
| 7553 Branch(Word32Equal(lhs_instance_type, | |
| 7554 Int32Constant(SIMD128_VALUE_TYPE)), | |
| 7555 &if_lhsissimd128value, &if_lhsisnotsimd128value); | |
| 7556 | |
| 7557 Bind(&if_lhsissimd128value); | |
| 7558 { | |
| 7559 // Load the map of {rhs}. | |
| 7560 Node* rhs_map = LoadMap(rhs); | |
| 7561 | |
| 7562 // Check if {rhs} is also a Simd128Value that is equal to {lhs}. | |
| 7563 GenerateEqual_Simd128Value_HeapObject( | |
| 7564 this, lhs, lhs_map, rhs, rhs_map, &if_equal, &if_notequal); | |
| 7565 } | |
| 7566 | |
| 7567 Bind(&if_lhsisnotsimd128value); | |
| 7568 Goto(&if_notequal); | |
| 7569 } | |
| 7570 } | 7419 } |
| 7571 } | 7420 } |
| 7572 } | 7421 } |
| 7573 | 7422 |
| 7574 Bind(&if_lhsissmi); | 7423 Bind(&if_lhsissmi); |
| 7575 { | 7424 { |
| 7576 // We already know that {lhs} and {rhs} are not reference equal, and {lhs} | 7425 // We already know that {lhs} and {rhs} are not reference equal, and {lhs} |
| 7577 // is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a | 7426 // is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a |
| 7578 // HeapNumber with an equal floating point value. | 7427 // HeapNumber with an equal floating point value. |
| 7579 | 7428 |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7866 Int32Constant(1 << Map::kIsCallable)), | 7715 Int32Constant(1 << Map::kIsCallable)), |
| 7867 &return_function); | 7716 &return_function); |
| 7868 | 7717 |
| 7869 GotoUnless(Word32Equal(callable_or_undetectable_mask, Int32Constant(0)), | 7718 GotoUnless(Word32Equal(callable_or_undetectable_mask, Int32Constant(0)), |
| 7870 &return_undefined); | 7719 &return_undefined); |
| 7871 | 7720 |
| 7872 GotoIf(IsJSReceiverInstanceType(instance_type), &return_object); | 7721 GotoIf(IsJSReceiverInstanceType(instance_type), &return_object); |
| 7873 | 7722 |
| 7874 GotoIf(IsStringInstanceType(instance_type), &return_string); | 7723 GotoIf(IsStringInstanceType(instance_type), &return_string); |
| 7875 | 7724 |
| 7876 #define SIMD128_BRANCH(TYPE, Type, type, lane_count, lane_type) \ | |
| 7877 Label return_##type(this); \ | |
| 7878 Node* type##_map = HeapConstant(factory()->type##_map()); \ | |
| 7879 GotoIf(WordEqual(map, type##_map), &return_##type); | |
| 7880 SIMD128_TYPES(SIMD128_BRANCH) | |
| 7881 #undef SIMD128_BRANCH | |
| 7882 | |
| 7883 CSA_ASSERT(this, Word32Equal(instance_type, Int32Constant(SYMBOL_TYPE))); | 7725 CSA_ASSERT(this, Word32Equal(instance_type, Int32Constant(SYMBOL_TYPE))); |
| 7884 result_var.Bind(HeapConstant(isolate()->factory()->symbol_string())); | 7726 result_var.Bind(HeapConstant(isolate()->factory()->symbol_string())); |
| 7885 Goto(&return_result); | 7727 Goto(&return_result); |
| 7886 | 7728 |
| 7887 Bind(&return_number); | 7729 Bind(&return_number); |
| 7888 { | 7730 { |
| 7889 result_var.Bind(HeapConstant(isolate()->factory()->number_string())); | 7731 result_var.Bind(HeapConstant(isolate()->factory()->number_string())); |
| 7890 Goto(&return_result); | 7732 Goto(&return_result); |
| 7891 } | 7733 } |
| 7892 | 7734 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 7914 result_var.Bind(HeapConstant(isolate()->factory()->object_string())); | 7756 result_var.Bind(HeapConstant(isolate()->factory()->object_string())); |
| 7915 Goto(&return_result); | 7757 Goto(&return_result); |
| 7916 } | 7758 } |
| 7917 | 7759 |
| 7918 Bind(&return_string); | 7760 Bind(&return_string); |
| 7919 { | 7761 { |
| 7920 result_var.Bind(HeapConstant(isolate()->factory()->string_string())); | 7762 result_var.Bind(HeapConstant(isolate()->factory()->string_string())); |
| 7921 Goto(&return_result); | 7763 Goto(&return_result); |
| 7922 } | 7764 } |
| 7923 | 7765 |
| 7924 #define SIMD128_BIND_RETURN(TYPE, Type, type, lane_count, lane_type) \ | |
| 7925 Bind(&return_##type); \ | |
| 7926 { \ | |
| 7927 result_var.Bind(HeapConstant(isolate()->factory()->type##_string())); \ | |
| 7928 Goto(&return_result); \ | |
| 7929 } | |
| 7930 SIMD128_TYPES(SIMD128_BIND_RETURN) | |
| 7931 #undef SIMD128_BIND_RETURN | |
| 7932 | |
| 7933 Bind(&return_result); | 7766 Bind(&return_result); |
| 7934 return result_var.value(); | 7767 return result_var.value(); |
| 7935 } | 7768 } |
| 7936 | 7769 |
| 7937 Node* CodeStubAssembler::GetSuperConstructor(Node* active_function, | 7770 Node* CodeStubAssembler::GetSuperConstructor(Node* active_function, |
| 7938 Node* context) { | 7771 Node* context) { |
| 7939 CSA_ASSERT(this, IsJSFunction(active_function)); | 7772 CSA_ASSERT(this, IsJSFunction(active_function)); |
| 7940 | 7773 |
| 7941 Label is_not_constructor(this, Label::kDeferred), out(this); | 7774 Label is_not_constructor(this, Label::kDeferred), out(this); |
| 7942 Variable result(this, MachineRepresentation::kTagged); | 7775 Variable result(this, MachineRepresentation::kTagged); |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8448 formatted.c_str(), TENURED); | 8281 formatted.c_str(), TENURED); |
| 8449 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 8282 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
| 8450 HeapConstant(string)); | 8283 HeapConstant(string)); |
| 8451 } | 8284 } |
| 8452 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 8285 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
| 8453 #endif | 8286 #endif |
| 8454 } | 8287 } |
| 8455 | 8288 |
| 8456 } // namespace internal | 8289 } // namespace internal |
| 8457 } // namespace v8 | 8290 } // namespace v8 |
| OLD | NEW |