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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 | 1577 |
1578 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 1578 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
1579 // by calling the runtime system. | 1579 // by calling the runtime system. |
1580 __ bind(&slow); | 1580 __ bind(&slow); |
1581 __ push(a1); | 1581 __ push(a1); |
1582 __ TailCallRuntime(Runtime::kArguments, 1, 1); | 1582 __ TailCallRuntime(Runtime::kArguments, 1, 1); |
1583 } | 1583 } |
1584 | 1584 |
1585 | 1585 |
1586 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 1586 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
1587 // sp[0] : number of parameters | 1587 // a1 : function |
1588 // sp[4] : receiver displacement | 1588 // a2 : number of parameters (tagged) |
1589 // sp[8] : function | 1589 // a3 : parameters pointer |
| 1590 |
| 1591 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function())); |
| 1592 DCHECK(a2.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1593 DCHECK(a3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
1590 | 1594 |
1591 // Check if the calling frame is an arguments adaptor frame. | 1595 // Check if the calling frame is an arguments adaptor frame. |
1592 Label runtime; | 1596 Label runtime; |
1593 __ ld(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1597 __ ld(a4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1594 __ ld(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); | 1598 __ ld(a0, MemOperand(a4, StandardFrameConstants::kContextOffset)); |
1595 __ Branch(&runtime, | 1599 __ Branch(&runtime, ne, a0, |
1596 ne, | |
1597 a2, | |
1598 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1600 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
1599 | 1601 |
1600 // Patch the arguments.length and the parameters pointer in the current frame. | 1602 // Patch the arguments.length and the parameters pointer in the current frame. |
1601 __ ld(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1603 __ ld(a2, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1602 __ sd(a2, MemOperand(sp, 0 * kPointerSize)); | |
1603 __ SmiScale(a7, a2, kPointerSizeLog2); | 1604 __ SmiScale(a7, a2, kPointerSizeLog2); |
1604 __ Daddu(a3, a3, Operand(a7)); | 1605 __ Daddu(a4, a4, Operand(a7)); |
1605 __ daddiu(a3, a3, StandardFrameConstants::kCallerSPOffset); | 1606 __ daddiu(a3, a4, StandardFrameConstants::kCallerSPOffset); |
1606 __ sd(a3, MemOperand(sp, 1 * kPointerSize)); | |
1607 | 1607 |
1608 __ bind(&runtime); | 1608 __ bind(&runtime); |
| 1609 __ Push(a1, a3, a2); |
1609 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 1610 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1610 } | 1611 } |
1611 | 1612 |
1612 | 1613 |
1613 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 1614 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
1614 // Stack layout: | 1615 // a1 : function |
1615 // sp[0] : number of parameters (tagged) | 1616 // a2 : number of parameters (tagged) |
1616 // sp[4] : address of receiver argument | 1617 // a3 : parameters pointer |
1617 // sp[8] : function | |
1618 // Registers used over whole function: | 1618 // Registers used over whole function: |
1619 // a6 : allocated object (tagged) | 1619 // a5 : arguments count (tagged) |
1620 // t1 : mapped parameter count (tagged) | 1620 // a6 : mapped parameter count (tagged) |
1621 | 1621 |
1622 __ ld(a1, MemOperand(sp, 0 * kPointerSize)); | 1622 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function())); |
1623 // a1 = parameter count (tagged) | 1623 DCHECK(a2.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1624 DCHECK(a3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
1624 | 1625 |
1625 // Check if the calling frame is an arguments adaptor frame. | 1626 // Check if the calling frame is an arguments adaptor frame. |
1626 Label runtime; | 1627 Label adaptor_frame, try_allocate, runtime; |
1627 Label adaptor_frame, try_allocate; | 1628 __ ld(a4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1628 __ ld(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1629 __ ld(a0, MemOperand(a4, StandardFrameConstants::kContextOffset)); |
1629 __ ld(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); | 1630 __ Branch(&adaptor_frame, eq, a0, |
1630 __ Branch(&adaptor_frame, | |
1631 eq, | |
1632 a2, | |
1633 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1631 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
1634 | 1632 |
1635 // No adaptor, parameter count = argument count. | 1633 // No adaptor, parameter count = argument count. |
1636 __ mov(a2, a1); | 1634 __ mov(a5, a2); |
1637 __ Branch(&try_allocate); | 1635 __ Branch(USE_DELAY_SLOT, &try_allocate); |
| 1636 __ mov(a6, a2); // In delay slot. |
1638 | 1637 |
1639 // We have an adaptor frame. Patch the parameters pointer. | 1638 // We have an adaptor frame. Patch the parameters pointer. |
1640 __ bind(&adaptor_frame); | 1639 __ bind(&adaptor_frame); |
1641 __ ld(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1640 __ ld(a5, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1642 __ SmiScale(t2, a2, kPointerSizeLog2); | 1641 __ SmiScale(t2, a5, kPointerSizeLog2); |
1643 __ Daddu(a3, a3, Operand(t2)); | 1642 __ Daddu(a4, a4, Operand(t2)); |
1644 __ Daddu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset)); | 1643 __ Daddu(a3, a4, Operand(StandardFrameConstants::kCallerSPOffset)); |
1645 __ sd(a3, MemOperand(sp, 1 * kPointerSize)); | |
1646 | 1644 |
1647 // a1 = parameter count (tagged) | 1645 // a5 = argument count (tagged) |
1648 // a2 = argument count (tagged) | 1646 // a6 = parameter count (tagged) |
1649 // Compute the mapped parameter count = min(a1, a2) in a1. | 1647 // Compute the mapped parameter count = min(a6, a5) in a6. |
1650 Label skip_min; | 1648 __ mov(a6, a2); |
1651 __ Branch(&skip_min, lt, a1, Operand(a2)); | 1649 __ Branch(&try_allocate, le, a6, Operand(a5)); |
1652 __ mov(a1, a2); | 1650 __ mov(a6, a5); |
1653 __ bind(&skip_min); | |
1654 | 1651 |
1655 __ bind(&try_allocate); | 1652 __ bind(&try_allocate); |
1656 | 1653 |
1657 // Compute the sizes of backing store, parameter map, and arguments object. | 1654 // Compute the sizes of backing store, parameter map, and arguments object. |
1658 // 1. Parameter map, has 2 extra words containing context and backing store. | 1655 // 1. Parameter map, has 2 extra words containing context and backing store. |
1659 const int kParameterMapHeaderSize = | 1656 const int kParameterMapHeaderSize = |
1660 FixedArray::kHeaderSize + 2 * kPointerSize; | 1657 FixedArray::kHeaderSize + 2 * kPointerSize; |
1661 // If there are no mapped parameters, we do not need the parameter_map. | 1658 // If there are no mapped parameters, we do not need the parameter_map. |
1662 Label param_map_size; | 1659 Label param_map_size; |
1663 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); | 1660 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); |
1664 __ Branch(USE_DELAY_SLOT, ¶m_map_size, eq, a1, Operand(zero_reg)); | 1661 __ Branch(USE_DELAY_SLOT, ¶m_map_size, eq, a6, Operand(zero_reg)); |
1665 __ mov(t1, zero_reg); // In delay slot: param map size = 0 when a1 == 0. | 1662 __ mov(t1, zero_reg); // In delay slot: param map size = 0 when a6 == 0. |
1666 __ SmiScale(t1, a1, kPointerSizeLog2); | 1663 __ SmiScale(t1, a6, kPointerSizeLog2); |
1667 __ daddiu(t1, t1, kParameterMapHeaderSize); | 1664 __ daddiu(t1, t1, kParameterMapHeaderSize); |
1668 __ bind(¶m_map_size); | 1665 __ bind(¶m_map_size); |
1669 | 1666 |
1670 // 2. Backing store. | 1667 // 2. Backing store. |
1671 __ SmiScale(t2, a2, kPointerSizeLog2); | 1668 __ SmiScale(t2, a5, kPointerSizeLog2); |
1672 __ Daddu(t1, t1, Operand(t2)); | 1669 __ Daddu(t1, t1, Operand(t2)); |
1673 __ Daddu(t1, t1, Operand(FixedArray::kHeaderSize)); | 1670 __ Daddu(t1, t1, Operand(FixedArray::kHeaderSize)); |
1674 | 1671 |
1675 // 3. Arguments object. | 1672 // 3. Arguments object. |
1676 __ Daddu(t1, t1, Operand(Heap::kSloppyArgumentsObjectSize)); | 1673 __ Daddu(t1, t1, Operand(Heap::kSloppyArgumentsObjectSize)); |
1677 | 1674 |
1678 // Do the allocation of all three objects in one go. | 1675 // Do the allocation of all three objects in one go. |
1679 __ Allocate(t1, v0, a3, a4, &runtime, TAG_OBJECT); | 1676 __ Allocate(t1, v0, a4, t1, &runtime, TAG_OBJECT); |
1680 | 1677 |
1681 // v0 = address of new object(s) (tagged) | 1678 // v0 = address of new object(s) (tagged) |
1682 // a2 = argument count (smi-tagged) | 1679 // a2 = argument count (smi-tagged) |
1683 // Get the arguments boilerplate from the current native context into a4. | 1680 // Get the arguments boilerplate from the current native context into a4. |
1684 const int kNormalOffset = | 1681 const int kNormalOffset = |
1685 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); | 1682 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); |
1686 const int kAliasedOffset = | 1683 const int kAliasedOffset = |
1687 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); | 1684 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); |
1688 | 1685 |
1689 __ ld(a4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1686 __ ld(a4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1690 __ ld(a4, FieldMemOperand(a4, GlobalObject::kNativeContextOffset)); | 1687 __ ld(a4, FieldMemOperand(a4, GlobalObject::kNativeContextOffset)); |
1691 Label skip2_ne, skip2_eq; | 1688 Label skip2_ne, skip2_eq; |
1692 __ Branch(&skip2_ne, ne, a1, Operand(zero_reg)); | 1689 __ Branch(&skip2_ne, ne, a6, Operand(zero_reg)); |
1693 __ ld(a4, MemOperand(a4, kNormalOffset)); | 1690 __ ld(a4, MemOperand(a4, kNormalOffset)); |
1694 __ bind(&skip2_ne); | 1691 __ bind(&skip2_ne); |
1695 | 1692 |
1696 __ Branch(&skip2_eq, eq, a1, Operand(zero_reg)); | 1693 __ Branch(&skip2_eq, eq, a6, Operand(zero_reg)); |
1697 __ ld(a4, MemOperand(a4, kAliasedOffset)); | 1694 __ ld(a4, MemOperand(a4, kAliasedOffset)); |
1698 __ bind(&skip2_eq); | 1695 __ bind(&skip2_eq); |
1699 | 1696 |
1700 // v0 = address of new object (tagged) | 1697 // v0 = address of new object (tagged) |
1701 // a1 = mapped parameter count (tagged) | |
1702 // a2 = argument count (smi-tagged) | 1698 // a2 = argument count (smi-tagged) |
1703 // a4 = address of arguments map (tagged) | 1699 // a4 = address of arguments map (tagged) |
| 1700 // a6 = mapped parameter count (tagged) |
1704 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset)); | 1701 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset)); |
1705 __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex); | 1702 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex); |
1706 __ sd(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 1703 __ sd(t1, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
1707 __ sd(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); | 1704 __ sd(t1, FieldMemOperand(v0, JSObject::kElementsOffset)); |
1708 | 1705 |
1709 // Set up the callee in-object property. | 1706 // Set up the callee in-object property. |
1710 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 1707 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
1711 __ ld(a3, MemOperand(sp, 2 * kPointerSize)); | 1708 __ AssertNotSmi(a1); |
1712 __ AssertNotSmi(a3); | |
1713 const int kCalleeOffset = JSObject::kHeaderSize + | 1709 const int kCalleeOffset = JSObject::kHeaderSize + |
1714 Heap::kArgumentsCalleeIndex * kPointerSize; | 1710 Heap::kArgumentsCalleeIndex * kPointerSize; |
1715 __ sd(a3, FieldMemOperand(v0, kCalleeOffset)); | 1711 __ sd(a1, FieldMemOperand(v0, kCalleeOffset)); |
1716 | 1712 |
1717 // Use the length (smi tagged) and set that as an in-object property too. | 1713 // Use the length (smi tagged) and set that as an in-object property too. |
| 1714 __ AssertSmi(a5); |
1718 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1715 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1719 const int kLengthOffset = JSObject::kHeaderSize + | 1716 const int kLengthOffset = JSObject::kHeaderSize + |
1720 Heap::kArgumentsLengthIndex * kPointerSize; | 1717 Heap::kArgumentsLengthIndex * kPointerSize; |
1721 __ sd(a2, FieldMemOperand(v0, kLengthOffset)); | 1718 __ sd(a5, FieldMemOperand(v0, kLengthOffset)); |
1722 | 1719 |
1723 // Set up the elements pointer in the allocated arguments object. | 1720 // Set up the elements pointer in the allocated arguments object. |
1724 // If we allocated a parameter map, a4 will point there, otherwise | 1721 // If we allocated a parameter map, a4 will point there, otherwise |
1725 // it will point to the backing store. | 1722 // it will point to the backing store. |
1726 __ Daddu(a4, v0, Operand(Heap::kSloppyArgumentsObjectSize)); | 1723 __ Daddu(a4, v0, Operand(Heap::kSloppyArgumentsObjectSize)); |
1727 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); | 1724 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); |
1728 | 1725 |
1729 // v0 = address of new object (tagged) | 1726 // v0 = address of new object (tagged) |
1730 // a1 = mapped parameter count (tagged) | |
1731 // a2 = argument count (tagged) | 1727 // a2 = argument count (tagged) |
1732 // a4 = address of parameter map or backing store (tagged) | 1728 // a4 = address of parameter map or backing store (tagged) |
| 1729 // a6 = mapped parameter count (tagged) |
1733 // Initialize parameter map. If there are no mapped arguments, we're done. | 1730 // Initialize parameter map. If there are no mapped arguments, we're done. |
1734 Label skip_parameter_map; | 1731 Label skip_parameter_map; |
1735 Label skip3; | 1732 Label skip3; |
1736 __ Branch(&skip3, ne, a1, Operand(Smi::FromInt(0))); | 1733 __ Branch(&skip3, ne, a6, Operand(Smi::FromInt(0))); |
1737 // Move backing store address to a3, because it is | 1734 // Move backing store address to a1, because it is |
1738 // expected there when filling in the unmapped arguments. | 1735 // expected there when filling in the unmapped arguments. |
1739 __ mov(a3, a4); | 1736 __ mov(a1, a4); |
1740 __ bind(&skip3); | 1737 __ bind(&skip3); |
1741 | 1738 |
1742 __ Branch(&skip_parameter_map, eq, a1, Operand(Smi::FromInt(0))); | 1739 __ Branch(&skip_parameter_map, eq, a6, Operand(Smi::FromInt(0))); |
1743 | 1740 |
1744 __ LoadRoot(a6, Heap::kSloppyArgumentsElementsMapRootIndex); | 1741 __ LoadRoot(a5, Heap::kSloppyArgumentsElementsMapRootIndex); |
1745 __ sd(a6, FieldMemOperand(a4, FixedArray::kMapOffset)); | 1742 __ sd(a5, FieldMemOperand(a4, FixedArray::kMapOffset)); |
1746 __ Daddu(a6, a1, Operand(Smi::FromInt(2))); | 1743 __ Daddu(a5, a6, Operand(Smi::FromInt(2))); |
1747 __ sd(a6, FieldMemOperand(a4, FixedArray::kLengthOffset)); | 1744 __ sd(a5, FieldMemOperand(a4, FixedArray::kLengthOffset)); |
1748 __ sd(cp, FieldMemOperand(a4, FixedArray::kHeaderSize + 0 * kPointerSize)); | 1745 __ sd(cp, FieldMemOperand(a4, FixedArray::kHeaderSize + 0 * kPointerSize)); |
1749 __ SmiScale(t2, a1, kPointerSizeLog2); | 1746 __ SmiScale(t2, a6, kPointerSizeLog2); |
1750 __ Daddu(a6, a4, Operand(t2)); | 1747 __ Daddu(a5, a4, Operand(t2)); |
1751 __ Daddu(a6, a6, Operand(kParameterMapHeaderSize)); | 1748 __ Daddu(a5, a5, Operand(kParameterMapHeaderSize)); |
1752 __ sd(a6, FieldMemOperand(a4, FixedArray::kHeaderSize + 1 * kPointerSize)); | 1749 __ sd(a5, FieldMemOperand(a4, FixedArray::kHeaderSize + 1 * kPointerSize)); |
1753 | 1750 |
1754 // Copy the parameter slots and the holes in the arguments. | 1751 // Copy the parameter slots and the holes in the arguments. |
1755 // We need to fill in mapped_parameter_count slots. They index the context, | 1752 // We need to fill in mapped_parameter_count slots. They index the context, |
1756 // where parameters are stored in reverse order, at | 1753 // where parameters are stored in reverse order, at |
1757 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | 1754 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |
1758 // The mapped parameter thus need to get indices | 1755 // The mapped parameter thus need to get indices |
1759 // MIN_CONTEXT_SLOTS+parameter_count-1 .. | 1756 // MIN_CONTEXT_SLOTS+parameter_count-1 .. |
1760 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | 1757 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |
1761 // We loop from right to left. | 1758 // We loop from right to left. |
1762 Label parameters_loop, parameters_test; | 1759 Label parameters_loop, parameters_test; |
1763 __ mov(a6, a1); | 1760 __ mov(a5, a6); |
1764 __ ld(t1, MemOperand(sp, 0 * kPointerSize)); | 1761 __ Daddu(t1, a2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); |
1765 __ Daddu(t1, t1, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); | 1762 __ Dsubu(t1, t1, Operand(a6)); |
1766 __ Dsubu(t1, t1, Operand(a1)); | |
1767 __ LoadRoot(a7, Heap::kTheHoleValueRootIndex); | 1763 __ LoadRoot(a7, Heap::kTheHoleValueRootIndex); |
1768 __ SmiScale(t2, a6, kPointerSizeLog2); | 1764 __ SmiScale(t2, a5, kPointerSizeLog2); |
1769 __ Daddu(a3, a4, Operand(t2)); | 1765 __ Daddu(a1, a4, Operand(t2)); |
1770 __ Daddu(a3, a3, Operand(kParameterMapHeaderSize)); | 1766 __ Daddu(a1, a1, Operand(kParameterMapHeaderSize)); |
1771 | 1767 |
1772 // a6 = loop variable (tagged) | 1768 // a1 = address of backing store (tagged) |
1773 // a1 = mapping index (tagged) | |
1774 // a3 = address of backing store (tagged) | |
1775 // a4 = address of parameter map (tagged) | 1769 // a4 = address of parameter map (tagged) |
1776 // a5 = temporary scratch (a.o., for address calculation) | 1770 // a0 = temporary scratch (a.o., for address calculation) |
| 1771 // t1 = loop variable (tagged) |
1777 // a7 = the hole value | 1772 // a7 = the hole value |
1778 __ jmp(¶meters_test); | 1773 __ jmp(¶meters_test); |
1779 | 1774 |
1780 __ bind(¶meters_loop); | 1775 __ bind(¶meters_loop); |
1781 | 1776 __ Dsubu(a5, a5, Operand(Smi::FromInt(1))); |
1782 __ Dsubu(a6, a6, Operand(Smi::FromInt(1))); | 1777 __ SmiScale(a0, a5, kPointerSizeLog2); |
1783 __ SmiScale(a5, a6, kPointerSizeLog2); | 1778 __ Daddu(a0, a0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); |
1784 __ Daddu(a5, a5, Operand(kParameterMapHeaderSize - kHeapObjectTag)); | 1779 __ Daddu(t2, a4, a0); |
1785 __ Daddu(t2, a4, a5); | |
1786 __ sd(t1, MemOperand(t2)); | 1780 __ sd(t1, MemOperand(t2)); |
1787 __ Dsubu(a5, a5, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); | 1781 __ Dsubu(a0, a0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); |
1788 __ Daddu(t2, a3, a5); | 1782 __ Daddu(t2, a1, a0); |
1789 __ sd(a7, MemOperand(t2)); | 1783 __ sd(a7, MemOperand(t2)); |
1790 __ Daddu(t1, t1, Operand(Smi::FromInt(1))); | 1784 __ Daddu(t1, t1, Operand(Smi::FromInt(1))); |
1791 __ bind(¶meters_test); | 1785 __ bind(¶meters_test); |
1792 __ Branch(¶meters_loop, ne, a6, Operand(Smi::FromInt(0))); | 1786 __ Branch(¶meters_loop, ne, a5, Operand(Smi::FromInt(0))); |
| 1787 |
| 1788 // Restore t1 = argument count (tagged). |
| 1789 __ ld(a5, FieldMemOperand(v0, kLengthOffset)); |
1793 | 1790 |
1794 __ bind(&skip_parameter_map); | 1791 __ bind(&skip_parameter_map); |
1795 // a2 = argument count (tagged) | 1792 // v0 = address of new object (tagged) |
1796 // a3 = address of backing store (tagged) | 1793 // a1 = address of backing store (tagged) |
1797 // a5 = scratch | 1794 // a5 = argument count (tagged) |
| 1795 // a6 = mapped parameter count (tagged) |
| 1796 // t1 = scratch |
1798 // Copy arguments header and remaining slots (if there are any). | 1797 // Copy arguments header and remaining slots (if there are any). |
1799 __ LoadRoot(a5, Heap::kFixedArrayMapRootIndex); | 1798 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex); |
1800 __ sd(a5, FieldMemOperand(a3, FixedArray::kMapOffset)); | 1799 __ sd(t1, FieldMemOperand(a1, FixedArray::kMapOffset)); |
1801 __ sd(a2, FieldMemOperand(a3, FixedArray::kLengthOffset)); | 1800 __ sd(a5, FieldMemOperand(a1, FixedArray::kLengthOffset)); |
1802 | 1801 |
1803 Label arguments_loop, arguments_test; | 1802 Label arguments_loop, arguments_test; |
1804 __ mov(t1, a1); | 1803 __ SmiScale(t2, a6, kPointerSizeLog2); |
1805 __ ld(a4, MemOperand(sp, 1 * kPointerSize)); | 1804 __ Dsubu(a3, a3, Operand(t2)); |
1806 __ SmiScale(t2, t1, kPointerSizeLog2); | |
1807 __ Dsubu(a4, a4, Operand(t2)); | |
1808 __ jmp(&arguments_test); | 1805 __ jmp(&arguments_test); |
1809 | 1806 |
1810 __ bind(&arguments_loop); | 1807 __ bind(&arguments_loop); |
1811 __ Dsubu(a4, a4, Operand(kPointerSize)); | 1808 __ Dsubu(a3, a3, Operand(kPointerSize)); |
1812 __ ld(a6, MemOperand(a4, 0)); | 1809 __ ld(a4, MemOperand(a3, 0)); |
1813 __ SmiScale(t2, t1, kPointerSizeLog2); | 1810 __ SmiScale(t2, a6, kPointerSizeLog2); |
1814 __ Daddu(a5, a3, Operand(t2)); | 1811 __ Daddu(t1, a1, Operand(t2)); |
1815 __ sd(a6, FieldMemOperand(a5, FixedArray::kHeaderSize)); | 1812 __ sd(a4, FieldMemOperand(t1, FixedArray::kHeaderSize)); |
1816 __ Daddu(t1, t1, Operand(Smi::FromInt(1))); | 1813 __ Daddu(a6, a6, Operand(Smi::FromInt(1))); |
1817 | 1814 |
1818 __ bind(&arguments_test); | 1815 __ bind(&arguments_test); |
1819 __ Branch(&arguments_loop, lt, t1, Operand(a2)); | 1816 __ Branch(&arguments_loop, lt, a6, Operand(a5)); |
1820 | 1817 |
1821 // Return and remove the on-stack parameters. | 1818 // Return. |
1822 __ DropAndRet(3); | 1819 __ Ret(); |
1823 | 1820 |
1824 // Do the runtime call to allocate the arguments object. | 1821 // Do the runtime call to allocate the arguments object. |
1825 // a2 = argument count (tagged) | 1822 // a5 = argument count (tagged) |
1826 __ bind(&runtime); | 1823 __ bind(&runtime); |
1827 __ sd(a2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count. | 1824 __ Push(a1, a3, a5); |
1828 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 1825 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1829 } | 1826 } |
1830 | 1827 |
1831 | 1828 |
1832 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1829 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1833 // Return address is in ra. | 1830 // Return address is in ra. |
1834 Label slow; | 1831 Label slow; |
1835 | 1832 |
1836 Register receiver = LoadDescriptor::ReceiverRegister(); | 1833 Register receiver = LoadDescriptor::ReceiverRegister(); |
1837 Register key = LoadDescriptor::NameRegister(); | 1834 Register key = LoadDescriptor::NameRegister(); |
1838 | 1835 |
1839 // Check that the key is an array index, that is Uint32. | 1836 // Check that the key is an array index, that is Uint32. |
1840 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); | 1837 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); |
1841 __ Branch(&slow, ne, t0, Operand(zero_reg)); | 1838 __ Branch(&slow, ne, t0, Operand(zero_reg)); |
1842 | 1839 |
1843 // Everything is fine, call runtime. | 1840 // Everything is fine, call runtime. |
1844 __ Push(receiver, key); // Receiver, key. | 1841 __ Push(receiver, key); // Receiver, key. |
1845 | 1842 |
1846 // Perform tail call to the entry. | 1843 // Perform tail call to the entry. |
1847 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1); | 1844 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1); |
1848 | 1845 |
1849 __ bind(&slow); | 1846 __ bind(&slow); |
1850 PropertyAccessCompiler::TailCallBuiltin( | 1847 PropertyAccessCompiler::TailCallBuiltin( |
1851 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 1848 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
1852 } | 1849 } |
1853 | 1850 |
1854 | 1851 |
1855 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 1852 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
1856 // sp[0] : number of parameters | 1853 // a1 : function |
1857 // sp[4] : receiver displacement | 1854 // a2 : number of parameters (tagged) |
1858 // sp[8] : function | 1855 // a3 : parameters pointer |
| 1856 |
| 1857 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function())); |
| 1858 DCHECK(a2.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1859 DCHECK(a3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
| 1860 |
1859 // Check if the calling frame is an arguments adaptor frame. | 1861 // Check if the calling frame is an arguments adaptor frame. |
1860 Label adaptor_frame, try_allocate, runtime; | 1862 Label try_allocate, runtime; |
1861 __ ld(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1863 __ ld(a4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1862 __ ld(a3, MemOperand(a2, StandardFrameConstants::kContextOffset)); | 1864 __ ld(a0, MemOperand(a4, StandardFrameConstants::kContextOffset)); |
1863 __ Branch(&adaptor_frame, | 1865 __ Branch(&try_allocate, ne, a0, |
1864 eq, | |
1865 a3, | |
1866 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1866 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
1867 | 1867 |
1868 // Get the length from the frame. | |
1869 __ ld(a1, MemOperand(sp, 0)); | |
1870 __ Branch(&try_allocate); | |
1871 | |
1872 // Patch the arguments.length and the parameters pointer. | 1868 // Patch the arguments.length and the parameters pointer. |
1873 __ bind(&adaptor_frame); | 1869 __ ld(a2, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1874 __ ld(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1870 __ SmiScale(at, a2, kPointerSizeLog2); |
1875 __ sd(a1, MemOperand(sp, 0)); | 1871 __ Daddu(a4, a4, Operand(at)); |
1876 __ SmiScale(at, a1, kPointerSizeLog2); | 1872 __ Daddu(a3, a4, Operand(StandardFrameConstants::kCallerSPOffset)); |
1877 | |
1878 __ Daddu(a3, a2, Operand(at)); | |
1879 | |
1880 __ Daddu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset)); | |
1881 __ sd(a3, MemOperand(sp, 1 * kPointerSize)); | |
1882 | 1873 |
1883 // Try the new space allocation. Start out with computing the size | 1874 // Try the new space allocation. Start out with computing the size |
1884 // of the arguments object and the elements array in words. | 1875 // of the arguments object and the elements array in words. |
1885 Label add_arguments_object; | 1876 Label add_arguments_object; |
1886 __ bind(&try_allocate); | 1877 __ bind(&try_allocate); |
1887 __ Branch(&add_arguments_object, eq, a1, Operand(zero_reg)); | 1878 __ SmiUntag(t1, a2); |
1888 __ SmiUntag(a1); | 1879 __ Branch(&add_arguments_object, eq, a2, Operand(zero_reg)); |
1889 | 1880 |
1890 __ Daddu(a1, a1, Operand(FixedArray::kHeaderSize / kPointerSize)); | 1881 __ Daddu(t1, t1, Operand(FixedArray::kHeaderSize / kPointerSize)); |
1891 __ bind(&add_arguments_object); | 1882 __ bind(&add_arguments_object); |
1892 __ Daddu(a1, a1, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize)); | 1883 __ Daddu(t1, t1, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize)); |
1893 | 1884 |
1894 // Do the allocation of both objects in one go. | 1885 // Do the allocation of both objects in one go. |
1895 __ Allocate(a1, v0, a2, a3, &runtime, | 1886 __ Allocate(t1, v0, a4, a5, &runtime, |
1896 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); | 1887 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); |
1897 | 1888 |
1898 // Get the arguments boilerplate from the current native context. | 1889 // Get the arguments boilerplate from the current native context. |
1899 __ ld(a4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1890 __ ld(a4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1900 __ ld(a4, FieldMemOperand(a4, GlobalObject::kNativeContextOffset)); | 1891 __ ld(a4, FieldMemOperand(a4, GlobalObject::kNativeContextOffset)); |
1901 __ ld(a4, MemOperand(a4, Context::SlotOffset( | 1892 __ ld(a4, MemOperand(a4, Context::SlotOffset( |
1902 Context::STRICT_ARGUMENTS_MAP_INDEX))); | 1893 Context::STRICT_ARGUMENTS_MAP_INDEX))); |
1903 | 1894 |
1904 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset)); | 1895 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset)); |
1905 __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex); | 1896 __ LoadRoot(a5, Heap::kEmptyFixedArrayRootIndex); |
1906 __ sd(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 1897 __ sd(a5, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
1907 __ sd(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); | 1898 __ sd(a5, FieldMemOperand(v0, JSObject::kElementsOffset)); |
1908 | 1899 |
1909 // Get the length (smi tagged) and set that as an in-object property too. | 1900 // Get the length (smi tagged) and set that as an in-object property too. |
1910 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1901 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1911 __ ld(a1, MemOperand(sp, 0 * kPointerSize)); | 1902 __ AssertSmi(a2); |
1912 __ AssertSmi(a1); | 1903 __ sd(a2, |
1913 __ sd(a1, FieldMemOperand(v0, JSObject::kHeaderSize + | 1904 FieldMemOperand(v0, JSObject::kHeaderSize + |
1914 Heap::kArgumentsLengthIndex * kPointerSize)); | 1905 Heap::kArgumentsLengthIndex * kPointerSize)); |
1915 | 1906 |
1916 Label done; | 1907 Label done; |
1917 __ Branch(&done, eq, a1, Operand(zero_reg)); | 1908 __ Branch(&done, eq, a2, Operand(zero_reg)); |
1918 | |
1919 // Get the parameters pointer from the stack. | |
1920 __ ld(a2, MemOperand(sp, 1 * kPointerSize)); | |
1921 | 1909 |
1922 // Set up the elements pointer in the allocated arguments object and | 1910 // Set up the elements pointer in the allocated arguments object and |
1923 // initialize the header in the elements fixed array. | 1911 // initialize the header in the elements fixed array. |
1924 __ Daddu(a4, v0, Operand(Heap::kStrictArgumentsObjectSize)); | 1912 __ Daddu(a4, v0, Operand(Heap::kStrictArgumentsObjectSize)); |
1925 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); | 1913 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); |
1926 __ LoadRoot(a3, Heap::kFixedArrayMapRootIndex); | 1914 __ LoadRoot(a5, Heap::kFixedArrayMapRootIndex); |
1927 __ sd(a3, FieldMemOperand(a4, FixedArray::kMapOffset)); | 1915 __ sd(a5, FieldMemOperand(a4, FixedArray::kMapOffset)); |
1928 __ sd(a1, FieldMemOperand(a4, FixedArray::kLengthOffset)); | 1916 __ sd(a2, FieldMemOperand(a4, FixedArray::kLengthOffset)); |
1929 // Untag the length for the loop. | 1917 __ SmiUntag(a2); |
1930 __ SmiUntag(a1); | |
1931 | |
1932 | 1918 |
1933 // Copy the fixed array slots. | 1919 // Copy the fixed array slots. |
1934 Label loop; | 1920 Label loop; |
1935 // Set up a4 to point to the first array slot. | 1921 // Set up a4 to point to the first array slot. |
1936 __ Daddu(a4, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1922 __ Daddu(a4, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1937 __ bind(&loop); | 1923 __ bind(&loop); |
1938 // Pre-decrement a2 with kPointerSize on each iteration. | 1924 // Pre-decrement a3 with kPointerSize on each iteration. |
1939 // Pre-decrement in order to skip receiver. | 1925 // Pre-decrement in order to skip receiver. |
1940 __ Daddu(a2, a2, Operand(-kPointerSize)); | 1926 __ Daddu(a3, a3, Operand(-kPointerSize)); |
1941 __ ld(a3, MemOperand(a2)); | 1927 __ ld(a5, MemOperand(a3)); |
1942 // Post-increment a4 with kPointerSize on each iteration. | 1928 // Post-increment a4 with kPointerSize on each iteration. |
1943 __ sd(a3, MemOperand(a4)); | 1929 __ sd(a5, MemOperand(a4)); |
1944 __ Daddu(a4, a4, Operand(kPointerSize)); | 1930 __ Daddu(a4, a4, Operand(kPointerSize)); |
1945 __ Dsubu(a1, a1, Operand(1)); | 1931 __ Dsubu(a2, a2, Operand(1)); |
1946 __ Branch(&loop, ne, a1, Operand(zero_reg)); | 1932 __ Branch(&loop, ne, a2, Operand(zero_reg)); |
1947 | 1933 |
1948 // Return and remove the on-stack parameters. | 1934 // Return. |
1949 __ bind(&done); | 1935 __ bind(&done); |
1950 __ DropAndRet(3); | 1936 __ Ret(); |
1951 | 1937 |
1952 // Do the runtime call to allocate the arguments object. | 1938 // Do the runtime call to allocate the arguments object. |
1953 __ bind(&runtime); | 1939 __ bind(&runtime); |
| 1940 __ Push(a1, a3, a2); |
1954 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); | 1941 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
1955 } | 1942 } |
1956 | 1943 |
1957 | 1944 |
1958 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1945 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1959 // Just jump directly to runtime if native RegExp is not selected at compile | 1946 // Just jump directly to runtime if native RegExp is not selected at compile |
1960 // time or if regexp entry in generated code is turned off runtime switch or | 1947 // time or if regexp entry in generated code is turned off runtime switch or |
1961 // at compilation. | 1948 // at compilation. |
1962 #ifdef V8_INTERPRETED_REGEXP | 1949 #ifdef V8_INTERPRETED_REGEXP |
1963 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 1950 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
(...skipping 3812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5776 MemOperand(fp, 6 * kPointerSize), NULL); | 5763 MemOperand(fp, 6 * kPointerSize), NULL); |
5777 } | 5764 } |
5778 | 5765 |
5779 | 5766 |
5780 #undef __ | 5767 #undef __ |
5781 | 5768 |
5782 } // namespace internal | 5769 } // namespace internal |
5783 } // namespace v8 | 5770 } // namespace v8 |
5784 | 5771 |
5785 #endif // V8_TARGET_ARCH_MIPS64 | 5772 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |