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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 // r3: boilerplate literal array. | 340 // r3: boilerplate literal array. |
341 ASSERT(mode != FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS); | 341 ASSERT(mode != FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS); |
342 | 342 |
343 // All sizes here are multiples of kPointerSize. | 343 // All sizes here are multiples of kPointerSize. |
344 int elements_size = 0; | 344 int elements_size = 0; |
345 if (length > 0) { | 345 if (length > 0) { |
346 elements_size = mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 346 elements_size = mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
347 ? FixedDoubleArray::SizeFor(length) | 347 ? FixedDoubleArray::SizeFor(length) |
348 : FixedArray::SizeFor(length); | 348 : FixedArray::SizeFor(length); |
349 } | 349 } |
350 int size = JSArray::kSize + elements_size; | 350 int elements_offset = JSArray::kSize; |
| 351 int size = elements_offset + elements_size; |
351 | 352 |
352 // Allocate both the JS array and the elements array in one big | 353 // Allocate both the JS array and the elements array in one big |
353 // allocation. This avoids multiple limit checks. | 354 // allocation. This avoids multiple limit checks. |
354 __ AllocateInNewSpace(size, | 355 __ AllocateInNewSpace(size, |
355 r0, | 356 r0, |
356 r1, | 357 r1, |
357 r2, | 358 r2, |
358 fail, | 359 fail, |
359 TAG_OBJECT); | 360 NO_ALLOCATION_FLAGS); |
360 | 361 |
361 // Copy the JS array part. | 362 // Copy the JS array part. |
362 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 363 __ sub(r3, r3, Operand(kHeapObjectTag)); |
363 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 364 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
364 __ ldr(r1, FieldMemOperand(r3, i)); | 365 RegList temps = r4.bit() | r5.bit() | r6.bit() | r7.bit(); |
365 __ str(r1, FieldMemOperand(r0, i)); | 366 __ ldm(ia_w, r3, temps); |
| 367 if (length > 0) { |
| 368 // Set the pointer to the elements array if it is non-empty. r0 is untagged, |
| 369 // so we need to include the tag here. |
| 370 STATIC_ASSERT(JSArray::kElementsOffset == 2 * kPointerSize); |
| 371 __ add(r6, r0, Operand(elements_offset + kHeapObjectTag)); |
| 372 } |
| 373 __ stm(ia_w, r0, temps); |
| 374 |
| 375 // Copy the elements from the boilerplate array, if needed. At this point, |
| 376 // r0 points to the beginning of elements. |
| 377 int restore_size = JSArray::kSize - kHeapObjectTag; |
| 378 if (length > 0) { |
| 379 // Load the elements array from the boilerplate. |
| 380 __ ldr(r3, MemOperand(r3, JSArray::kElementsOffset - JSArray::kSize)); |
| 381 ASSERT((elements_size % kPointerSize) == 0); |
| 382 if (CpuFeatures::IsSupported(VFP2)) { |
| 383 CpuFeatures::Scope scope(VFP2); |
| 384 SwVfpRegister first_reg = s0; |
| 385 SwVfpRegister last_reg = s15; |
| 386 __ sub(r3, r3, Operand(kHeapObjectTag)); |
| 387 __ VFPCopyFields(r0, r3, elements_size / kPointerSize, |
| 388 first_reg, last_reg); |
| 389 restore_size += elements_size; |
| 390 } else { |
| 391 __ CopyFields(r6, r3, r1.bit(), elements_size / kPointerSize); |
366 } | 392 } |
367 } | 393 } |
368 | 394 |
369 if (length > 0) { | 395 // At this point, r0 points to the end of the copied region. Bring it back to |
370 // Get hold of the elements array of the boilerplate and setup the | 396 // the beginning and tag it. |
371 // elements pointer in the resulting object. | 397 __ sub(r0, r0, Operand(restore_size)); |
372 __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset)); | |
373 __ add(r2, r0, Operand(JSArray::kSize)); | |
374 __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset)); | |
375 | |
376 // Copy the elements array. | |
377 ASSERT((elements_size % kPointerSize) == 0); | |
378 __ CopyFields(r2, r3, r1.bit(), elements_size / kPointerSize); | |
379 } | |
380 } | 398 } |
381 | 399 |
382 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { | 400 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
383 // Stack layout on entry: | 401 // Stack layout on entry: |
384 // | 402 // |
385 // [sp]: constant elements. | 403 // [sp]: constant elements. |
386 // [sp + kPointerSize]: literal index. | 404 // [sp + kPointerSize]: literal index. |
387 // [sp + (2 * kPointerSize)]: literals array. | 405 // [sp + (2 * kPointerSize)]: literals array. |
388 | 406 |
389 // Load boilerplate object into r3 and check if we need to create a | 407 // Load boilerplate object into r3 and check if we need to create a |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 // Check that the boilerplate contains only fast properties and we can | 495 // Check that the boilerplate contains only fast properties and we can |
478 // statically determine the instance size. | 496 // statically determine the instance size. |
479 int size = JSObject::kHeaderSize + length_ * kPointerSize; | 497 int size = JSObject::kHeaderSize + length_ * kPointerSize; |
480 __ ldr(r0, FieldMemOperand(r3, HeapObject::kMapOffset)); | 498 __ ldr(r0, FieldMemOperand(r3, HeapObject::kMapOffset)); |
481 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceSizeOffset)); | 499 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceSizeOffset)); |
482 __ cmp(r0, Operand(size >> kPointerSizeLog2)); | 500 __ cmp(r0, Operand(size >> kPointerSizeLog2)); |
483 __ b(ne, &slow_case); | 501 __ b(ne, &slow_case); |
484 | 502 |
485 // Allocate the JS object and copy header together with all in-object | 503 // Allocate the JS object and copy header together with all in-object |
486 // properties from the boilerplate. | 504 // properties from the boilerplate. |
487 __ AllocateInNewSpace(size, r0, r1, r2, &slow_case, TAG_OBJECT); | 505 if (CpuFeatures::IsSupported(VFP2)) { |
488 for (int i = 0; i < size; i += kPointerSize) { | 506 CpuFeatures::Scope scope(VFP2); |
489 __ ldr(r1, FieldMemOperand(r3, i)); | 507 __ AllocateInNewSpace(size, r0, r1, r2, &slow_case, NO_ALLOCATION_FLAGS); |
490 __ str(r1, FieldMemOperand(r0, i)); | 508 SwVfpRegister first_reg = s0; |
| 509 SwVfpRegister last_reg = s15; |
| 510 __ sub(r3, r3, Operand(kHeapObjectTag)); |
| 511 __ VFPCopyFields(r0, r3, size / kPointerSize, first_reg, last_reg); |
| 512 __ sub(r0, r0, Operand(size - kHeapObjectTag)); |
| 513 } else { |
| 514 __ AllocateInNewSpace(size, r0, r1, r2, &slow_case, TAG_OBJECT); |
| 515 for (int i = 0; i < size; i += kPointerSize) { |
| 516 __ ldr(r1, FieldMemOperand(r3, i)); |
| 517 __ str(r1, FieldMemOperand(r0, i)); |
| 518 } |
491 } | 519 } |
492 | 520 |
493 // Return and remove the on-stack parameters. | 521 // Return and remove the on-stack parameters. |
494 __ add(sp, sp, Operand(4 * kPointerSize)); | 522 __ add(sp, sp, Operand(4 * kPointerSize)); |
495 __ Ret(); | 523 __ Ret(); |
496 | 524 |
497 __ bind(&slow_case); | 525 __ bind(&slow_case); |
498 __ TailCallRuntime(Runtime::kCreateObjectLiteralShallow, 4, 1); | 526 __ TailCallRuntime(Runtime::kCreateObjectLiteralShallow, 4, 1); |
499 } | 527 } |
500 | 528 |
(...skipping 7123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7624 | 7652 |
7625 __ Pop(lr, r5, r1); | 7653 __ Pop(lr, r5, r1); |
7626 __ Ret(); | 7654 __ Ret(); |
7627 } | 7655 } |
7628 | 7656 |
7629 #undef __ | 7657 #undef __ |
7630 | 7658 |
7631 } } // namespace v8::internal | 7659 } } // namespace v8::internal |
7632 | 7660 |
7633 #endif // V8_TARGET_ARCH_ARM | 7661 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |