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 |