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/arm64/simulator-arm64.h" | 9 #include "src/arm64/simulator-arm64.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 masm->LeaveFrame(StackFrame::INTERNAL); | 95 masm->LeaveFrame(StackFrame::INTERNAL); |
96 ASSERT(masm->has_frame()); | 96 ASSERT(masm->has_frame()); |
97 masm->set_has_frame(false); | 97 masm->set_has_frame(false); |
98 } | 98 } |
99 | 99 |
100 | 100 |
101 // ------------------------------------------------------------------------- | 101 // ------------------------------------------------------------------------- |
102 // Code generators | 102 // Code generators |
103 | 103 |
104 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( | 104 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( |
105 MacroAssembler* masm, AllocationSiteMode mode, | 105 MacroAssembler* masm, |
| 106 Register receiver, |
| 107 Register key, |
| 108 Register value, |
| 109 Register target_map, |
| 110 AllocationSiteMode mode, |
106 Label* allocation_memento_found) { | 111 Label* allocation_memento_found) { |
107 // ----------- S t a t e ------------- | 112 ASM_LOCATION( |
108 // -- x2 : receiver | 113 "ElementsTransitionGenerator::GenerateMapChangeElementsTransition"); |
109 // -- x3 : target map | 114 ASSERT(!AreAliased(receiver, key, value, target_map)); |
110 // ----------------------------------- | |
111 Register receiver = x2; | |
112 Register map = x3; | |
113 | 115 |
114 if (mode == TRACK_ALLOCATION_SITE) { | 116 if (mode == TRACK_ALLOCATION_SITE) { |
115 ASSERT(allocation_memento_found != NULL); | 117 ASSERT(allocation_memento_found != NULL); |
116 __ JumpIfJSArrayHasAllocationMemento(receiver, x10, x11, | 118 __ JumpIfJSArrayHasAllocationMemento(receiver, x10, x11, |
117 allocation_memento_found); | 119 allocation_memento_found); |
118 } | 120 } |
119 | 121 |
120 // Set transitioned map. | 122 // Set transitioned map. |
121 __ Str(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 123 __ Str(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
122 __ RecordWriteField(receiver, | 124 __ RecordWriteField(receiver, |
123 HeapObject::kMapOffset, | 125 HeapObject::kMapOffset, |
124 map, | 126 target_map, |
125 x10, | 127 x10, |
126 kLRHasNotBeenSaved, | 128 kLRHasNotBeenSaved, |
127 kDontSaveFPRegs, | 129 kDontSaveFPRegs, |
128 EMIT_REMEMBERED_SET, | 130 EMIT_REMEMBERED_SET, |
129 OMIT_SMI_CHECK); | 131 OMIT_SMI_CHECK); |
130 } | 132 } |
131 | 133 |
132 | 134 |
133 void ElementsTransitionGenerator::GenerateSmiToDouble( | 135 void ElementsTransitionGenerator::GenerateSmiToDouble( |
134 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { | 136 MacroAssembler* masm, |
| 137 Register receiver, |
| 138 Register key, |
| 139 Register value, |
| 140 Register target_map, |
| 141 AllocationSiteMode mode, |
| 142 Label* fail) { |
135 ASM_LOCATION("ElementsTransitionGenerator::GenerateSmiToDouble"); | 143 ASM_LOCATION("ElementsTransitionGenerator::GenerateSmiToDouble"); |
136 // ----------- S t a t e ------------- | 144 Label gc_required, only_change_map; |
137 // -- lr : return address | 145 Register elements = x4; |
138 // -- x0 : value | 146 Register length = x5; |
139 // -- x1 : key | 147 Register array_size = x6; |
140 // -- x2 : receiver | 148 Register array = x7; |
141 // -- x3 : target map, scratch for subsequent call | |
142 // ----------------------------------- | |
143 Register receiver = x2; | |
144 Register target_map = x3; | |
145 | 149 |
146 Label gc_required, only_change_map; | 150 Register scratch = x6; |
| 151 |
| 152 // Verify input registers don't conflict with locals. |
| 153 ASSERT(!AreAliased(receiver, key, value, target_map, |
| 154 elements, length, array_size, array)); |
147 | 155 |
148 if (mode == TRACK_ALLOCATION_SITE) { | 156 if (mode == TRACK_ALLOCATION_SITE) { |
149 __ JumpIfJSArrayHasAllocationMemento(receiver, x10, x11, fail); | 157 __ JumpIfJSArrayHasAllocationMemento(receiver, x10, x11, fail); |
150 } | 158 } |
151 | 159 |
152 // Check for empty arrays, which only require a map transition and no changes | 160 // Check for empty arrays, which only require a map transition and no changes |
153 // to the backing store. | 161 // to the backing store. |
154 Register elements = x4; | |
155 __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 162 __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
156 __ JumpIfRoot(elements, Heap::kEmptyFixedArrayRootIndex, &only_change_map); | 163 __ JumpIfRoot(elements, Heap::kEmptyFixedArrayRootIndex, &only_change_map); |
157 | 164 |
158 __ Push(lr); | 165 __ Push(lr); |
159 Register length = x5; | |
160 __ Ldrsw(length, UntagSmiFieldMemOperand(elements, | 166 __ Ldrsw(length, UntagSmiFieldMemOperand(elements, |
161 FixedArray::kLengthOffset)); | 167 FixedArray::kLengthOffset)); |
162 | 168 |
163 // Allocate new FixedDoubleArray. | 169 // Allocate new FixedDoubleArray. |
164 Register array_size = x6; | |
165 Register array = x7; | |
166 __ Lsl(array_size, length, kDoubleSizeLog2); | 170 __ Lsl(array_size, length, kDoubleSizeLog2); |
167 __ Add(array_size, array_size, FixedDoubleArray::kHeaderSize); | 171 __ Add(array_size, array_size, FixedDoubleArray::kHeaderSize); |
168 __ Allocate(array_size, array, x10, x11, &gc_required, DOUBLE_ALIGNMENT); | 172 __ Allocate(array_size, array, x10, x11, &gc_required, DOUBLE_ALIGNMENT); |
169 // Register array is non-tagged heap object. | 173 // Register array is non-tagged heap object. |
170 | 174 |
171 // Set the destination FixedDoubleArray's length and map. | 175 // Set the destination FixedDoubleArray's length and map. |
172 Register map_root = x6; | 176 Register map_root = array_size; |
173 __ LoadRoot(map_root, Heap::kFixedDoubleArrayMapRootIndex); | 177 __ LoadRoot(map_root, Heap::kFixedDoubleArrayMapRootIndex); |
174 __ SmiTag(x11, length); | 178 __ SmiTag(x11, length); |
175 __ Str(x11, MemOperand(array, FixedDoubleArray::kLengthOffset)); | 179 __ Str(x11, MemOperand(array, FixedDoubleArray::kLengthOffset)); |
176 __ Str(map_root, MemOperand(array, HeapObject::kMapOffset)); | 180 __ Str(map_root, MemOperand(array, HeapObject::kMapOffset)); |
177 | 181 |
178 __ Str(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 182 __ Str(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
179 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, x6, | 183 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch, |
180 kLRHasBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, | 184 kLRHasBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, |
181 OMIT_SMI_CHECK); | 185 OMIT_SMI_CHECK); |
182 | 186 |
183 // Replace receiver's backing store with newly created FixedDoubleArray. | 187 // Replace receiver's backing store with newly created FixedDoubleArray. |
184 __ Add(x10, array, kHeapObjectTag); | 188 __ Add(x10, array, kHeapObjectTag); |
185 __ Str(x10, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 189 __ Str(x10, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
186 __ RecordWriteField(receiver, JSObject::kElementsOffset, x10, | 190 __ RecordWriteField(receiver, JSObject::kElementsOffset, x10, |
187 x6, kLRHasBeenSaved, kDontSaveFPRegs, | 191 scratch, kLRHasBeenSaved, kDontSaveFPRegs, |
188 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 192 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
189 | 193 |
190 // Prepare for conversion loop. | 194 // Prepare for conversion loop. |
191 Register src_elements = x10; | 195 Register src_elements = x10; |
192 Register dst_elements = x11; | 196 Register dst_elements = x11; |
193 Register dst_end = x12; | 197 Register dst_end = x12; |
194 __ Add(src_elements, elements, FixedArray::kHeaderSize - kHeapObjectTag); | 198 __ Add(src_elements, elements, FixedArray::kHeaderSize - kHeapObjectTag); |
195 __ Add(dst_elements, array, FixedDoubleArray::kHeaderSize); | 199 __ Add(dst_elements, array, FixedDoubleArray::kHeaderSize); |
196 __ Add(dst_end, dst_elements, Operand(length, LSL, kDoubleSizeLog2)); | 200 __ Add(dst_end, dst_elements, Operand(length, LSL, kDoubleSizeLog2)); |
197 | 201 |
198 FPRegister nan_d = d1; | 202 FPRegister nan_d = d1; |
199 __ Fmov(nan_d, rawbits_to_double(kHoleNanInt64)); | 203 __ Fmov(nan_d, rawbits_to_double(kHoleNanInt64)); |
200 | 204 |
201 Label entry, done; | 205 Label entry, done; |
202 __ B(&entry); | 206 __ B(&entry); |
203 | 207 |
204 __ Bind(&only_change_map); | 208 __ Bind(&only_change_map); |
205 __ Str(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 209 __ Str(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
206 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, x6, | 210 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch, |
207 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, | 211 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, |
208 OMIT_SMI_CHECK); | 212 OMIT_SMI_CHECK); |
209 __ B(&done); | 213 __ B(&done); |
210 | 214 |
211 // Call into runtime if GC is required. | 215 // Call into runtime if GC is required. |
212 __ Bind(&gc_required); | 216 __ Bind(&gc_required); |
213 __ Pop(lr); | 217 __ Pop(lr); |
214 __ B(fail); | 218 __ B(fail); |
215 | 219 |
216 // Iterate over the array, copying and coverting smis to doubles. If an | 220 // Iterate over the array, copying and coverting smis to doubles. If an |
(...skipping 11 matching lines...) Expand all Loading... |
228 __ Cmp(dst_elements, dst_end); | 232 __ Cmp(dst_elements, dst_end); |
229 __ B(lt, &loop); | 233 __ B(lt, &loop); |
230 } | 234 } |
231 | 235 |
232 __ Pop(lr); | 236 __ Pop(lr); |
233 __ Bind(&done); | 237 __ Bind(&done); |
234 } | 238 } |
235 | 239 |
236 | 240 |
237 void ElementsTransitionGenerator::GenerateDoubleToObject( | 241 void ElementsTransitionGenerator::GenerateDoubleToObject( |
238 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { | 242 MacroAssembler* masm, |
| 243 Register receiver, |
| 244 Register key, |
| 245 Register value, |
| 246 Register target_map, |
| 247 AllocationSiteMode mode, |
| 248 Label* fail) { |
239 ASM_LOCATION("ElementsTransitionGenerator::GenerateDoubleToObject"); | 249 ASM_LOCATION("ElementsTransitionGenerator::GenerateDoubleToObject"); |
240 // ----------- S t a t e ------------- | 250 Register elements = x4; |
241 // -- x0 : value | 251 Register array_size = x6; |
242 // -- x1 : key | 252 Register array = x7; |
243 // -- x2 : receiver | 253 Register length = x5; |
244 // -- lr : return address | 254 |
245 // -- x3 : target map, scratch for subsequent call | 255 // Verify input registers don't conflict with locals. |
246 // -- x4 : scratch (elements) | 256 ASSERT(!AreAliased(receiver, key, value, target_map, |
247 // ----------------------------------- | 257 elements, array_size, array, length)); |
248 Register value = x0; | |
249 Register key = x1; | |
250 Register receiver = x2; | |
251 Register target_map = x3; | |
252 | 258 |
253 if (mode == TRACK_ALLOCATION_SITE) { | 259 if (mode == TRACK_ALLOCATION_SITE) { |
254 __ JumpIfJSArrayHasAllocationMemento(receiver, x10, x11, fail); | 260 __ JumpIfJSArrayHasAllocationMemento(receiver, x10, x11, fail); |
255 } | 261 } |
256 | 262 |
257 // Check for empty arrays, which only require a map transition and no changes | 263 // Check for empty arrays, which only require a map transition and no changes |
258 // to the backing store. | 264 // to the backing store. |
259 Label only_change_map; | 265 Label only_change_map; |
260 Register elements = x4; | 266 |
261 __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 267 __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
262 __ JumpIfRoot(elements, Heap::kEmptyFixedArrayRootIndex, &only_change_map); | 268 __ JumpIfRoot(elements, Heap::kEmptyFixedArrayRootIndex, &only_change_map); |
263 | 269 |
264 __ Push(lr); | 270 __ Push(lr); |
265 // TODO(all): These registers may not need to be pushed. Examine | 271 // TODO(all): These registers may not need to be pushed. Examine |
266 // RecordWriteStub and check whether it's needed. | 272 // RecordWriteStub and check whether it's needed. |
267 __ Push(target_map, receiver, key, value); | 273 __ Push(target_map, receiver, key, value); |
268 Register length = x5; | |
269 __ Ldrsw(length, UntagSmiFieldMemOperand(elements, | 274 __ Ldrsw(length, UntagSmiFieldMemOperand(elements, |
270 FixedArray::kLengthOffset)); | 275 FixedArray::kLengthOffset)); |
271 | |
272 // Allocate new FixedArray. | 276 // Allocate new FixedArray. |
273 Register array_size = x6; | |
274 Register array = x7; | |
275 Label gc_required; | 277 Label gc_required; |
276 __ Mov(array_size, FixedDoubleArray::kHeaderSize); | 278 __ Mov(array_size, FixedDoubleArray::kHeaderSize); |
277 __ Add(array_size, array_size, Operand(length, LSL, kPointerSizeLog2)); | 279 __ Add(array_size, array_size, Operand(length, LSL, kPointerSizeLog2)); |
278 __ Allocate(array_size, array, x10, x11, &gc_required, NO_ALLOCATION_FLAGS); | 280 __ Allocate(array_size, array, x10, x11, &gc_required, NO_ALLOCATION_FLAGS); |
279 | 281 |
280 // Set destination FixedDoubleArray's length and map. | 282 // Set destination FixedDoubleArray's length and map. |
281 Register map_root = x6; | 283 Register map_root = array_size; |
282 __ LoadRoot(map_root, Heap::kFixedArrayMapRootIndex); | 284 __ LoadRoot(map_root, Heap::kFixedArrayMapRootIndex); |
283 __ SmiTag(x11, length); | 285 __ SmiTag(x11, length); |
284 __ Str(x11, MemOperand(array, FixedDoubleArray::kLengthOffset)); | 286 __ Str(x11, MemOperand(array, FixedDoubleArray::kLengthOffset)); |
285 __ Str(map_root, MemOperand(array, HeapObject::kMapOffset)); | 287 __ Str(map_root, MemOperand(array, HeapObject::kMapOffset)); |
286 | 288 |
287 // Prepare for conversion loop. | 289 // Prepare for conversion loop. |
288 Register src_elements = x10; | 290 Register src_elements = x10; |
289 Register dst_elements = x11; | 291 Register dst_elements = x11; |
290 Register dst_end = x12; | 292 Register dst_end = x12; |
291 __ Add(src_elements, elements, | 293 __ Add(src_elements, elements, |
(...skipping 17 matching lines...) Expand all Loading... |
309 __ B(fail); | 311 __ B(fail); |
310 | 312 |
311 { | 313 { |
312 Label loop, convert_hole; | 314 Label loop, convert_hole; |
313 __ Bind(&loop); | 315 __ Bind(&loop); |
314 __ Ldr(x13, MemOperand(src_elements, kPointerSize, PostIndex)); | 316 __ Ldr(x13, MemOperand(src_elements, kPointerSize, PostIndex)); |
315 __ Cmp(x13, kHoleNanInt64); | 317 __ Cmp(x13, kHoleNanInt64); |
316 __ B(eq, &convert_hole); | 318 __ B(eq, &convert_hole); |
317 | 319 |
318 // Non-hole double, copy value into a heap number. | 320 // Non-hole double, copy value into a heap number. |
319 Register heap_num = x5; | 321 Register heap_num = length; |
320 __ AllocateHeapNumber(heap_num, &gc_required, x6, x4, | 322 Register scratch = array_size; |
| 323 Register scratch2 = elements; |
| 324 __ AllocateHeapNumber(heap_num, &gc_required, scratch, scratch2, |
321 x13, heap_num_map); | 325 x13, heap_num_map); |
322 __ Mov(x13, dst_elements); | 326 __ Mov(x13, dst_elements); |
323 __ Str(heap_num, MemOperand(dst_elements, kPointerSize, PostIndex)); | 327 __ Str(heap_num, MemOperand(dst_elements, kPointerSize, PostIndex)); |
324 __ RecordWrite(array, x13, heap_num, kLRHasBeenSaved, kDontSaveFPRegs, | 328 __ RecordWrite(array, x13, heap_num, kLRHasBeenSaved, kDontSaveFPRegs, |
325 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 329 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
326 | 330 |
327 __ B(&entry); | 331 __ B(&entry); |
328 | 332 |
329 // Replace the-hole NaN with the-hole pointer. | 333 // Replace the-hole NaN with the-hole pointer. |
330 __ Bind(&convert_hole); | 334 __ Bind(&convert_hole); |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 __ Fmul(result, double_temp3, double_temp1); | 616 __ Fmul(result, double_temp3, double_temp1); |
613 | 617 |
614 __ Bind(&done); | 618 __ Bind(&done); |
615 } | 619 } |
616 | 620 |
617 #undef __ | 621 #undef __ |
618 | 622 |
619 } } // namespace v8::internal | 623 } } // namespace v8::internal |
620 | 624 |
621 #endif // V8_TARGET_ARCH_ARM64 | 625 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |