| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 97   __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | 97   __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | 
| 98   __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 98   __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 
| 99   // r4: source FixedArray | 99   // r4: source FixedArray | 
| 100   // r5: number of elements (smi-tagged) | 100   // r5: number of elements (smi-tagged) | 
| 101 | 101 | 
| 102   // Allocate new FixedDoubleArray. | 102   // Allocate new FixedDoubleArray. | 
| 103   __ mov(lr, Operand(FixedDoubleArray::kHeaderSize)); | 103   __ mov(lr, Operand(FixedDoubleArray::kHeaderSize)); | 
| 104   __ add(lr, lr, Operand(r5, LSL, 2)); | 104   __ add(lr, lr, Operand(r5, LSL, 2)); | 
| 105   __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | 105   __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | 
| 106   // r6: destination FixedDoubleArray, not tagged as heap object | 106   // r6: destination FixedDoubleArray, not tagged as heap object | 
|  | 107   // Set destination FixedDoubleArray's length and map. | 
| 107   __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex); | 108   __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex); | 
|  | 109   __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); | 
| 108   __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | 110   __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | 
| 109   // Set destination FixedDoubleArray's length. |  | 
| 110   __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); |  | 
| 111   // Update receiver's map. | 111   // Update receiver's map. | 
| 112 | 112 | 
| 113   __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 113   __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 
| 114   __ RecordWriteField(r2, | 114   __ RecordWriteField(r2, | 
| 115                       HeapObject::kMapOffset, | 115                       HeapObject::kMapOffset, | 
| 116                       r3, | 116                       r3, | 
| 117                       r9, | 117                       r9, | 
| 118                       kLRHasBeenSaved, | 118                       kLRHasBeenSaved, | 
| 119                       kDontSaveFPRegs, | 119                       kDontSaveFPRegs, | 
| 120                       EMIT_REMEMBERED_SET, | 120                       EMIT_REMEMBERED_SET, | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 148 | 148 | 
| 149   // Call into runtime if GC is required. | 149   // Call into runtime if GC is required. | 
| 150   __ bind(&gc_required); | 150   __ bind(&gc_required); | 
| 151   __ pop(lr); | 151   __ pop(lr); | 
| 152   __ b(fail); | 152   __ b(fail); | 
| 153 | 153 | 
| 154   // Convert and copy elements. | 154   // Convert and copy elements. | 
| 155   __ bind(&loop); | 155   __ bind(&loop); | 
| 156   __ ldr(r9, MemOperand(r3, 4, PostIndex)); | 156   __ ldr(r9, MemOperand(r3, 4, PostIndex)); | 
| 157   // r9: current element | 157   // r9: current element | 
| 158   __ JumpIfNotSmi(r9, &convert_hole); | 158   __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole); | 
| 159 | 159 | 
| 160   // Normal smi, convert to double and store. | 160   // Normal smi, convert to double and store. | 
| 161   __ SmiUntag(r9); |  | 
| 162   if (vfp3_supported) { | 161   if (vfp3_supported) { | 
| 163     CpuFeatures::Scope scope(VFP3); | 162     CpuFeatures::Scope scope(VFP3); | 
| 164     __ vmov(s0, r9); | 163     __ vmov(s0, r9); | 
| 165     __ vcvt_f64_s32(d0, s0); | 164     __ vcvt_f64_s32(d0, s0); | 
| 166     __ vstr(d0, r7, 0); | 165     __ vstr(d0, r7, 0); | 
| 167     __ add(r7, r7, Operand(8)); | 166     __ add(r7, r7, Operand(8)); | 
| 168   } else { | 167   } else { | 
| 169     FloatingPointHelper::ConvertIntToDouble(masm, | 168     FloatingPointHelper::ConvertIntToDouble(masm, | 
| 170                                             r9, | 169                                             r9, | 
| 171                                             FloatingPointHelper::kCoreRegisters, | 170                                             FloatingPointHelper::kCoreRegisters, | 
| 172                                             d0, | 171                                             d0, | 
| 173                                             r0, | 172                                             r0, | 
| 174                                             r1, | 173                                             r1, | 
| 175                                             lr, | 174                                             lr, | 
| 176                                             s0); | 175                                             s0); | 
| 177     __ Strd(r0, r1, MemOperand(r7, 8, PostIndex)); | 176     __ Strd(r0, r1, MemOperand(r7, 8, PostIndex)); | 
| 178   } | 177   } | 
| 179   __ b(&entry); | 178   __ b(&entry); | 
| 180 | 179 | 
| 181   // Hole found, store the-hole NaN. | 180   // Hole found, store the-hole NaN. | 
| 182   __ bind(&convert_hole); | 181   __ bind(&convert_hole); | 
| 183   if (FLAG_debug_code) { | 182   if (FLAG_debug_code) { | 
|  | 183     // Restore a "smi-untagged" heap object. | 
|  | 184     __ SmiTag(r9); | 
|  | 185     __ orr(r9, r9, Operand(1)); | 
| 184     __ CompareRoot(r9, Heap::kTheHoleValueRootIndex); | 186     __ CompareRoot(r9, Heap::kTheHoleValueRootIndex); | 
| 185     __ Assert(eq, "object found in smi-only array"); | 187     __ Assert(eq, "object found in smi-only array"); | 
| 186   } | 188   } | 
| 187   __ Strd(r4, r5, MemOperand(r7, 8, PostIndex)); | 189   __ Strd(r4, r5, MemOperand(r7, 8, PostIndex)); | 
| 188 | 190 | 
| 189   __ bind(&entry); | 191   __ bind(&entry); | 
| 190   __ cmp(r7, r6); | 192   __ cmp(r7, r6); | 
| 191   __ b(lt, &loop); | 193   __ b(lt, &loop); | 
| 192 | 194 | 
| 193   if (!vfp3_supported) __ Pop(r1, r0); | 195   if (!vfp3_supported) __ Pop(r1, r0); | 
| 194   __ pop(lr); | 196   __ pop(lr); | 
| 195 } | 197 } | 
| 196 | 198 | 
| 197 | 199 | 
| 198 void ElementsTransitionGenerator::GenerateDoubleToObject( | 200 void ElementsTransitionGenerator::GenerateDoubleToObject( | 
| 199     MacroAssembler* masm, Label* fail) { | 201     MacroAssembler* masm, Label* fail) { | 
| 200   // ----------- S t a t e ------------- | 202   // ----------- S t a t e ------------- | 
| 201   //  -- r0    : value | 203   //  -- r0    : value | 
| 202   //  -- r1    : key | 204   //  -- r1    : key | 
| 203   //  -- r2    : receiver | 205   //  -- r2    : receiver | 
| 204   //  -- lr    : return address | 206   //  -- lr    : return address | 
| 205   //  -- r3    : target map, scratch for subsequent call | 207   //  -- r3    : target map, scratch for subsequent call | 
| 206   //  -- r4    : scratch (elements) | 208   //  -- r4    : scratch (elements) | 
| 207   // ----------------------------------- | 209   // ----------------------------------- | 
| 208   Label entry, loop, convert_hole, gc_required; | 210   Label entry, loop, convert_hole, gc_required; | 
| 209 | 211 | 
| 210   __ push(lr); | 212   __ push(lr); | 
|  | 213   __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | 
| 211   __ Push(r3, r2, r1, r0); | 214   __ Push(r3, r2, r1, r0); | 
| 212 |  | 
| 213   __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); |  | 
| 214   __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 215   __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 
| 215   // r4: source FixedDoubleArray | 216   // r4: source FixedDoubleArray | 
| 216   // r5: number of elements (smi-tagged) | 217   // r5: number of elements (smi-tagged) | 
| 217 | 218 | 
| 218   // Allocate new FixedArray. | 219   // Allocate new FixedArray. | 
| 219   __ mov(r0, Operand(FixedDoubleArray::kHeaderSize)); | 220   __ mov(r0, Operand(FixedDoubleArray::kHeaderSize)); | 
| 220   __ add(r0, r0, Operand(r5, LSL, 1)); | 221   __ add(r0, r0, Operand(r5, LSL, 1)); | 
| 221   __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | 222   __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | 
| 222   // r6: destination FixedArray, not tagged as heap object | 223   // r6: destination FixedArray, not tagged as heap object | 
|  | 224   // Set destination FixedDoubleArray's length and map. | 
| 223   __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); | 225   __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); | 
|  | 226   __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); | 
| 224   __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | 227   __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | 
| 225   // Set destination FixedDoubleArray's length. |  | 
| 226   __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); |  | 
| 227 | 228 | 
| 228   // Prepare for conversion loop. | 229   // Prepare for conversion loop. | 
| 229   __ add(r4, r4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4)); | 230   __ add(r4, r4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4)); | 
| 230   __ add(r3, r6, Operand(FixedArray::kHeaderSize)); | 231   __ add(r3, r6, Operand(FixedArray::kHeaderSize)); | 
| 231   __ add(r6, r6, Operand(kHeapObjectTag)); | 232   __ add(r6, r6, Operand(kHeapObjectTag)); | 
| 232   __ add(r5, r3, Operand(r5, LSL, 1)); | 233   __ add(r5, r3, Operand(r5, LSL, 1)); | 
| 233   __ LoadRoot(r7, Heap::kTheHoleValueRootIndex); | 234   __ LoadRoot(r7, Heap::kTheHoleValueRootIndex); | 
| 234   __ LoadRoot(r9, Heap::kHeapNumberMapRootIndex); | 235   __ LoadRoot(r9, Heap::kHeapNumberMapRootIndex); | 
| 235   // Using offsetted addresses in r4 to fully take advantage of post-indexing. | 236   // Using offsetted addresses in r4 to fully take advantage of post-indexing. | 
| 236   // r3: begin of destination FixedArray element fields, not tagged | 237   // r3: begin of destination FixedArray element fields, not tagged | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 318   __ b(eq, &check_sequential); | 319   __ b(eq, &check_sequential); | 
| 319 | 320 | 
| 320   // Dispatch on the indirect string shape: slice or cons. | 321   // Dispatch on the indirect string shape: slice or cons. | 
| 321   Label cons_string; | 322   Label cons_string; | 
| 322   __ tst(result, Operand(kSlicedNotConsMask)); | 323   __ tst(result, Operand(kSlicedNotConsMask)); | 
| 323   __ b(eq, &cons_string); | 324   __ b(eq, &cons_string); | 
| 324 | 325 | 
| 325   // Handle slices. | 326   // Handle slices. | 
| 326   Label indirect_string_loaded; | 327   Label indirect_string_loaded; | 
| 327   __ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); | 328   __ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); | 
|  | 329   __ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset)); | 
| 328   __ add(index, index, Operand(result, ASR, kSmiTagSize)); | 330   __ add(index, index, Operand(result, ASR, kSmiTagSize)); | 
| 329   __ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset)); |  | 
| 330   __ jmp(&indirect_string_loaded); | 331   __ jmp(&indirect_string_loaded); | 
| 331 | 332 | 
| 332   // Handle cons strings. | 333   // Handle cons strings. | 
| 333   // Check whether the right hand side is the empty string (i.e. if | 334   // Check whether the right hand side is the empty string (i.e. if | 
| 334   // this is really a flat string in a cons string). If that is not | 335   // this is really a flat string in a cons string). If that is not | 
| 335   // the case we would rather go to the runtime system now to flatten | 336   // the case we would rather go to the runtime system now to flatten | 
| 336   // the string. | 337   // the string. | 
| 337   __ bind(&cons_string); | 338   __ bind(&cons_string); | 
| 338   __ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset)); | 339   __ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset)); | 
| 339   __ LoadRoot(ip, Heap::kEmptyStringRootIndex); | 340   __ CompareRoot(result, Heap::kEmptyStringRootIndex); | 
| 340   __ cmp(result, ip); |  | 
| 341   __ b(ne, call_runtime); | 341   __ b(ne, call_runtime); | 
| 342   // Get the first of the two strings and load its instance type. | 342   // Get the first of the two strings and load its instance type. | 
| 343   __ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset)); | 343   __ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset)); | 
| 344 | 344 | 
| 345   __ bind(&indirect_string_loaded); | 345   __ bind(&indirect_string_loaded); | 
| 346   __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); | 346   __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); | 
| 347   __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); | 347   __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); | 
| 348 | 348 | 
| 349   // Distinguish sequential and external strings. Only these two string | 349   // Distinguish sequential and external strings. Only these two string | 
| 350   // representations can reach here (slices and flat cons strings have been | 350   // representations can reach here (slices and flat cons strings have been | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 388   // Ascii string. | 388   // Ascii string. | 
| 389   __ ldrb(result, MemOperand(string, index)); | 389   __ ldrb(result, MemOperand(string, index)); | 
| 390   __ bind(&done); | 390   __ bind(&done); | 
| 391 } | 391 } | 
| 392 | 392 | 
| 393 #undef __ | 393 #undef __ | 
| 394 | 394 | 
| 395 } }  // namespace v8::internal | 395 } }  // namespace v8::internal | 
| 396 | 396 | 
| 397 #endif  // V8_TARGET_ARCH_ARM | 397 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|