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