OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( | 83 void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( |
84 MacroAssembler* masm, Label* fail) { | 84 MacroAssembler* masm, Label* fail) { |
85 // ----------- S t a t e ------------- | 85 // ----------- S t a t e ------------- |
86 // -- r0 : value | 86 // -- r0 : value |
87 // -- r1 : key | 87 // -- r1 : key |
88 // -- r2 : receiver | 88 // -- r2 : receiver |
89 // -- lr : return address | 89 // -- lr : return address |
90 // -- r3 : target map, scratch for subsequent call | 90 // -- r3 : target map, scratch for subsequent call |
91 // -- r4 : scratch (elements) | 91 // -- r4 : scratch (elements) |
92 // ----------------------------------- | 92 // ----------------------------------- |
93 Label loop, entry, convert_hole, gc_required; | 93 Label loop, entry, convert_hole, gc_required, only_change_map, done; |
94 bool vfp3_supported = CpuFeatures::IsSupported(VFP3); | 94 bool vfp3_supported = CpuFeatures::IsSupported(VFP3); |
| 95 |
| 96 // Check for empty arrays, which only require a map transition and no changes |
| 97 // to the backing store. |
| 98 __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); |
| 99 __ CompareRoot(r4, Heap::kEmptyFixedArrayRootIndex); |
| 100 __ b(eq, &only_change_map); |
| 101 |
95 __ push(lr); | 102 __ push(lr); |
96 | |
97 __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
98 __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 103 __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
99 // r4: source FixedArray | 104 // r4: source FixedArray |
100 // r5: number of elements (smi-tagged) | 105 // r5: number of elements (smi-tagged) |
101 | 106 |
102 // Allocate new FixedDoubleArray. | 107 // Allocate new FixedDoubleArray. |
103 __ mov(lr, Operand(FixedDoubleArray::kHeaderSize)); | 108 __ mov(lr, Operand(FixedDoubleArray::kHeaderSize)); |
104 __ add(lr, lr, Operand(r5, LSL, 2)); | 109 __ add(lr, lr, Operand(r5, LSL, 2)); |
105 __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | 110 __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); |
106 // r6: destination FixedDoubleArray, not tagged as heap object | 111 // r6: destination FixedDoubleArray, not tagged as heap object |
107 // Set destination FixedDoubleArray's length and map. | 112 // Set destination FixedDoubleArray's length and map. |
108 __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex); | 113 __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex); |
109 __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); | 114 __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); |
110 __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | 115 __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); |
111 // Update receiver's map. | 116 // Update receiver's map. |
112 | 117 |
113 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 118 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
114 __ RecordWriteField(r2, | 119 __ RecordWriteField(r2, |
115 HeapObject::kMapOffset, | 120 HeapObject::kMapOffset, |
116 r3, | 121 r3, |
117 r9, | 122 r9, |
118 kLRHasBeenSaved, | 123 kLRHasBeenSaved, |
119 kDontSaveFPRegs, | 124 kDontSaveFPRegs, |
120 EMIT_REMEMBERED_SET, | 125 OMIT_REMEMBERED_SET, |
121 OMIT_SMI_CHECK); | 126 OMIT_SMI_CHECK); |
122 // Replace receiver's backing store with newly created FixedDoubleArray. | 127 // Replace receiver's backing store with newly created FixedDoubleArray. |
123 __ add(r3, r6, Operand(kHeapObjectTag)); | 128 __ add(r3, r6, Operand(kHeapObjectTag)); |
124 __ str(r3, FieldMemOperand(r2, JSObject::kElementsOffset)); | 129 __ str(r3, FieldMemOperand(r2, JSObject::kElementsOffset)); |
125 __ RecordWriteField(r2, | 130 __ RecordWriteField(r2, |
126 JSObject::kElementsOffset, | 131 JSObject::kElementsOffset, |
127 r3, | 132 r3, |
128 r9, | 133 r9, |
129 kLRHasBeenSaved, | 134 kLRHasBeenSaved, |
130 kDontSaveFPRegs, | 135 kDontSaveFPRegs, |
131 EMIT_REMEMBERED_SET, | 136 EMIT_REMEMBERED_SET, |
132 OMIT_SMI_CHECK); | 137 OMIT_SMI_CHECK); |
133 | 138 |
134 // Prepare for conversion loop. | 139 // Prepare for conversion loop. |
135 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 140 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
136 __ add(r7, r6, Operand(FixedDoubleArray::kHeaderSize)); | 141 __ add(r7, r6, Operand(FixedDoubleArray::kHeaderSize)); |
137 __ add(r6, r7, Operand(r5, LSL, 2)); | 142 __ add(r6, r7, Operand(r5, LSL, 2)); |
138 __ mov(r4, Operand(kHoleNanLower32)); | 143 __ mov(r4, Operand(kHoleNanLower32)); |
139 __ mov(r5, Operand(kHoleNanUpper32)); | 144 __ mov(r5, Operand(kHoleNanUpper32)); |
140 // r3: begin of source FixedArray element fields, not tagged | 145 // r3: begin of source FixedArray element fields, not tagged |
141 // r4: kHoleNanLower32 | 146 // r4: kHoleNanLower32 |
142 // r5: kHoleNanUpper32 | 147 // r5: kHoleNanUpper32 |
143 // r6: end of destination FixedDoubleArray, not tagged | 148 // r6: end of destination FixedDoubleArray, not tagged |
144 // r7: begin of FixedDoubleArray element fields, not tagged | 149 // r7: begin of FixedDoubleArray element fields, not tagged |
145 if (!vfp3_supported) __ Push(r1, r0); | 150 if (!vfp3_supported) __ Push(r1, r0); |
146 | 151 |
147 __ b(&entry); | 152 __ b(&entry); |
148 | 153 |
| 154 __ bind(&only_change_map); |
| 155 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
| 156 __ RecordWriteField(r2, |
| 157 HeapObject::kMapOffset, |
| 158 r3, |
| 159 r9, |
| 160 kLRHasBeenSaved, |
| 161 kDontSaveFPRegs, |
| 162 OMIT_REMEMBERED_SET, |
| 163 OMIT_SMI_CHECK); |
| 164 __ b(&done); |
| 165 |
149 // Call into runtime if GC is required. | 166 // Call into runtime if GC is required. |
150 __ bind(&gc_required); | 167 __ bind(&gc_required); |
151 __ pop(lr); | 168 __ pop(lr); |
152 __ b(fail); | 169 __ b(fail); |
153 | 170 |
154 // Convert and copy elements. | 171 // Convert and copy elements. |
155 __ bind(&loop); | 172 __ bind(&loop); |
156 __ ldr(r9, MemOperand(r3, 4, PostIndex)); | 173 __ ldr(r9, MemOperand(r3, 4, PostIndex)); |
157 // r9: current element | 174 // r9: current element |
158 __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole); | 175 __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole); |
(...skipping 28 matching lines...) Expand all Loading... |
187 __ Assert(eq, "object found in smi-only array"); | 204 __ Assert(eq, "object found in smi-only array"); |
188 } | 205 } |
189 __ Strd(r4, r5, MemOperand(r7, 8, PostIndex)); | 206 __ Strd(r4, r5, MemOperand(r7, 8, PostIndex)); |
190 | 207 |
191 __ bind(&entry); | 208 __ bind(&entry); |
192 __ cmp(r7, r6); | 209 __ cmp(r7, r6); |
193 __ b(lt, &loop); | 210 __ b(lt, &loop); |
194 | 211 |
195 if (!vfp3_supported) __ Pop(r1, r0); | 212 if (!vfp3_supported) __ Pop(r1, r0); |
196 __ pop(lr); | 213 __ pop(lr); |
| 214 __ bind(&done); |
197 } | 215 } |
198 | 216 |
199 | 217 |
200 void ElementsTransitionGenerator::GenerateDoubleToObject( | 218 void ElementsTransitionGenerator::GenerateDoubleToObject( |
201 MacroAssembler* masm, Label* fail) { | 219 MacroAssembler* masm, Label* fail) { |
202 // ----------- S t a t e ------------- | 220 // ----------- S t a t e ------------- |
203 // -- r0 : value | 221 // -- r0 : value |
204 // -- r1 : key | 222 // -- r1 : key |
205 // -- r2 : receiver | 223 // -- r2 : receiver |
206 // -- lr : return address | 224 // -- lr : return address |
207 // -- r3 : target map, scratch for subsequent call | 225 // -- r3 : target map, scratch for subsequent call |
208 // -- r4 : scratch (elements) | 226 // -- r4 : scratch (elements) |
209 // ----------------------------------- | 227 // ----------------------------------- |
210 Label entry, loop, convert_hole, gc_required; | 228 Label entry, loop, convert_hole, gc_required, only_change_map; |
| 229 |
| 230 // Check for empty arrays, which only require a map transition and no changes |
| 231 // to the backing store. |
| 232 __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); |
| 233 __ CompareRoot(r4, Heap::kEmptyFixedArrayRootIndex); |
| 234 __ b(eq, &only_change_map); |
211 | 235 |
212 __ push(lr); | 236 __ push(lr); |
213 __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
214 __ Push(r3, r2, r1, r0); | 237 __ Push(r3, r2, r1, r0); |
215 __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 238 __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
216 // r4: source FixedDoubleArray | 239 // r4: source FixedDoubleArray |
217 // r5: number of elements (smi-tagged) | 240 // r5: number of elements (smi-tagged) |
218 | 241 |
219 // Allocate new FixedArray. | 242 // Allocate new FixedArray. |
220 __ mov(r0, Operand(FixedDoubleArray::kHeaderSize)); | 243 __ mov(r0, Operand(FixedDoubleArray::kHeaderSize)); |
221 __ add(r0, r0, Operand(r5, LSL, 1)); | 244 __ add(r0, r0, Operand(r5, LSL, 1)); |
222 __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | 245 __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); |
223 // r6: destination FixedArray, not tagged as heap object | 246 // r6: destination FixedArray, not tagged as heap object |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 296 |
274 // Replace the-hole NaN with the-hole pointer. | 297 // Replace the-hole NaN with the-hole pointer. |
275 __ bind(&convert_hole); | 298 __ bind(&convert_hole); |
276 __ str(r7, MemOperand(r3, 4, PostIndex)); | 299 __ str(r7, MemOperand(r3, 4, PostIndex)); |
277 | 300 |
278 __ bind(&entry); | 301 __ bind(&entry); |
279 __ cmp(r3, r5); | 302 __ cmp(r3, r5); |
280 __ b(lt, &loop); | 303 __ b(lt, &loop); |
281 | 304 |
282 __ Pop(r3, r2, r1, r0); | 305 __ Pop(r3, r2, r1, r0); |
283 // Update receiver's map. | |
284 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | |
285 __ RecordWriteField(r2, | |
286 HeapObject::kMapOffset, | |
287 r3, | |
288 r9, | |
289 kLRHasBeenSaved, | |
290 kDontSaveFPRegs, | |
291 EMIT_REMEMBERED_SET, | |
292 OMIT_SMI_CHECK); | |
293 // Replace receiver's backing store with newly created and filled FixedArray. | 306 // Replace receiver's backing store with newly created and filled FixedArray. |
294 __ str(r6, FieldMemOperand(r2, JSObject::kElementsOffset)); | 307 __ str(r6, FieldMemOperand(r2, JSObject::kElementsOffset)); |
295 __ RecordWriteField(r2, | 308 __ RecordWriteField(r2, |
296 JSObject::kElementsOffset, | 309 JSObject::kElementsOffset, |
297 r6, | 310 r6, |
298 r9, | 311 r9, |
299 kLRHasBeenSaved, | 312 kLRHasBeenSaved, |
300 kDontSaveFPRegs, | 313 kDontSaveFPRegs, |
301 EMIT_REMEMBERED_SET, | 314 EMIT_REMEMBERED_SET, |
302 OMIT_SMI_CHECK); | 315 OMIT_SMI_CHECK); |
303 __ pop(lr); | 316 __ pop(lr); |
| 317 |
| 318 __ bind(&only_change_map); |
| 319 // Update receiver's map. |
| 320 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
| 321 __ RecordWriteField(r2, |
| 322 HeapObject::kMapOffset, |
| 323 r3, |
| 324 r9, |
| 325 kLRHasNotBeenSaved, |
| 326 kDontSaveFPRegs, |
| 327 OMIT_REMEMBERED_SET, |
| 328 OMIT_SMI_CHECK); |
304 } | 329 } |
305 | 330 |
306 | 331 |
307 void StringCharLoadGenerator::Generate(MacroAssembler* masm, | 332 void StringCharLoadGenerator::Generate(MacroAssembler* masm, |
308 Register string, | 333 Register string, |
309 Register index, | 334 Register index, |
310 Register result, | 335 Register result, |
311 Label* call_runtime) { | 336 Label* call_runtime) { |
312 // Fetch the instance type of the receiver into result register. | 337 // Fetch the instance type of the receiver into result register. |
313 __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); | 338 __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 // Ascii string. | 413 // Ascii string. |
389 __ ldrb(result, MemOperand(string, index)); | 414 __ ldrb(result, MemOperand(string, index)); |
390 __ bind(&done); | 415 __ bind(&done); |
391 } | 416 } |
392 | 417 |
393 #undef __ | 418 #undef __ |
394 | 419 |
395 } } // namespace v8::internal | 420 } } // namespace v8::internal |
396 | 421 |
397 #endif // V8_TARGET_ARCH_ARM | 422 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |