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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 3701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3712 } else if (if_all_clear == fall_through) { | 3712 } else if (if_all_clear == fall_through) { |
3713 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); | 3713 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); |
3714 } else if (if_any_set == fall_through) { | 3714 } else if (if_any_set == fall_through) { |
3715 TestAndBranchIfAllClear(reg, bit_pattern, if_all_clear); | 3715 TestAndBranchIfAllClear(reg, bit_pattern, if_all_clear); |
3716 } else { | 3716 } else { |
3717 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); | 3717 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); |
3718 B(if_all_clear); | 3718 B(if_all_clear); |
3719 } | 3719 } |
3720 } | 3720 } |
3721 | 3721 |
3722 | |
3723 void MacroAssembler::CheckFastElements(Register map, | |
3724 Register scratch, | |
3725 Label* fail) { | |
3726 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
3727 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
3728 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
3729 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
3730 Ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | |
3731 Cmp(scratch, Map::kMaximumBitField2FastHoleyElementValue); | |
3732 B(hi, fail); | |
3733 } | |
3734 | |
3735 | |
3736 void MacroAssembler::CheckFastObjectElements(Register map, | 3722 void MacroAssembler::CheckFastObjectElements(Register map, |
3737 Register scratch, | 3723 Register scratch, |
3738 Label* fail) { | 3724 Label* fail) { |
3739 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 3725 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
3740 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 3726 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
3741 STATIC_ASSERT(FAST_ELEMENTS == 2); | 3727 STATIC_ASSERT(FAST_ELEMENTS == 2); |
3742 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 3728 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
3743 Ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | 3729 Ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); |
3744 Cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | 3730 Cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); |
3745 // If cond==ls, set cond=hi, otherwise compare. | 3731 // If cond==ls, set cond=hi, otherwise compare. |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3937 Eor(key, key, Operand(key, LSR, 4)); | 3923 Eor(key, key, Operand(key, LSR, 4)); |
3938 // hash = hash * 2057; | 3924 // hash = hash * 2057; |
3939 Mov(scratch, Operand(key, LSL, 11)); | 3925 Mov(scratch, Operand(key, LSL, 11)); |
3940 Add(key, key, Operand(key, LSL, 3)); | 3926 Add(key, key, Operand(key, LSL, 3)); |
3941 Add(key, key, scratch); | 3927 Add(key, key, scratch); |
3942 // hash = hash ^ (hash >> 16); | 3928 // hash = hash ^ (hash >> 16); |
3943 Eor(key, key, Operand(key, LSR, 16)); | 3929 Eor(key, key, Operand(key, LSR, 16)); |
3944 Bic(key, key, Operand(0xc0000000u)); | 3930 Bic(key, key, Operand(0xc0000000u)); |
3945 } | 3931 } |
3946 | 3932 |
3947 | |
3948 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | |
3949 Register elements, | |
3950 Register key, | |
3951 Register result, | |
3952 Register scratch0, | |
3953 Register scratch1, | |
3954 Register scratch2, | |
3955 Register scratch3) { | |
3956 DCHECK(!AreAliased(elements, key, scratch0, scratch1, scratch2, scratch3)); | |
3957 | |
3958 Label done; | |
3959 | |
3960 SmiUntag(scratch0, key); | |
3961 GetNumberHash(scratch0, scratch1); | |
3962 | |
3963 // Compute the capacity mask. | |
3964 Ldrsw(scratch1, | |
3965 UntagSmiFieldMemOperand(elements, | |
3966 SeededNumberDictionary::kCapacityOffset)); | |
3967 Sub(scratch1, scratch1, 1); | |
3968 | |
3969 // Generate an unrolled loop that performs a few probes before giving up. | |
3970 for (int i = 0; i < kNumberDictionaryProbes; i++) { | |
3971 // Compute the masked index: (hash + i + i * i) & mask. | |
3972 if (i > 0) { | |
3973 Add(scratch2, scratch0, SeededNumberDictionary::GetProbeOffset(i)); | |
3974 } else { | |
3975 Mov(scratch2, scratch0); | |
3976 } | |
3977 And(scratch2, scratch2, scratch1); | |
3978 | |
3979 // Scale the index by multiplying by the element size. | |
3980 DCHECK(SeededNumberDictionary::kEntrySize == 3); | |
3981 Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); | |
3982 | |
3983 // Check if the key is identical to the name. | |
3984 Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); | |
3985 Ldr(scratch3, | |
3986 FieldMemOperand(scratch2, | |
3987 SeededNumberDictionary::kElementsStartOffset)); | |
3988 Cmp(key, scratch3); | |
3989 if (i != (kNumberDictionaryProbes - 1)) { | |
3990 B(eq, &done); | |
3991 } else { | |
3992 B(ne, miss); | |
3993 } | |
3994 } | |
3995 | |
3996 Bind(&done); | |
3997 // Check that the value is a field property. | |
3998 const int kDetailsOffset = | |
3999 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; | |
4000 Ldrsw(scratch1, UntagSmiFieldMemOperand(scratch2, kDetailsOffset)); | |
4001 DCHECK_EQ(DATA, 0); | |
4002 TestAndBranchIfAnySet(scratch1, PropertyDetails::TypeField::kMask, miss); | |
4003 | |
4004 // Get the value at the masked, scaled index and return. | |
4005 const int kValueOffset = | |
4006 SeededNumberDictionary::kElementsStartOffset + kPointerSize; | |
4007 Ldr(result, FieldMemOperand(scratch2, kValueOffset)); | |
4008 } | |
4009 | |
4010 void MacroAssembler::RecordWriteCodeEntryField(Register js_function, | 3933 void MacroAssembler::RecordWriteCodeEntryField(Register js_function, |
4011 Register code_entry, | 3934 Register code_entry, |
4012 Register scratch) { | 3935 Register scratch) { |
4013 const int offset = JSFunction::kCodeEntryOffset; | 3936 const int offset = JSFunction::kCodeEntryOffset; |
4014 | 3937 |
4015 // Since a code entry (value) is always in old space, we don't need to update | 3938 // Since a code entry (value) is always in old space, we don't need to update |
4016 // remembered set. If incremental marking is off, there is nothing for us to | 3939 // remembered set. If incremental marking is off, there is nothing for us to |
4017 // do. | 3940 // do. |
4018 if (!FLAG_incremental_marking) return; | 3941 if (!FLAG_incremental_marking) return; |
4019 | 3942 |
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5152 } | 5075 } |
5153 | 5076 |
5154 | 5077 |
5155 #undef __ | 5078 #undef __ |
5156 | 5079 |
5157 | 5080 |
5158 } // namespace internal | 5081 } // namespace internal |
5159 } // namespace v8 | 5082 } // namespace v8 |
5160 | 5083 |
5161 #endif // V8_TARGET_ARCH_ARM64 | 5084 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |