OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, | 791 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, |
792 receiver_map, x10, x11, slow); | 792 receiver_map, x10, x11, slow); |
793 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); | 793 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); |
794 ElementsTransitionGenerator::GenerateDoubleToObject( | 794 ElementsTransitionGenerator::GenerateDoubleToObject( |
795 masm, receiver, key, value, receiver_map, mode, slow); | 795 masm, receiver, key, value, receiver_map, mode, slow); |
796 __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 796 __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
797 __ B(&finish_store); | 797 __ B(&finish_store); |
798 } | 798 } |
799 | 799 |
800 | 800 |
801 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 801 void KeyedStoreIC::GenerateGeneric( |
802 StrictMode strict_mode) { | 802 MacroAssembler* masm, StrictMode strict_mode, |
| 803 KeyedStoreStubCacheRequirement handler_requirement) { |
803 ASM_LOCATION("KeyedStoreIC::GenerateGeneric"); | 804 ASM_LOCATION("KeyedStoreIC::GenerateGeneric"); |
804 Label slow; | 805 Label slow; |
805 Label array; | 806 Label array; |
806 Label fast_object; | 807 Label fast_object; |
807 Label extra; | 808 Label extra; |
808 Label fast_object_grow; | 809 Label fast_object_grow; |
809 Label fast_double_grow; | 810 Label fast_double_grow; |
810 Label fast_double; | 811 Label fast_double; |
| 812 Label maybe_name_key; |
| 813 Label miss; |
811 | 814 |
812 Register value = StoreDescriptor::ValueRegister(); | 815 Register value = StoreDescriptor::ValueRegister(); |
813 Register key = StoreDescriptor::NameRegister(); | 816 Register key = StoreDescriptor::NameRegister(); |
814 Register receiver = StoreDescriptor::ReceiverRegister(); | 817 Register receiver = StoreDescriptor::ReceiverRegister(); |
815 DCHECK(receiver.is(x1)); | 818 DCHECK(receiver.is(x1)); |
816 DCHECK(key.is(x2)); | 819 DCHECK(key.is(x2)); |
817 DCHECK(value.is(x0)); | 820 DCHECK(value.is(x0)); |
818 | 821 |
819 Register receiver_map = x3; | 822 Register receiver_map = x3; |
820 Register elements = x4; | 823 Register elements = x4; |
821 Register elements_map = x5; | 824 Register elements_map = x5; |
822 | 825 |
823 __ JumpIfNotSmi(key, &slow); | 826 __ JumpIfNotSmi(key, &maybe_name_key); |
824 __ JumpIfSmi(receiver, &slow); | 827 __ JumpIfSmi(receiver, &slow); |
825 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 828 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
826 | 829 |
827 // Check that the receiver does not require access checks and is not observed. | 830 // Check that the receiver does not require access checks and is not observed. |
828 // The generic stub does not perform map checks or handle observed objects. | 831 // The generic stub does not perform map checks or handle observed objects. |
829 __ Ldrb(x10, FieldMemOperand(receiver_map, Map::kBitFieldOffset)); | 832 __ Ldrb(x10, FieldMemOperand(receiver_map, Map::kBitFieldOffset)); |
830 __ TestAndBranchIfAnySet( | 833 __ TestAndBranchIfAnySet( |
831 x10, (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kIsObserved), &slow); | 834 x10, (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kIsObserved), &slow); |
832 | 835 |
833 // Check if the object is a JS array or not. | 836 // Check if the object is a JS array or not. |
(...skipping 12 matching lines...) Expand all Loading... |
846 __ B(hi, &fast_object); | 849 __ B(hi, &fast_object); |
847 | 850 |
848 | 851 |
849 __ Bind(&slow); | 852 __ Bind(&slow); |
850 // Slow case, handle jump to runtime. | 853 // Slow case, handle jump to runtime. |
851 // Live values: | 854 // Live values: |
852 // x0: value | 855 // x0: value |
853 // x1: key | 856 // x1: key |
854 // x2: receiver | 857 // x2: receiver |
855 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); | 858 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); |
| 859 // Never returns to here. |
856 | 860 |
| 861 __ bind(&maybe_name_key); |
| 862 __ Ldr(x10, FieldMemOperand(key, HeapObject::kMapOffset)); |
| 863 __ Ldrb(x10, FieldMemOperand(x10, Map::kInstanceTypeOffset)); |
| 864 __ JumpIfNotUniqueNameInstanceType(x10, &slow); |
| 865 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 866 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 867 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, |
| 868 key, x3, x4, x5, x6); |
| 869 // Cache miss. |
| 870 if (handler_requirement == kCallRuntimeOnMissingHandler) { |
| 871 __ B(&slow); |
| 872 } else { |
| 873 DCHECK(handler_requirement == kMissOnMissingHandler); |
| 874 __ B(&miss); |
| 875 } |
857 | 876 |
858 __ Bind(&extra); | 877 __ Bind(&extra); |
859 // Extra capacity case: Check if there is extra capacity to | 878 // Extra capacity case: Check if there is extra capacity to |
860 // perform the store and update the length. Used for adding one | 879 // perform the store and update the length. Used for adding one |
861 // element to the array by writing to array[array.length]. | 880 // element to the array by writing to array[array.length]. |
862 | 881 |
863 // Check for room in the elements backing store. | 882 // Check for room in the elements backing store. |
864 // Both the key and the length of FixedArray are smis. | 883 // Both the key and the length of FixedArray are smis. |
865 __ Ldrsw(x10, UntagSmiFieldMemOperand(elements, FixedArray::kLengthOffset)); | 884 __ Ldrsw(x10, UntagSmiFieldMemOperand(elements, FixedArray::kLengthOffset)); |
866 __ Cmp(x10, Operand::UntagSmi(key)); | 885 __ Cmp(x10, Operand::UntagSmi(key)); |
(...skipping 21 matching lines...) Expand all Loading... |
888 __ B(eq, &extra); // We can handle the case where we are appending 1 element. | 907 __ B(eq, &extra); // We can handle the case where we are appending 1 element. |
889 __ B(lo, &slow); | 908 __ B(lo, &slow); |
890 | 909 |
891 KeyedStoreGenerateGenericHelper( | 910 KeyedStoreGenerateGenericHelper( |
892 masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength, | 911 masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength, |
893 value, key, receiver, receiver_map, elements_map, elements); | 912 value, key, receiver, receiver_map, elements_map, elements); |
894 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 913 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
895 &slow, kDontCheckMap, kIncrementLength, value, | 914 &slow, kDontCheckMap, kIncrementLength, value, |
896 key, receiver, receiver_map, elements_map, | 915 key, receiver, receiver_map, elements_map, |
897 elements); | 916 elements); |
| 917 |
| 918 if (handler_requirement == kMissOnMissingHandler) { |
| 919 __ bind(&miss); |
| 920 GenerateMiss(masm); |
| 921 } |
898 } | 922 } |
899 | 923 |
900 | 924 |
901 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 925 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
902 Register receiver = StoreDescriptor::ReceiverRegister(); | 926 Register receiver = StoreDescriptor::ReceiverRegister(); |
903 Register name = StoreDescriptor::NameRegister(); | 927 Register name = StoreDescriptor::NameRegister(); |
904 DCHECK(!AreAliased(receiver, name, StoreDescriptor::ValueRegister(), x3, x4, | 928 DCHECK(!AreAliased(receiver, name, StoreDescriptor::ValueRegister(), x3, x4, |
905 x5, x6)); | 929 x5, x6)); |
906 | 930 |
907 // Probe the stub cache. | 931 // Probe the stub cache. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 } else { | 1054 } else { |
1031 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); | 1055 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); |
1032 // This is JumpIfSmi(smi_reg, branch_imm). | 1056 // This is JumpIfSmi(smi_reg, branch_imm). |
1033 patcher.tbz(smi_reg, 0, branch_imm); | 1057 patcher.tbz(smi_reg, 0, branch_imm); |
1034 } | 1058 } |
1035 } | 1059 } |
1036 } | 1060 } |
1037 } // namespace v8::internal | 1061 } // namespace v8::internal |
1038 | 1062 |
1039 #endif // V8_TARGET_ARCH_ARM64 | 1063 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |