OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1482 | 1482 |
1483 StubRuntimeCallHelper call_helper; | 1483 StubRuntimeCallHelper call_helper; |
1484 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); | 1484 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); |
1485 | 1485 |
1486 __ bind(&miss); | 1486 __ bind(&miss); |
1487 PropertyAccessCompiler::TailCallBuiltin( | 1487 PropertyAccessCompiler::TailCallBuiltin( |
1488 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 1488 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
1489 } | 1489 } |
1490 | 1490 |
1491 | 1491 |
1492 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | |
1493 // r1 : function | |
1494 // r2 : number of parameters (tagged) | |
1495 // r3 : parameters pointer | |
1496 | |
1497 DCHECK(r1.is(ArgumentsAccessNewDescriptor::function())); | |
1498 DCHECK(r2.is(ArgumentsAccessNewDescriptor::parameter_count())); | |
1499 DCHECK(r3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | |
1500 | |
1501 // Check if the calling frame is an arguments adaptor frame. | |
1502 Label runtime; | |
1503 __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
1504 __ ldr(r0, MemOperand(r4, StandardFrameConstants::kContextOffset)); | |
1505 __ cmp(r0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
1506 __ b(ne, &runtime); | |
1507 | |
1508 // Patch the arguments.length and the parameters pointer in the current frame. | |
1509 __ ldr(r2, MemOperand(r4, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
1510 __ add(r4, r4, Operand(r2, LSL, 1)); | |
1511 __ add(r3, r4, Operand(StandardFrameConstants::kCallerSPOffset)); | |
1512 | |
1513 __ bind(&runtime); | |
1514 __ Push(r1, r3, r2); | |
1515 __ TailCallRuntime(Runtime::kNewSloppyArguments); | |
1516 } | |
1517 | |
1518 | |
1519 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | |
1520 // r1 : function | |
1521 // r2 : number of parameters (tagged) | |
1522 // r3 : parameters pointer | |
1523 // Registers used over whole function: | |
1524 // r5 : arguments count (tagged) | |
1525 // r6 : mapped parameter count (tagged) | |
1526 | |
1527 DCHECK(r1.is(ArgumentsAccessNewDescriptor::function())); | |
1528 DCHECK(r2.is(ArgumentsAccessNewDescriptor::parameter_count())); | |
1529 DCHECK(r3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | |
1530 | |
1531 // Check if the calling frame is an arguments adaptor frame. | |
1532 Label adaptor_frame, try_allocate, runtime; | |
1533 __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
1534 __ ldr(r0, MemOperand(r4, StandardFrameConstants::kContextOffset)); | |
1535 __ cmp(r0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
1536 __ b(eq, &adaptor_frame); | |
1537 | |
1538 // No adaptor, parameter count = argument count. | |
1539 __ mov(r5, r2); | |
1540 __ mov(r6, r2); | |
1541 __ b(&try_allocate); | |
1542 | |
1543 // We have an adaptor frame. Patch the parameters pointer. | |
1544 __ bind(&adaptor_frame); | |
1545 __ ldr(r5, MemOperand(r4, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
1546 __ add(r4, r4, Operand(r5, LSL, 1)); | |
1547 __ add(r3, r4, Operand(StandardFrameConstants::kCallerSPOffset)); | |
1548 | |
1549 // r5 = argument count (tagged) | |
1550 // r6 = parameter count (tagged) | |
1551 // Compute the mapped parameter count = min(r6, r5) in r6. | |
1552 __ mov(r6, r2); | |
1553 __ cmp(r6, Operand(r5)); | |
1554 __ mov(r6, Operand(r5), LeaveCC, gt); | |
1555 | |
1556 __ bind(&try_allocate); | |
1557 | |
1558 // Compute the sizes of backing store, parameter map, and arguments object. | |
1559 // 1. Parameter map, has 2 extra words containing context and backing store. | |
1560 const int kParameterMapHeaderSize = | |
1561 FixedArray::kHeaderSize + 2 * kPointerSize; | |
1562 // If there are no mapped parameters, we do not need the parameter_map. | |
1563 __ cmp(r6, Operand(Smi::FromInt(0))); | |
1564 __ mov(r9, Operand::Zero(), LeaveCC, eq); | |
1565 __ mov(r9, Operand(r6, LSL, 1), LeaveCC, ne); | |
1566 __ add(r9, r9, Operand(kParameterMapHeaderSize), LeaveCC, ne); | |
1567 | |
1568 // 2. Backing store. | |
1569 __ add(r9, r9, Operand(r5, LSL, 1)); | |
1570 __ add(r9, r9, Operand(FixedArray::kHeaderSize)); | |
1571 | |
1572 // 3. Arguments object. | |
1573 __ add(r9, r9, Operand(JSSloppyArgumentsObject::kSize)); | |
1574 | |
1575 // Do the allocation of all three objects in one go. | |
1576 __ Allocate(r9, r0, r9, r4, &runtime, TAG_OBJECT); | |
1577 | |
1578 // r0 = address of new object(s) (tagged) | |
1579 // r2 = argument count (smi-tagged) | |
1580 // Get the arguments boilerplate from the current native context into r4. | |
1581 const int kNormalOffset = | |
1582 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); | |
1583 const int kAliasedOffset = | |
1584 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); | |
1585 | |
1586 __ ldr(r4, NativeContextMemOperand()); | |
1587 __ cmp(r6, Operand::Zero()); | |
1588 __ ldr(r4, MemOperand(r4, kNormalOffset), eq); | |
1589 __ ldr(r4, MemOperand(r4, kAliasedOffset), ne); | |
1590 | |
1591 // r0 = address of new object (tagged) | |
1592 // r2 = argument count (smi-tagged) | |
1593 // r4 = address of arguments map (tagged) | |
1594 // r6 = mapped parameter count (tagged) | |
1595 __ str(r4, FieldMemOperand(r0, JSObject::kMapOffset)); | |
1596 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); | |
1597 __ str(r9, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | |
1598 __ str(r9, FieldMemOperand(r0, JSObject::kElementsOffset)); | |
1599 | |
1600 // Set up the callee in-object property. | |
1601 __ AssertNotSmi(r1); | |
1602 __ str(r1, FieldMemOperand(r0, JSSloppyArgumentsObject::kCalleeOffset)); | |
1603 | |
1604 // Use the length (smi tagged) and set that as an in-object property too. | |
1605 __ AssertSmi(r5); | |
1606 __ str(r5, FieldMemOperand(r0, JSSloppyArgumentsObject::kLengthOffset)); | |
1607 | |
1608 // Set up the elements pointer in the allocated arguments object. | |
1609 // If we allocated a parameter map, r4 will point there, otherwise | |
1610 // it will point to the backing store. | |
1611 __ add(r4, r0, Operand(JSSloppyArgumentsObject::kSize)); | |
1612 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); | |
1613 | |
1614 // r0 = address of new object (tagged) | |
1615 // r2 = argument count (tagged) | |
1616 // r4 = address of parameter map or backing store (tagged) | |
1617 // r6 = mapped parameter count (tagged) | |
1618 // Initialize parameter map. If there are no mapped arguments, we're done. | |
1619 Label skip_parameter_map; | |
1620 __ cmp(r6, Operand(Smi::FromInt(0))); | |
1621 // Move backing store address to r1, because it is | |
1622 // expected there when filling in the unmapped arguments. | |
1623 __ mov(r1, r4, LeaveCC, eq); | |
1624 __ b(eq, &skip_parameter_map); | |
1625 | |
1626 __ LoadRoot(r5, Heap::kSloppyArgumentsElementsMapRootIndex); | |
1627 __ str(r5, FieldMemOperand(r4, FixedArray::kMapOffset)); | |
1628 __ add(r5, r6, Operand(Smi::FromInt(2))); | |
1629 __ str(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | |
1630 __ str(cp, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize)); | |
1631 __ add(r5, r4, Operand(r6, LSL, 1)); | |
1632 __ add(r5, r5, Operand(kParameterMapHeaderSize)); | |
1633 __ str(r5, FieldMemOperand(r4, FixedArray::kHeaderSize + 1 * kPointerSize)); | |
1634 | |
1635 // Copy the parameter slots and the holes in the arguments. | |
1636 // We need to fill in mapped_parameter_count slots. They index the context, | |
1637 // where parameters are stored in reverse order, at | |
1638 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | |
1639 // The mapped parameter thus need to get indices | |
1640 // MIN_CONTEXT_SLOTS+parameter_count-1 .. | |
1641 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | |
1642 // We loop from right to left. | |
1643 Label parameters_loop, parameters_test; | |
1644 __ mov(r5, r6); | |
1645 __ add(r9, r2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); | |
1646 __ sub(r9, r9, Operand(r6)); | |
1647 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
1648 __ add(r1, r4, Operand(r5, LSL, 1)); | |
1649 __ add(r1, r1, Operand(kParameterMapHeaderSize)); | |
1650 | |
1651 // r1 = address of backing store (tagged) | |
1652 // r4 = address of parameter map (tagged), which is also the address of new | |
1653 // object + Heap::kSloppyArgumentsObjectSize (tagged) | |
1654 // r0 = temporary scratch (a.o., for address calculation) | |
1655 // r5 = loop variable (tagged) | |
1656 // ip = the hole value | |
1657 __ jmp(¶meters_test); | |
1658 | |
1659 __ bind(¶meters_loop); | |
1660 __ sub(r5, r5, Operand(Smi::FromInt(1))); | |
1661 __ mov(r0, Operand(r5, LSL, 1)); | |
1662 __ add(r0, r0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); | |
1663 __ str(r9, MemOperand(r4, r0)); | |
1664 __ sub(r0, r0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); | |
1665 __ str(ip, MemOperand(r1, r0)); | |
1666 __ add(r9, r9, Operand(Smi::FromInt(1))); | |
1667 __ bind(¶meters_test); | |
1668 __ cmp(r5, Operand(Smi::FromInt(0))); | |
1669 __ b(ne, ¶meters_loop); | |
1670 | |
1671 // Restore r0 = new object (tagged) and r5 = argument count (tagged). | |
1672 __ sub(r0, r4, Operand(JSSloppyArgumentsObject::kSize)); | |
1673 __ ldr(r5, FieldMemOperand(r0, JSSloppyArgumentsObject::kLengthOffset)); | |
1674 | |
1675 __ bind(&skip_parameter_map); | |
1676 // r0 = address of new object (tagged) | |
1677 // r1 = address of backing store (tagged) | |
1678 // r5 = argument count (tagged) | |
1679 // r6 = mapped parameter count (tagged) | |
1680 // r9 = scratch | |
1681 // Copy arguments header and remaining slots (if there are any). | |
1682 __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); | |
1683 __ str(r9, FieldMemOperand(r1, FixedArray::kMapOffset)); | |
1684 __ str(r5, FieldMemOperand(r1, FixedArray::kLengthOffset)); | |
1685 | |
1686 Label arguments_loop, arguments_test; | |
1687 __ sub(r3, r3, Operand(r6, LSL, 1)); | |
1688 __ jmp(&arguments_test); | |
1689 | |
1690 __ bind(&arguments_loop); | |
1691 __ sub(r3, r3, Operand(kPointerSize)); | |
1692 __ ldr(r4, MemOperand(r3, 0)); | |
1693 __ add(r9, r1, Operand(r6, LSL, 1)); | |
1694 __ str(r4, FieldMemOperand(r9, FixedArray::kHeaderSize)); | |
1695 __ add(r6, r6, Operand(Smi::FromInt(1))); | |
1696 | |
1697 __ bind(&arguments_test); | |
1698 __ cmp(r6, Operand(r5)); | |
1699 __ b(lt, &arguments_loop); | |
1700 | |
1701 // Return. | |
1702 __ Ret(); | |
1703 | |
1704 // Do the runtime call to allocate the arguments object. | |
1705 // r0 = address of new object (tagged) | |
1706 // r5 = argument count (tagged) | |
1707 __ bind(&runtime); | |
1708 __ Push(r1, r3, r5); | |
1709 __ TailCallRuntime(Runtime::kNewSloppyArguments); | |
1710 } | |
1711 | |
1712 | |
1713 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1492 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1714 // Return address is in lr. | 1493 // Return address is in lr. |
1715 Label slow; | 1494 Label slow; |
1716 | 1495 |
1717 Register receiver = LoadDescriptor::ReceiverRegister(); | 1496 Register receiver = LoadDescriptor::ReceiverRegister(); |
1718 Register key = LoadDescriptor::NameRegister(); | 1497 Register key = LoadDescriptor::NameRegister(); |
1719 | 1498 |
1720 // Check that the key is an array index, that is Uint32. | 1499 // Check that the key is an array index, that is Uint32. |
1721 __ NonNegativeSmiTst(key); | 1500 __ NonNegativeSmiTst(key); |
1722 __ b(ne, &slow); | 1501 __ b(ne, &slow); |
(...skipping 3217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4940 __ Push(r0, r2, r1); | 4719 __ Push(r0, r2, r1); |
4941 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4720 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4942 __ mov(r3, r0); | 4721 __ mov(r3, r0); |
4943 __ Pop(r0, r2); | 4722 __ Pop(r0, r2); |
4944 } | 4723 } |
4945 __ jmp(&done_allocate); | 4724 __ jmp(&done_allocate); |
4946 } | 4725 } |
4947 } | 4726 } |
4948 | 4727 |
4949 | 4728 |
| 4729 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { |
| 4730 // ----------- S t a t e ------------- |
| 4731 // -- r1 : function |
| 4732 // -- cp : context |
| 4733 // -- fp : frame pointer |
| 4734 // -- lr : return address |
| 4735 // ----------------------------------- |
| 4736 __ AssertFunction(r1); |
| 4737 |
| 4738 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. |
| 4739 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 4740 __ ldr(r2, |
| 4741 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 4742 __ add(r3, fp, Operand(r2, LSL, kPointerSizeLog2 - 1)); |
| 4743 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 4744 |
| 4745 // r1 : function |
| 4746 // r2 : number of parameters (tagged) |
| 4747 // r3 : parameters pointer |
| 4748 // Registers used over whole function: |
| 4749 // r5 : arguments count (tagged) |
| 4750 // r6 : mapped parameter count (tagged) |
| 4751 |
| 4752 // Check if the calling frame is an arguments adaptor frame. |
| 4753 Label adaptor_frame, try_allocate, runtime; |
| 4754 __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 4755 __ ldr(r0, MemOperand(r4, StandardFrameConstants::kContextOffset)); |
| 4756 __ cmp(r0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 4757 __ b(eq, &adaptor_frame); |
| 4758 |
| 4759 // No adaptor, parameter count = argument count. |
| 4760 __ mov(r5, r2); |
| 4761 __ mov(r6, r2); |
| 4762 __ b(&try_allocate); |
| 4763 |
| 4764 // We have an adaptor frame. Patch the parameters pointer. |
| 4765 __ bind(&adaptor_frame); |
| 4766 __ ldr(r5, MemOperand(r4, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4767 __ add(r4, r4, Operand(r5, LSL, 1)); |
| 4768 __ add(r3, r4, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 4769 |
| 4770 // r5 = argument count (tagged) |
| 4771 // r6 = parameter count (tagged) |
| 4772 // Compute the mapped parameter count = min(r6, r5) in r6. |
| 4773 __ mov(r6, r2); |
| 4774 __ cmp(r6, Operand(r5)); |
| 4775 __ mov(r6, Operand(r5), LeaveCC, gt); |
| 4776 |
| 4777 __ bind(&try_allocate); |
| 4778 |
| 4779 // Compute the sizes of backing store, parameter map, and arguments object. |
| 4780 // 1. Parameter map, has 2 extra words containing context and backing store. |
| 4781 const int kParameterMapHeaderSize = |
| 4782 FixedArray::kHeaderSize + 2 * kPointerSize; |
| 4783 // If there are no mapped parameters, we do not need the parameter_map. |
| 4784 __ cmp(r6, Operand(Smi::FromInt(0))); |
| 4785 __ mov(r9, Operand::Zero(), LeaveCC, eq); |
| 4786 __ mov(r9, Operand(r6, LSL, 1), LeaveCC, ne); |
| 4787 __ add(r9, r9, Operand(kParameterMapHeaderSize), LeaveCC, ne); |
| 4788 |
| 4789 // 2. Backing store. |
| 4790 __ add(r9, r9, Operand(r5, LSL, 1)); |
| 4791 __ add(r9, r9, Operand(FixedArray::kHeaderSize)); |
| 4792 |
| 4793 // 3. Arguments object. |
| 4794 __ add(r9, r9, Operand(JSSloppyArgumentsObject::kSize)); |
| 4795 |
| 4796 // Do the allocation of all three objects in one go. |
| 4797 __ Allocate(r9, r0, r9, r4, &runtime, TAG_OBJECT); |
| 4798 |
| 4799 // r0 = address of new object(s) (tagged) |
| 4800 // r2 = argument count (smi-tagged) |
| 4801 // Get the arguments boilerplate from the current native context into r4. |
| 4802 const int kNormalOffset = |
| 4803 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); |
| 4804 const int kAliasedOffset = |
| 4805 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); |
| 4806 |
| 4807 __ ldr(r4, NativeContextMemOperand()); |
| 4808 __ cmp(r6, Operand::Zero()); |
| 4809 __ ldr(r4, MemOperand(r4, kNormalOffset), eq); |
| 4810 __ ldr(r4, MemOperand(r4, kAliasedOffset), ne); |
| 4811 |
| 4812 // r0 = address of new object (tagged) |
| 4813 // r2 = argument count (smi-tagged) |
| 4814 // r4 = address of arguments map (tagged) |
| 4815 // r6 = mapped parameter count (tagged) |
| 4816 __ str(r4, FieldMemOperand(r0, JSObject::kMapOffset)); |
| 4817 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); |
| 4818 __ str(r9, FieldMemOperand(r0, JSObject::kPropertiesOffset)); |
| 4819 __ str(r9, FieldMemOperand(r0, JSObject::kElementsOffset)); |
| 4820 |
| 4821 // Set up the callee in-object property. |
| 4822 __ AssertNotSmi(r1); |
| 4823 __ str(r1, FieldMemOperand(r0, JSSloppyArgumentsObject::kCalleeOffset)); |
| 4824 |
| 4825 // Use the length (smi tagged) and set that as an in-object property too. |
| 4826 __ AssertSmi(r5); |
| 4827 __ str(r5, FieldMemOperand(r0, JSSloppyArgumentsObject::kLengthOffset)); |
| 4828 |
| 4829 // Set up the elements pointer in the allocated arguments object. |
| 4830 // If we allocated a parameter map, r4 will point there, otherwise |
| 4831 // it will point to the backing store. |
| 4832 __ add(r4, r0, Operand(JSSloppyArgumentsObject::kSize)); |
| 4833 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); |
| 4834 |
| 4835 // r0 = address of new object (tagged) |
| 4836 // r2 = argument count (tagged) |
| 4837 // r4 = address of parameter map or backing store (tagged) |
| 4838 // r6 = mapped parameter count (tagged) |
| 4839 // Initialize parameter map. If there are no mapped arguments, we're done. |
| 4840 Label skip_parameter_map; |
| 4841 __ cmp(r6, Operand(Smi::FromInt(0))); |
| 4842 // Move backing store address to r1, because it is |
| 4843 // expected there when filling in the unmapped arguments. |
| 4844 __ mov(r1, r4, LeaveCC, eq); |
| 4845 __ b(eq, &skip_parameter_map); |
| 4846 |
| 4847 __ LoadRoot(r5, Heap::kSloppyArgumentsElementsMapRootIndex); |
| 4848 __ str(r5, FieldMemOperand(r4, FixedArray::kMapOffset)); |
| 4849 __ add(r5, r6, Operand(Smi::FromInt(2))); |
| 4850 __ str(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
| 4851 __ str(cp, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize)); |
| 4852 __ add(r5, r4, Operand(r6, LSL, 1)); |
| 4853 __ add(r5, r5, Operand(kParameterMapHeaderSize)); |
| 4854 __ str(r5, FieldMemOperand(r4, FixedArray::kHeaderSize + 1 * kPointerSize)); |
| 4855 |
| 4856 // Copy the parameter slots and the holes in the arguments. |
| 4857 // We need to fill in mapped_parameter_count slots. They index the context, |
| 4858 // where parameters are stored in reverse order, at |
| 4859 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |
| 4860 // The mapped parameter thus need to get indices |
| 4861 // MIN_CONTEXT_SLOTS+parameter_count-1 .. |
| 4862 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |
| 4863 // We loop from right to left. |
| 4864 Label parameters_loop, parameters_test; |
| 4865 __ mov(r5, r6); |
| 4866 __ add(r9, r2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); |
| 4867 __ sub(r9, r9, Operand(r6)); |
| 4868 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 4869 __ add(r1, r4, Operand(r5, LSL, 1)); |
| 4870 __ add(r1, r1, Operand(kParameterMapHeaderSize)); |
| 4871 |
| 4872 // r1 = address of backing store (tagged) |
| 4873 // r4 = address of parameter map (tagged), which is also the address of new |
| 4874 // object + Heap::kSloppyArgumentsObjectSize (tagged) |
| 4875 // r0 = temporary scratch (a.o., for address calculation) |
| 4876 // r5 = loop variable (tagged) |
| 4877 // ip = the hole value |
| 4878 __ jmp(¶meters_test); |
| 4879 |
| 4880 __ bind(¶meters_loop); |
| 4881 __ sub(r5, r5, Operand(Smi::FromInt(1))); |
| 4882 __ mov(r0, Operand(r5, LSL, 1)); |
| 4883 __ add(r0, r0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); |
| 4884 __ str(r9, MemOperand(r4, r0)); |
| 4885 __ sub(r0, r0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); |
| 4886 __ str(ip, MemOperand(r1, r0)); |
| 4887 __ add(r9, r9, Operand(Smi::FromInt(1))); |
| 4888 __ bind(¶meters_test); |
| 4889 __ cmp(r5, Operand(Smi::FromInt(0))); |
| 4890 __ b(ne, ¶meters_loop); |
| 4891 |
| 4892 // Restore r0 = new object (tagged) and r5 = argument count (tagged). |
| 4893 __ sub(r0, r4, Operand(JSSloppyArgumentsObject::kSize)); |
| 4894 __ ldr(r5, FieldMemOperand(r0, JSSloppyArgumentsObject::kLengthOffset)); |
| 4895 |
| 4896 __ bind(&skip_parameter_map); |
| 4897 // r0 = address of new object (tagged) |
| 4898 // r1 = address of backing store (tagged) |
| 4899 // r5 = argument count (tagged) |
| 4900 // r6 = mapped parameter count (tagged) |
| 4901 // r9 = scratch |
| 4902 // Copy arguments header and remaining slots (if there are any). |
| 4903 __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); |
| 4904 __ str(r9, FieldMemOperand(r1, FixedArray::kMapOffset)); |
| 4905 __ str(r5, FieldMemOperand(r1, FixedArray::kLengthOffset)); |
| 4906 |
| 4907 Label arguments_loop, arguments_test; |
| 4908 __ sub(r3, r3, Operand(r6, LSL, 1)); |
| 4909 __ jmp(&arguments_test); |
| 4910 |
| 4911 __ bind(&arguments_loop); |
| 4912 __ sub(r3, r3, Operand(kPointerSize)); |
| 4913 __ ldr(r4, MemOperand(r3, 0)); |
| 4914 __ add(r9, r1, Operand(r6, LSL, 1)); |
| 4915 __ str(r4, FieldMemOperand(r9, FixedArray::kHeaderSize)); |
| 4916 __ add(r6, r6, Operand(Smi::FromInt(1))); |
| 4917 |
| 4918 __ bind(&arguments_test); |
| 4919 __ cmp(r6, Operand(r5)); |
| 4920 __ b(lt, &arguments_loop); |
| 4921 |
| 4922 // Return. |
| 4923 __ Ret(); |
| 4924 |
| 4925 // Do the runtime call to allocate the arguments object. |
| 4926 // r0 = address of new object (tagged) |
| 4927 // r5 = argument count (tagged) |
| 4928 __ bind(&runtime); |
| 4929 __ Push(r1, r3, r5); |
| 4930 __ TailCallRuntime(Runtime::kNewSloppyArguments); |
| 4931 } |
| 4932 |
| 4933 |
4950 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { | 4934 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
4951 // ----------- S t a t e ------------- | 4935 // ----------- S t a t e ------------- |
4952 // -- r1 : function | 4936 // -- r1 : function |
4953 // -- cp : context | 4937 // -- cp : context |
4954 // -- fp : frame pointer | 4938 // -- fp : frame pointer |
4955 // -- lr : return address | 4939 // -- lr : return address |
4956 // ----------------------------------- | 4940 // ----------------------------------- |
4957 __ AssertFunction(r1); | 4941 __ AssertFunction(r1); |
4958 | 4942 |
4959 // For Ignition we need to skip all possible handler/stub frames until | 4943 // For Ignition we need to skip all possible handler/stub frames until |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5526 kStackUnwindSpace, NULL, return_value_operand, NULL); | 5510 kStackUnwindSpace, NULL, return_value_operand, NULL); |
5527 } | 5511 } |
5528 | 5512 |
5529 | 5513 |
5530 #undef __ | 5514 #undef __ |
5531 | 5515 |
5532 } // namespace internal | 5516 } // namespace internal |
5533 } // namespace v8 | 5517 } // namespace v8 |
5534 | 5518 |
5535 #endif // V8_TARGET_ARCH_ARM | 5519 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |