| 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/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 3055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3066 DCHECK(csp.Is(__ StackPointer())); | 3066 DCHECK(csp.Is(__ StackPointer())); |
| 3067 | 3067 |
| 3068 intptr_t code = | 3068 intptr_t code = |
| 3069 reinterpret_cast<intptr_t>(GetCode().location()); | 3069 reinterpret_cast<intptr_t>(GetCode().location()); |
| 3070 __ Mov(lr, Operand(code, RelocInfo::CODE_TARGET)); | 3070 __ Mov(lr, Operand(code, RelocInfo::CODE_TARGET)); |
| 3071 __ Mov(x10, target); | 3071 __ Mov(x10, target); |
| 3072 // Branch to the stub. | 3072 // Branch to the stub. |
| 3073 __ Blr(lr); | 3073 __ Blr(lr); |
| 3074 } | 3074 } |
| 3075 | 3075 |
| 3076 | |
| 3077 // Probe the name dictionary in the 'elements' register. | |
| 3078 // Jump to the 'done' label if a property with the given name is found. | |
| 3079 // Jump to the 'miss' label otherwise. | |
| 3080 // | |
| 3081 // If lookup was successful 'scratch2' will be equal to elements + 4 * index. | |
| 3082 // 'elements' and 'name' registers are preserved on miss. | |
| 3083 void NameDictionaryLookupStub::GeneratePositiveLookup( | |
| 3084 MacroAssembler* masm, | |
| 3085 Label* miss, | |
| 3086 Label* done, | |
| 3087 Register elements, | |
| 3088 Register name, | |
| 3089 Register scratch1, | |
| 3090 Register scratch2) { | |
| 3091 DCHECK(!AreAliased(elements, name, scratch1, scratch2)); | |
| 3092 | |
| 3093 // Assert that name contains a string. | |
| 3094 __ AssertName(name); | |
| 3095 | |
| 3096 // Compute the capacity mask. | |
| 3097 __ Ldrsw(scratch1, UntagSmiFieldMemOperand(elements, kCapacityOffset)); | |
| 3098 __ Sub(scratch1, scratch1, 1); | |
| 3099 | |
| 3100 // Generate an unrolled loop that performs a few probes before giving up. | |
| 3101 for (int i = 0; i < kInlinedProbes; i++) { | |
| 3102 // Compute the masked index: (hash + i + i * i) & mask. | |
| 3103 __ Ldr(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); | |
| 3104 if (i > 0) { | |
| 3105 // Add the probe offset (i + i * i) left shifted to avoid right shifting | |
| 3106 // the hash in a separate instruction. The value hash + i + i * i is right | |
| 3107 // shifted in the following and instruction. | |
| 3108 DCHECK(NameDictionary::GetProbeOffset(i) < | |
| 3109 1 << (32 - Name::kHashFieldOffset)); | |
| 3110 __ Add(scratch2, scratch2, Operand( | |
| 3111 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); | |
| 3112 } | |
| 3113 __ And(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); | |
| 3114 | |
| 3115 // Scale the index by multiplying by the element size. | |
| 3116 STATIC_ASSERT(NameDictionary::kEntrySize == 3); | |
| 3117 __ Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); | |
| 3118 | |
| 3119 // Check if the key is identical to the name. | |
| 3120 UseScratchRegisterScope temps(masm); | |
| 3121 Register scratch3 = temps.AcquireX(); | |
| 3122 __ Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); | |
| 3123 __ Ldr(scratch3, FieldMemOperand(scratch2, kElementsStartOffset)); | |
| 3124 __ Cmp(name, scratch3); | |
| 3125 __ B(eq, done); | |
| 3126 } | |
| 3127 | |
| 3128 // The inlined probes didn't find the entry. | |
| 3129 // Call the complete stub to scan the whole dictionary. | |
| 3130 | |
| 3131 CPURegList spill_list(CPURegister::kRegister, kXRegSizeInBits, 0, 6); | |
| 3132 spill_list.Combine(lr); | |
| 3133 spill_list.Remove(scratch1); | |
| 3134 spill_list.Remove(scratch2); | |
| 3135 | |
| 3136 __ PushCPURegList(spill_list); | |
| 3137 | |
| 3138 if (name.is(x0)) { | |
| 3139 DCHECK(!elements.is(x1)); | |
| 3140 __ Mov(x1, name); | |
| 3141 __ Mov(x0, elements); | |
| 3142 } else { | |
| 3143 __ Mov(x0, elements); | |
| 3144 __ Mov(x1, name); | |
| 3145 } | |
| 3146 | |
| 3147 Label not_found; | |
| 3148 NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); | |
| 3149 __ CallStub(&stub); | |
| 3150 __ Cbz(x0, ¬_found); | |
| 3151 __ Mov(scratch2, x2); // Move entry index into scratch2. | |
| 3152 __ PopCPURegList(spill_list); | |
| 3153 __ B(done); | |
| 3154 | |
| 3155 __ Bind(¬_found); | |
| 3156 __ PopCPURegList(spill_list); | |
| 3157 __ B(miss); | |
| 3158 } | |
| 3159 | |
| 3160 | |
| 3161 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, | 3076 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, |
| 3162 Label* miss, | 3077 Label* miss, |
| 3163 Label* done, | 3078 Label* done, |
| 3164 Register receiver, | 3079 Register receiver, |
| 3165 Register properties, | 3080 Register properties, |
| 3166 Handle<Name> name, | 3081 Handle<Name> name, |
| 3167 Register scratch0) { | 3082 Register scratch0) { |
| 3168 DCHECK(!AreAliased(receiver, properties, scratch0)); | 3083 DCHECK(!AreAliased(receiver, properties, scratch0)); |
| 3169 DCHECK(name->IsUniqueName()); | 3084 DCHECK(name->IsUniqueName()); |
| 3170 // If names of slots in range from 1 to kProbes - 1 for the hash value are | 3085 // If names of slots in range from 1 to kProbes - 1 for the hash value are |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4555 kStackUnwindSpace, NULL, spill_offset, | 4470 kStackUnwindSpace, NULL, spill_offset, |
| 4556 return_value_operand, NULL); | 4471 return_value_operand, NULL); |
| 4557 } | 4472 } |
| 4558 | 4473 |
| 4559 #undef __ | 4474 #undef __ |
| 4560 | 4475 |
| 4561 } // namespace internal | 4476 } // namespace internal |
| 4562 } // namespace v8 | 4477 } // namespace v8 |
| 4563 | 4478 |
| 4564 #endif // V8_TARGET_ARCH_ARM64 | 4479 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |