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 |
1492 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1713 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1493 // Return address is in lr. | 1714 // Return address is in lr. |
1494 Label slow; | 1715 Label slow; |
1495 | 1716 |
1496 Register receiver = LoadDescriptor::ReceiverRegister(); | 1717 Register receiver = LoadDescriptor::ReceiverRegister(); |
1497 Register key = LoadDescriptor::NameRegister(); | 1718 Register key = LoadDescriptor::NameRegister(); |
1498 | 1719 |
1499 // Check that the key is an array index, that is Uint32. | 1720 // Check that the key is an array index, that is Uint32. |
1500 __ NonNegativeSmiTst(key); | 1721 __ NonNegativeSmiTst(key); |
1501 __ b(ne, &slow); | 1722 __ b(ne, &slow); |
(...skipping 3217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4719 __ Push(r0, r2, r1); | 4940 __ Push(r0, r2, r1); |
4720 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4941 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4721 __ mov(r3, r0); | 4942 __ mov(r3, r0); |
4722 __ Pop(r0, r2); | 4943 __ Pop(r0, r2); |
4723 } | 4944 } |
4724 __ jmp(&done_allocate); | 4945 __ jmp(&done_allocate); |
4725 } | 4946 } |
4726 } | 4947 } |
4727 | 4948 |
4728 | 4949 |
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 | |
4934 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { | 4950 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
4935 // ----------- S t a t e ------------- | 4951 // ----------- S t a t e ------------- |
4936 // -- r1 : function | 4952 // -- r1 : function |
4937 // -- cp : context | 4953 // -- cp : context |
4938 // -- fp : frame pointer | 4954 // -- fp : frame pointer |
4939 // -- lr : return address | 4955 // -- lr : return address |
4940 // ----------------------------------- | 4956 // ----------------------------------- |
4941 __ AssertFunction(r1); | 4957 __ AssertFunction(r1); |
4942 | 4958 |
4943 // For Ignition we need to skip all possible handler/stub frames until | 4959 // 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... |
5510 kStackUnwindSpace, NULL, return_value_operand, NULL); | 5526 kStackUnwindSpace, NULL, return_value_operand, NULL); |
5511 } | 5527 } |
5512 | 5528 |
5513 | 5529 |
5514 #undef __ | 5530 #undef __ |
5515 | 5531 |
5516 } // namespace internal | 5532 } // namespace internal |
5517 } // namespace v8 | 5533 } // namespace v8 |
5518 | 5534 |
5519 #endif // V8_TARGET_ARCH_ARM | 5535 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |