| 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 |