OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 } | 886 } |
887 | 887 |
888 | 888 |
889 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { | 889 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { |
890 // ----------- S t a t e ------------- | 890 // ----------- S t a t e ------------- |
891 // -- rax : value | 891 // -- rax : value |
892 // -- rcx : key | 892 // -- rcx : key |
893 // -- rdx : receiver | 893 // -- rdx : receiver |
894 // -- rsp[0] : return address | 894 // -- rsp[0] : return address |
895 // ----------------------------------- | 895 // ----------------------------------- |
896 Label slow, fast, array, extra, check_pixel_array; | 896 Label slow, slow_with_tagged_index, fast, array, extra, check_pixel_array; |
897 | 897 |
898 // Check that the object isn't a smi. | 898 // Check that the object isn't a smi. |
899 __ JumpIfSmi(rdx, &slow); | 899 __ JumpIfSmi(rdx, &slow_with_tagged_index); |
900 // Get the map from the receiver. | 900 // Get the map from the receiver. |
901 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); | 901 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); |
902 // Check that the receiver does not require access checks. We need | 902 // Check that the receiver does not require access checks. We need |
903 // to do this because this generic stub does not perform map checks. | 903 // to do this because this generic stub does not perform map checks. |
904 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), | 904 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), |
905 Immediate(1 << Map::kIsAccessCheckNeeded)); | 905 Immediate(1 << Map::kIsAccessCheckNeeded)); |
906 __ j(not_zero, &slow); | 906 __ j(not_zero, &slow_with_tagged_index); |
907 // Check that the key is a smi. | 907 // Check that the key is a smi. |
908 __ JumpIfNotSmi(rcx, &slow); | 908 __ JumpIfNotSmi(rcx, &slow_with_tagged_index); |
| 909 __ SmiToInteger32(rcx, rcx); |
909 | 910 |
910 __ CmpInstanceType(rbx, JS_ARRAY_TYPE); | 911 __ CmpInstanceType(rbx, JS_ARRAY_TYPE); |
911 __ j(equal, &array); | 912 __ j(equal, &array); |
912 // Check that the object is some kind of JS object. | 913 // Check that the object is some kind of JS object. |
913 __ CmpInstanceType(rbx, FIRST_JS_OBJECT_TYPE); | 914 __ CmpInstanceType(rbx, FIRST_JS_OBJECT_TYPE); |
914 __ j(below, &slow); | 915 __ j(below, &slow); |
915 | 916 |
916 // Object case: Check key against length in the elements array. | 917 // Object case: Check key against length in the elements array. |
917 // rax: value | 918 // rax: value |
918 // rdx: JSObject | 919 // rdx: JSObject |
919 // rcx: index (as a smi) | 920 // rcx: index |
920 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 921 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
921 // Check that the object is in fast mode (not dictionary). | 922 // Check that the object is in fast mode (not dictionary). |
922 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 923 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
923 Heap::kFixedArrayMapRootIndex); | 924 Heap::kFixedArrayMapRootIndex); |
924 __ j(not_equal, &check_pixel_array); | 925 __ j(not_equal, &check_pixel_array); |
925 __ SmiCompare(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); | 926 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); |
926 // rax: value | 927 // rax: value |
927 // rbx: FixedArray | 928 // rbx: FixedArray |
928 // rcx: index (as a smi) | 929 // rcx: index |
929 __ j(below, &fast); | 930 __ j(above, &fast); |
930 | 931 |
931 // Slow case: call runtime. | 932 // Slow case: call runtime. |
932 __ bind(&slow); | 933 __ bind(&slow); |
| 934 __ Integer32ToSmi(rcx, rcx); |
| 935 __ bind(&slow_with_tagged_index); |
933 GenerateRuntimeSetProperty(masm); | 936 GenerateRuntimeSetProperty(masm); |
| 937 // Never returns to here. |
934 | 938 |
935 // Check whether the elements is a pixel array. | 939 // Check whether the elements is a pixel array. |
936 // rax: value | 940 // rax: value |
937 // rdx: receiver | 941 // rdx: receiver |
938 // rbx: receiver's elements array | 942 // rbx: receiver's elements array |
939 // rcx: index (as a smi), zero-extended. | 943 // rcx: index, zero-extended. |
940 __ bind(&check_pixel_array); | 944 __ bind(&check_pixel_array); |
941 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 945 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
942 Heap::kPixelArrayMapRootIndex); | 946 Heap::kPixelArrayMapRootIndex); |
943 __ j(not_equal, &slow); | 947 __ j(not_equal, &slow); |
944 // Check that the value is a smi. If a conversion is needed call into the | 948 // Check that the value is a smi. If a conversion is needed call into the |
945 // runtime to convert and clamp. | 949 // runtime to convert and clamp. |
946 __ JumpIfNotSmi(rax, &slow); | 950 __ JumpIfNotSmi(rax, &slow); |
947 __ SmiToInteger32(rdi, rcx); | 951 __ cmpl(rcx, FieldOperand(rbx, PixelArray::kLengthOffset)); |
948 __ cmpl(rdi, FieldOperand(rbx, PixelArray::kLengthOffset)); | |
949 __ j(above_equal, &slow); | 952 __ j(above_equal, &slow); |
950 // No more bailouts to slow case on this path, so key not needed. | 953 // No more bailouts to slow case on this path, so key not needed. |
951 __ SmiToInteger32(rcx, rax); | 954 __ SmiToInteger32(rdi, rax); |
952 { // Clamp the value to [0..255]. | 955 { // Clamp the value to [0..255]. |
953 Label done; | 956 Label done; |
954 __ testl(rcx, Immediate(0xFFFFFF00)); | 957 __ testl(rdi, Immediate(0xFFFFFF00)); |
955 __ j(zero, &done); | 958 __ j(zero, &done); |
956 __ setcc(negative, rcx); // 1 if negative, 0 if positive. | 959 __ setcc(negative, rdi); // 1 if negative, 0 if positive. |
957 __ decb(rcx); // 0 if negative, 255 if positive. | 960 __ decb(rdi); // 0 if negative, 255 if positive. |
958 __ bind(&done); | 961 __ bind(&done); |
959 } | 962 } |
960 __ movq(rbx, FieldOperand(rbx, PixelArray::kExternalPointerOffset)); | 963 __ movq(rbx, FieldOperand(rbx, PixelArray::kExternalPointerOffset)); |
961 __ movb(Operand(rbx, rdi, times_1, 0), rcx); | 964 __ movb(Operand(rbx, rcx, times_1, 0), rdi); |
962 __ ret(0); | 965 __ ret(0); |
963 | 966 |
964 // Extra capacity case: Check if there is extra capacity to | 967 // Extra capacity case: Check if there is extra capacity to |
965 // perform the store and update the length. Used for adding one | 968 // perform the store and update the length. Used for adding one |
966 // element to the array by writing to array[array.length]. | 969 // element to the array by writing to array[array.length]. |
967 __ bind(&extra); | 970 __ bind(&extra); |
968 // rax: value | 971 // rax: value |
969 // rdx: receiver (a JSArray) | 972 // rdx: receiver (a JSArray) |
970 // rbx: receiver's elements array (a FixedArray) | 973 // rbx: receiver's elements array (a FixedArray) |
971 // rcx: index (as a smi) | 974 // rcx: index |
972 // flags: smicompare (rdx.length(), rbx) | 975 // flags: smicompare (rdx.length(), rbx) |
973 __ j(not_equal, &slow); // do not leave holes in the array | 976 __ j(not_equal, &slow); // do not leave holes in the array |
974 __ SmiCompare(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); | 977 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); |
975 __ j(above_equal, &slow); | 978 __ j(below_equal, &slow); |
976 // Increment index to get new length. | 979 // Increment index to get new length. |
977 __ SmiAddConstant(rdi, rcx, Smi::FromInt(1)); | 980 __ leal(rdi, Operand(rcx, 1)); |
978 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rdi); | 981 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi); |
979 __ jmp(&fast); | 982 __ jmp(&fast); |
980 | 983 |
981 // Array case: Get the length and the elements array from the JS | 984 // Array case: Get the length and the elements array from the JS |
982 // array. Check that the array is in fast mode; if it is the | 985 // array. Check that the array is in fast mode; if it is the |
983 // length is always a smi. | 986 // length is always a smi. |
984 __ bind(&array); | 987 __ bind(&array); |
985 // rax: value | 988 // rax: value |
986 // rdx: receiver (a JSArray) | 989 // rdx: receiver (a JSArray) |
987 // rcx: index (as a smi) | 990 // rcx: index |
988 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 991 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
989 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 992 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
990 Heap::kFixedArrayMapRootIndex); | 993 Heap::kFixedArrayMapRootIndex); |
991 __ j(not_equal, &slow); | 994 __ j(not_equal, &slow); |
992 | 995 |
993 // Check the key against the length in the array, compute the | 996 // Check the key against the length in the array, compute the |
994 // address to store into and fall through to fast case. | 997 // address to store into and fall through to fast case. |
995 __ SmiCompare(FieldOperand(rdx, JSArray::kLengthOffset), rcx); | 998 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); |
996 __ j(below_equal, &extra); | 999 __ j(below_equal, &extra); |
997 | 1000 |
998 // Fast case: Do the store. | 1001 // Fast case: Do the store. |
999 __ bind(&fast); | 1002 __ bind(&fast); |
1000 // rax: value | 1003 // rax: value |
1001 // rbx: receiver's elements array (a FixedArray) | 1004 // rbx: receiver's elements array (a FixedArray) |
1002 // rcx: index (as a smi) | 1005 // rcx: index |
1003 Label non_smi_value; | 1006 Label non_smi_value; |
| 1007 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize), |
| 1008 rax); |
1004 __ JumpIfNotSmi(rax, &non_smi_value); | 1009 __ JumpIfNotSmi(rax, &non_smi_value); |
1005 SmiIndex index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2); | |
1006 __ movq(FieldOperand(rbx, index.reg, index.scale, FixedArray::kHeaderSize), | |
1007 rax); | |
1008 __ ret(0); | 1010 __ ret(0); |
1009 __ bind(&non_smi_value); | 1011 __ bind(&non_smi_value); |
1010 // Slow case that needs to retain rcx for use by RecordWrite. | 1012 // Slow case that needs to retain rcx for use by RecordWrite. |
1011 // Update write barrier for the elements array address. | 1013 // Update write barrier for the elements array address. |
1012 SmiIndex index2 = masm->SmiToIndex(kScratchRegister, rcx, kPointerSizeLog2); | |
1013 __ movq(FieldOperand(rbx, index2.reg, index2.scale, FixedArray::kHeaderSize), | |
1014 rax); | |
1015 __ movq(rdx, rax); | 1014 __ movq(rdx, rax); |
1016 __ SmiToInteger32(rcx, rcx); | |
1017 __ RecordWriteNonSmi(rbx, 0, rdx, rcx); | 1015 __ RecordWriteNonSmi(rbx, 0, rdx, rcx); |
1018 __ ret(0); | 1016 __ ret(0); |
1019 } | 1017 } |
1020 | 1018 |
1021 | 1019 |
1022 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, | 1020 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, |
1023 ExternalArrayType array_type) { | 1021 ExternalArrayType array_type) { |
1024 // ----------- S t a t e ------------- | 1022 // ----------- S t a t e ------------- |
1025 // -- rax : value | 1023 // -- rax : value |
1026 // -- rcx : key | 1024 // -- rcx : key |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 GenerateMiss(masm); | 1851 GenerateMiss(masm); |
1854 } | 1852 } |
1855 | 1853 |
1856 | 1854 |
1857 #undef __ | 1855 #undef __ |
1858 | 1856 |
1859 | 1857 |
1860 } } // namespace v8::internal | 1858 } } // namespace v8::internal |
1861 | 1859 |
1862 #endif // V8_TARGET_ARCH_X64 | 1860 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |