Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 1361143005: MIPS: [turbofan] Call ArgumentsAccessStub to materialize arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/mips/interface-descriptors-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 1597 __ lw(t0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1594 __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); 1598 __ lw(a0, MemOperand(t0, 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 __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1603 __ lw(a2, MemOperand(t0, ArgumentsAdaptorFrameConstants::kLengthOffset));
1602 __ sw(a2, MemOperand(sp, 0 * kPointerSize));
1603 __ sll(t3, a2, 1); 1604 __ sll(t3, a2, 1);
1604 __ Addu(a3, a3, Operand(t3)); 1605 __ Addu(t0, t0, Operand(t3));
1605 __ addiu(a3, a3, StandardFrameConstants::kCallerSPOffset); 1606 __ addiu(a3, t0, StandardFrameConstants::kCallerSPOffset);
1606 __ sw(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 // t2 : allocated object (tagged) 1619 // t1 : arguments count (tagged)
1620 // t5 : mapped parameter count (tagged) 1620 // t2 : mapped parameter count (tagged)
1621 1621
1622 __ lw(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 __ lw(t0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1628 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 1629 __ lw(a0, MemOperand(t0, StandardFrameConstants::kContextOffset));
1629 __ lw(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(t1, a2);
1637 __ b(&try_allocate); 1635 __ Branch(USE_DELAY_SLOT, &try_allocate);
1638 __ nop(); // Branch delay slot nop. 1636 __ mov(t2, a2); // In delay slot.
1639 1637
1640 // We have an adaptor frame. Patch the parameters pointer. 1638 // We have an adaptor frame. Patch the parameters pointer.
1641 __ bind(&adaptor_frame); 1639 __ bind(&adaptor_frame);
1642 __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1640 __ lw(t1, MemOperand(t0, ArgumentsAdaptorFrameConstants::kLengthOffset));
1643 __ sll(t6, a2, 1); 1641 __ sll(t6, t1, 1);
1644 __ Addu(a3, a3, Operand(t6)); 1642 __ Addu(t0, t0, Operand(t6));
1645 __ Addu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset)); 1643 __ Addu(a3, t0, Operand(StandardFrameConstants::kCallerSPOffset));
1646 __ sw(a3, MemOperand(sp, 1 * kPointerSize));
1647 1644
1648 // a1 = parameter count (tagged) 1645 // t1 = argument count (tagged)
1649 // a2 = argument count (tagged) 1646 // t2 = parameter count (tagged)
1650 // Compute the mapped parameter count = min(a1, a2) in a1. 1647 // Compute the mapped parameter count = min(t2, t1) in t2.
1651 Label skip_min; 1648 Label skip_min;
1652 __ Branch(&skip_min, lt, a1, Operand(a2)); 1649 __ Branch(USE_DELAY_SLOT, &skip_min, lt, t2, Operand(t1));
1653 __ mov(a1, a2); 1650 __ mov(t2, a2); // In delay slot.
1651 __ mov(t2, t1);
1654 __ bind(&skip_min); 1652 __ bind(&skip_min);
1655 1653
1656 __ bind(&try_allocate); 1654 __ bind(&try_allocate);
1657 1655
1658 // Compute the sizes of backing store, parameter map, and arguments object. 1656 // Compute the sizes of backing store, parameter map, and arguments object.
1659 // 1. Parameter map, has 2 extra words containing context and backing store. 1657 // 1. Parameter map, has 2 extra words containing context and backing store.
1660 const int kParameterMapHeaderSize = 1658 const int kParameterMapHeaderSize =
1661 FixedArray::kHeaderSize + 2 * kPointerSize; 1659 FixedArray::kHeaderSize + 2 * kPointerSize;
1662 // If there are no mapped parameters, we do not need the parameter_map. 1660 // If there are no mapped parameters, we do not need the parameter_map.
1663 Label param_map_size; 1661 Label param_map_size;
1664 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); 1662 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0));
1665 __ Branch(USE_DELAY_SLOT, &param_map_size, eq, a1, Operand(zero_reg)); 1663 __ Branch(USE_DELAY_SLOT, &param_map_size, eq, t2, Operand(zero_reg));
1666 __ mov(t5, zero_reg); // In delay slot: param map size = 0 when a1 == 0. 1664 __ mov(t5, zero_reg); // In delay slot: param map size = 0 when a1 == 0.
1667 __ sll(t5, a1, 1); 1665 __ sll(t5, t2, 1);
1668 __ addiu(t5, t5, kParameterMapHeaderSize); 1666 __ addiu(t5, t5, kParameterMapHeaderSize);
1669 __ bind(&param_map_size); 1667 __ bind(&param_map_size);
1670 1668
1671 // 2. Backing store. 1669 // 2. Backing store.
1672 __ sll(t6, a2, 1); 1670 __ sll(t6, t1, 1);
1673 __ Addu(t5, t5, Operand(t6)); 1671 __ Addu(t5, t5, Operand(t6));
1674 __ Addu(t5, t5, Operand(FixedArray::kHeaderSize)); 1672 __ Addu(t5, t5, Operand(FixedArray::kHeaderSize));
1675 1673
1676 // 3. Arguments object. 1674 // 3. Arguments object.
1677 __ Addu(t5, t5, Operand(Heap::kSloppyArgumentsObjectSize)); 1675 __ Addu(t5, t5, Operand(Heap::kSloppyArgumentsObjectSize));
1678 1676
1679 // Do the allocation of all three objects in one go. 1677 // Do the allocation of all three objects in one go.
1680 __ Allocate(t5, v0, a3, t0, &runtime, TAG_OBJECT); 1678 __ Allocate(t5, v0, t0, t5, &runtime, TAG_OBJECT);
1681 1679
1682 // v0 = address of new object(s) (tagged) 1680 // v0 = address of new object(s) (tagged)
1683 // a2 = argument count (smi-tagged) 1681 // a2 = argument count (smi-tagged)
1684 // Get the arguments boilerplate from the current native context into t0. 1682 // Get the arguments boilerplate from the current native context into t0.
1685 const int kNormalOffset = 1683 const int kNormalOffset =
1686 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); 1684 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
1687 const int kAliasedOffset = 1685 const int kAliasedOffset =
1688 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); 1686 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
1689 1687
1690 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 1688 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
1691 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset)); 1689 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset));
1692 Label skip2_ne, skip2_eq; 1690 Label skip2_ne, skip2_eq;
1693 __ Branch(&skip2_ne, ne, a1, Operand(zero_reg)); 1691 __ Branch(&skip2_ne, ne, t2, Operand(zero_reg));
1694 __ lw(t0, MemOperand(t0, kNormalOffset)); 1692 __ lw(t0, MemOperand(t0, kNormalOffset));
1695 __ bind(&skip2_ne); 1693 __ bind(&skip2_ne);
1696 1694
1697 __ Branch(&skip2_eq, eq, a1, Operand(zero_reg)); 1695 __ Branch(&skip2_eq, eq, a1, Operand(zero_reg));
paul.l... 2015/09/24 04:07:05 The main bug is this a1 should have been changed t
paul.l... 2015/09/24 04:33:58 The 2 branches here (in older code also) bugged me
1698 __ lw(t0, MemOperand(t0, kAliasedOffset)); 1696 __ lw(t0, MemOperand(t0, kAliasedOffset));
1699 __ bind(&skip2_eq); 1697 __ bind(&skip2_eq);
1700 1698
1701 // v0 = address of new object (tagged) 1699 // v0 = address of new object (tagged)
1702 // a1 = mapped parameter count (tagged)
1703 // a2 = argument count (smi-tagged) 1700 // a2 = argument count (smi-tagged)
1704 // t0 = address of arguments map (tagged) 1701 // t0 = address of arguments map (tagged)
1702 // t2 = mapped parameter count (tagged)
1705 __ sw(t0, FieldMemOperand(v0, JSObject::kMapOffset)); 1703 __ sw(t0, FieldMemOperand(v0, JSObject::kMapOffset));
1706 __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex); 1704 __ LoadRoot(t5, Heap::kEmptyFixedArrayRootIndex);
1707 __ sw(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 1705 __ sw(t5, FieldMemOperand(v0, JSObject::kPropertiesOffset));
1708 __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); 1706 __ sw(t5, FieldMemOperand(v0, JSObject::kElementsOffset));
1709 1707
1710 // Set up the callee in-object property. 1708 // Set up the callee in-object property.
1711 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 1709 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
1712 __ lw(a3, MemOperand(sp, 2 * kPointerSize)); 1710 __ AssertNotSmi(a1);
1713 __ AssertNotSmi(a3);
1714 const int kCalleeOffset = JSObject::kHeaderSize + 1711 const int kCalleeOffset = JSObject::kHeaderSize +
1715 Heap::kArgumentsCalleeIndex * kPointerSize; 1712 Heap::kArgumentsCalleeIndex * kPointerSize;
1716 __ sw(a3, FieldMemOperand(v0, kCalleeOffset)); 1713 __ sw(a1, FieldMemOperand(v0, kCalleeOffset));
1717 1714
1718 // Use the length (smi tagged) and set that as an in-object property too. 1715 // Use the length (smi tagged) and set that as an in-object property too.
1719 __ AssertSmi(a2); 1716 __ AssertSmi(t0);
1720 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 1717 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1721 const int kLengthOffset = JSObject::kHeaderSize + 1718 const int kLengthOffset = JSObject::kHeaderSize +
1722 Heap::kArgumentsLengthIndex * kPointerSize; 1719 Heap::kArgumentsLengthIndex * kPointerSize;
1723 __ sw(a2, FieldMemOperand(v0, kLengthOffset)); 1720 __ sw(t0, FieldMemOperand(v0, kLengthOffset));
1724 1721
1725 // Set up the elements pointer in the allocated arguments object. 1722 // Set up the elements pointer in the allocated arguments object.
1726 // If we allocated a parameter map, t0 will point there, otherwise 1723 // If we allocated a parameter map, t0 will point there, otherwise
1727 // it will point to the backing store. 1724 // it will point to the backing store.
1728 __ Addu(t0, v0, Operand(Heap::kSloppyArgumentsObjectSize)); 1725 __ Addu(t0, v0, Operand(Heap::kSloppyArgumentsObjectSize));
1729 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); 1726 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
1730 1727
1731 // v0 = address of new object (tagged) 1728 // v0 = address of new object (tagged)
1732 // a1 = mapped parameter count (tagged)
1733 // a2 = argument count (tagged) 1729 // a2 = argument count (tagged)
1734 // t0 = address of parameter map or backing store (tagged) 1730 // t0 = address of parameter map or backing store (tagged)
1731 // t2 = mapped parameter count (tagged)
1735 // Initialize parameter map. If there are no mapped arguments, we're done. 1732 // Initialize parameter map. If there are no mapped arguments, we're done.
1736 Label skip_parameter_map; 1733 Label skip_parameter_map;
1737 Label skip3; 1734 Label skip3;
1738 __ Branch(&skip3, ne, a1, Operand(Smi::FromInt(0))); 1735 __ Branch(&skip3, ne, t2, Operand(Smi::FromInt(0)));
1739 // Move backing store address to a3, because it is 1736 // Move backing store address to a3, because it is
1740 // expected there when filling in the unmapped arguments. 1737 // expected there when filling in the unmapped arguments.
1741 __ mov(a3, t0); 1738 __ mov(a1, t0);
1742 __ bind(&skip3); 1739 __ bind(&skip3);
1743 1740
1744 __ Branch(&skip_parameter_map, eq, a1, Operand(Smi::FromInt(0))); 1741 __ Branch(&skip_parameter_map, eq, t2, Operand(Smi::FromInt(0)));
1745 1742
1746 __ LoadRoot(t2, Heap::kSloppyArgumentsElementsMapRootIndex); 1743 __ LoadRoot(t1, Heap::kSloppyArgumentsElementsMapRootIndex);
1747 __ sw(t2, FieldMemOperand(t0, FixedArray::kMapOffset)); 1744 __ sw(t1, FieldMemOperand(t0, FixedArray::kMapOffset));
1748 __ Addu(t2, a1, Operand(Smi::FromInt(2))); 1745 __ Addu(t1, t2, Operand(Smi::FromInt(2)));
1749 __ sw(t2, FieldMemOperand(t0, FixedArray::kLengthOffset)); 1746 __ sw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset));
1750 __ sw(cp, FieldMemOperand(t0, FixedArray::kHeaderSize + 0 * kPointerSize)); 1747 __ sw(cp, FieldMemOperand(t0, FixedArray::kHeaderSize + 0 * kPointerSize));
1751 __ sll(t6, a1, 1); 1748 __ sll(t6, t2, 1);
1752 __ Addu(t2, t0, Operand(t6)); 1749 __ Addu(t1, t0, Operand(t6));
1753 __ Addu(t2, t2, Operand(kParameterMapHeaderSize)); 1750 __ Addu(t1, t1, Operand(kParameterMapHeaderSize));
1754 __ sw(t2, FieldMemOperand(t0, FixedArray::kHeaderSize + 1 * kPointerSize)); 1751 __ sw(t1, FieldMemOperand(t0, FixedArray::kHeaderSize + 1 * kPointerSize));
1755 1752
1756 // Copy the parameter slots and the holes in the arguments. 1753 // Copy the parameter slots and the holes in the arguments.
1757 // We need to fill in mapped_parameter_count slots. They index the context, 1754 // We need to fill in mapped_parameter_count slots. They index the context,
1758 // where parameters are stored in reverse order, at 1755 // where parameters are stored in reverse order, at
1759 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 1756 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
1760 // The mapped parameter thus need to get indices 1757 // The mapped parameter thus need to get indices
1761 // MIN_CONTEXT_SLOTS+parameter_count-1 .. 1758 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
1762 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count 1759 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
1763 // We loop from right to left. 1760 // We loop from right to left.
1764 Label parameters_loop, parameters_test; 1761 Label parameters_loop, parameters_test;
1765 __ mov(t2, a1); 1762 __ mov(t1, t2);
1766 __ lw(t5, MemOperand(sp, 0 * kPointerSize)); 1763 __ Addu(t5, a2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
1767 __ Addu(t5, t5, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); 1764 __ Subu(t5, t5, Operand(t2));
1768 __ Subu(t5, t5, Operand(a1));
1769 __ LoadRoot(t3, Heap::kTheHoleValueRootIndex); 1765 __ LoadRoot(t3, Heap::kTheHoleValueRootIndex);
1770 __ sll(t6, t2, 1); 1766 __ sll(t6, t1, 1);
1771 __ Addu(a3, t0, Operand(t6)); 1767 __ Addu(a1, t0, Operand(t6));
1772 __ Addu(a3, a3, Operand(kParameterMapHeaderSize)); 1768 __ Addu(a1, a1, Operand(kParameterMapHeaderSize));
1773 1769
1774 // t2 = loop variable (tagged) 1770 // a1 = address of backing store (tagged)
1775 // a1 = mapping index (tagged)
1776 // a3 = address of backing store (tagged)
1777 // t0 = address of parameter map (tagged) 1771 // t0 = address of parameter map (tagged)
1778 // t1 = temporary scratch (a.o., for address calculation) 1772 // a0 = temporary scratch (a.o., for address calculation)
1773 // t1 = loop variable (tagged)
1779 // t3 = the hole value 1774 // t3 = the hole value
1780 __ jmp(&parameters_test); 1775 __ jmp(&parameters_test);
1781 1776
1782 __ bind(&parameters_loop); 1777 __ bind(&parameters_loop);
1783 __ Subu(t2, t2, Operand(Smi::FromInt(1))); 1778 __ Subu(t1, t1, Operand(Smi::FromInt(1)));
1784 __ sll(t1, t2, 1); 1779 __ sll(a0, t1, 1);
1785 __ Addu(t1, t1, Operand(kParameterMapHeaderSize - kHeapObjectTag)); 1780 __ Addu(a0, a0, Operand(kParameterMapHeaderSize - kHeapObjectTag));
1786 __ Addu(t6, t0, t1); 1781 __ Addu(t6, t0, a0);
1787 __ sw(t5, MemOperand(t6)); 1782 __ sw(t5, MemOperand(t6));
1788 __ Subu(t1, t1, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); 1783 __ Subu(a0, a0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
1789 __ Addu(t6, a3, t1); 1784 __ Addu(t6, a1, a0);
1790 __ sw(t3, MemOperand(t6)); 1785 __ sw(t3, MemOperand(t6));
1791 __ Addu(t5, t5, Operand(Smi::FromInt(1))); 1786 __ Addu(t5, t5, Operand(Smi::FromInt(1)));
1792 __ bind(&parameters_test); 1787 __ bind(&parameters_test);
1793 __ Branch(&parameters_loop, ne, t2, Operand(Smi::FromInt(0))); 1788 __ Branch(&parameters_loop, ne, t1, Operand(Smi::FromInt(0)));
1789
1790 // t1 = argument count (tagged).
1791 __ lw(t1, FieldMemOperand(v0, kLengthOffset));
1794 1792
1795 __ bind(&skip_parameter_map); 1793 __ bind(&skip_parameter_map);
1796 // a2 = argument count (tagged) 1794 // v0 = address of new object (tagged)
1797 // a3 = address of backing store (tagged) 1795 // a1 = address of backing store (tagged)
1798 // t1 = scratch 1796 // t1 = argument count (tagged)
1797 // t2 = mapped parameter count (tagged)
1798 // t5 = scratch
1799 // Copy arguments header and remaining slots (if there are any). 1799 // Copy arguments header and remaining slots (if there are any).
1800 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex); 1800 __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex);
1801 __ sw(t1, FieldMemOperand(a3, FixedArray::kMapOffset)); 1801 __ sw(t5, FieldMemOperand(a1, FixedArray::kMapOffset));
1802 __ sw(a2, FieldMemOperand(a3, FixedArray::kLengthOffset)); 1802 __ sw(t1, FieldMemOperand(a1, FixedArray::kLengthOffset));
1803 1803
1804 Label arguments_loop, arguments_test; 1804 Label arguments_loop, arguments_test;
1805 __ mov(t5, a1); 1805 __ sll(t6, t2, 1);
1806 __ lw(t0, MemOperand(sp, 1 * kPointerSize)); 1806 __ Subu(a3, a3, Operand(t6));
1807 __ sll(t6, t5, 1);
1808 __ Subu(t0, t0, Operand(t6));
1809 __ jmp(&arguments_test); 1807 __ jmp(&arguments_test);
1810 1808
1811 __ bind(&arguments_loop); 1809 __ bind(&arguments_loop);
1812 __ Subu(t0, t0, Operand(kPointerSize)); 1810 __ Subu(a3, a3, Operand(kPointerSize));
1813 __ lw(t2, MemOperand(t0, 0)); 1811 __ lw(t0, MemOperand(a3, 0));
1814 __ sll(t6, t5, 1); 1812 __ sll(t6, t2, 1);
1815 __ Addu(t1, a3, Operand(t6)); 1813 __ Addu(t5, a1, Operand(t6));
1816 __ sw(t2, FieldMemOperand(t1, FixedArray::kHeaderSize)); 1814 __ sw(t0, FieldMemOperand(t5, FixedArray::kHeaderSize));
1817 __ Addu(t5, t5, Operand(Smi::FromInt(1))); 1815 __ Addu(t2, t2, Operand(Smi::FromInt(1)));
1818 1816
1819 __ bind(&arguments_test); 1817 __ bind(&arguments_test);
1820 __ Branch(&arguments_loop, lt, t5, Operand(a2)); 1818 __ Branch(&arguments_loop, lt, t2, Operand(t1));
1821 1819
1822 // Return and remove the on-stack parameters. 1820 // Return.
1823 __ DropAndRet(3); 1821 __ Ret();
1824 1822
1825 // Do the runtime call to allocate the arguments object. 1823 // Do the runtime call to allocate the arguments object.
1826 // a2 = argument count (tagged) 1824 // t1 = argument count (tagged)
1827 __ bind(&runtime); 1825 __ bind(&runtime);
1828 __ sw(a2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count. 1826 __ Push(a1, a3, t1);
1829 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 1827 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
1830 } 1828 }
1831 1829
1832 1830
1833 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { 1831 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) {
1834 // Return address is in ra. 1832 // Return address is in ra.
1835 Label slow; 1833 Label slow;
1836 1834
1837 Register receiver = LoadDescriptor::ReceiverRegister(); 1835 Register receiver = LoadDescriptor::ReceiverRegister();
1838 Register key = LoadDescriptor::NameRegister(); 1836 Register key = LoadDescriptor::NameRegister();
1839 1837
1840 // Check that the key is an array index, that is Uint32. 1838 // Check that the key is an array index, that is Uint32.
1841 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); 1839 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask));
1842 __ Branch(&slow, ne, t0, Operand(zero_reg)); 1840 __ Branch(&slow, ne, t0, Operand(zero_reg));
1843 1841
1844 // Everything is fine, call runtime. 1842 // Everything is fine, call runtime.
1845 __ Push(receiver, key); // Receiver, key. 1843 __ Push(receiver, key); // Receiver, key.
1846 1844
1847 // Perform tail call to the entry. 1845 // Perform tail call to the entry.
1848 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1); 1846 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1);
1849 1847
1850 __ bind(&slow); 1848 __ bind(&slow);
1851 PropertyAccessCompiler::TailCallBuiltin( 1849 PropertyAccessCompiler::TailCallBuiltin(
1852 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); 1850 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
1853 } 1851 }
1854 1852
1855 1853
1856 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 1854 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
1857 // sp[0] : number of parameters 1855 // a1 : function
1858 // sp[4] : receiver displacement 1856 // a2 : number of parameters (tagged)
1859 // sp[8] : function 1857 // a3 : parameters pointer
1858
1859 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function()));
1860 DCHECK(a2.is(ArgumentsAccessNewDescriptor::parameter_count()));
1861 DCHECK(a3.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
1862
1860 // Check if the calling frame is an arguments adaptor frame. 1863 // Check if the calling frame is an arguments adaptor frame.
1861 Label adaptor_frame, try_allocate, runtime; 1864 Label try_allocate, runtime;
1862 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 1865 __ lw(t0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1863 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset)); 1866 __ lw(a0, MemOperand(t0, StandardFrameConstants::kContextOffset));
1864 __ Branch(&adaptor_frame, 1867 __ Branch(&try_allocate, ne, a0,
1865 eq,
1866 a3,
1867 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1868 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1868 1869
1869 // Get the length from the frame.
1870 __ lw(a1, MemOperand(sp, 0));
1871 __ Branch(&try_allocate);
1872
1873 // Patch the arguments.length and the parameters pointer. 1870 // Patch the arguments.length and the parameters pointer.
1874 __ bind(&adaptor_frame); 1871 __ lw(a2, MemOperand(t0, ArgumentsAdaptorFrameConstants::kLengthOffset));
1875 __ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1872 __ sll(at, a2, kPointerSizeLog2 - kSmiTagSize);
1876 __ sw(a1, MemOperand(sp, 0)); 1873 __ Addu(t0, t0, Operand(at));
1877 __ sll(at, a1, kPointerSizeLog2 - kSmiTagSize); 1874 __ Addu(a3, t0, Operand(StandardFrameConstants::kCallerSPOffset));
1878 __ Addu(a3, a2, Operand(at));
1879
1880 __ Addu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset));
1881 __ sw(a3, MemOperand(sp, 1 * kPointerSize));
1882 1875
1883 // Try the new space allocation. Start out with computing the size 1876 // Try the new space allocation. Start out with computing the size
1884 // of the arguments object and the elements array in words. 1877 // of the arguments object and the elements array in words.
1885 Label add_arguments_object; 1878 Label add_arguments_object;
1886 __ bind(&try_allocate); 1879 __ bind(&try_allocate);
1887 __ Branch(&add_arguments_object, eq, a1, Operand(zero_reg)); 1880 __ Branch(&add_arguments_object, eq, a2, Operand(zero_reg));
1888 __ srl(a1, a1, kSmiTagSize); 1881 __ SmiUntag(t5, a2);
1889 1882
1890 __ Addu(a1, a1, Operand(FixedArray::kHeaderSize / kPointerSize)); 1883 __ Addu(t5, t5, Operand(FixedArray::kHeaderSize / kPointerSize));
1891 __ bind(&add_arguments_object); 1884 __ bind(&add_arguments_object);
1892 __ Addu(a1, a1, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize)); 1885 __ Addu(t5, t5, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize));
1893 1886
1894 // Do the allocation of both objects in one go. 1887 // Do the allocation of both objects in one go.
1895 __ Allocate(a1, v0, a2, a3, &runtime, 1888 __ Allocate(t5, v0, t0, t1, &runtime,
1896 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); 1889 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
1897 1890
1898 // Get the arguments boilerplate from the current native context. 1891 // Get the arguments boilerplate from the current native context.
1899 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 1892 __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
1900 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset)); 1893 __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset));
1901 __ lw(t0, MemOperand( 1894 __ lw(t0, MemOperand(
1902 t0, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX))); 1895 t0, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX)));
1903 1896
1904 __ sw(t0, FieldMemOperand(v0, JSObject::kMapOffset)); 1897 __ sw(t0, FieldMemOperand(v0, JSObject::kMapOffset));
1905 __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex); 1898 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex);
1906 __ sw(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 1899 __ sw(t1, FieldMemOperand(v0, JSObject::kPropertiesOffset));
1907 __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); 1900 __ sw(t1, FieldMemOperand(v0, JSObject::kElementsOffset));
1908 1901
1909 // Get the length (smi tagged) and set that as an in-object property too. 1902 // Get the length (smi tagged) and set that as an in-object property too.
1910 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 1903 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1911 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); 1904 __ AssertSmi(a2);
1912 __ AssertSmi(a1); 1905 __ sw(a2,
1913 __ sw(a1, FieldMemOperand(v0, JSObject::kHeaderSize + 1906 FieldMemOperand(v0, JSObject::kHeaderSize +
1914 Heap::kArgumentsLengthIndex * kPointerSize)); 1907 Heap::kArgumentsLengthIndex * kPointerSize));
1915 1908
1916 Label done; 1909 Label done;
1917 __ Branch(&done, eq, a1, Operand(zero_reg)); 1910 __ Branch(&done, eq, a2, Operand(zero_reg));
1918
1919 // Get the parameters pointer from the stack.
1920 __ lw(a2, MemOperand(sp, 1 * kPointerSize));
1921 1911
1922 // Set up the elements pointer in the allocated arguments object and 1912 // Set up the elements pointer in the allocated arguments object and
1923 // initialize the header in the elements fixed array. 1913 // initialize the header in the elements fixed array.
1924 __ Addu(t0, v0, Operand(Heap::kStrictArgumentsObjectSize)); 1914 __ Addu(t0, v0, Operand(Heap::kStrictArgumentsObjectSize));
1925 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); 1915 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
1926 __ LoadRoot(a3, Heap::kFixedArrayMapRootIndex); 1916 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex);
1927 __ sw(a3, FieldMemOperand(t0, FixedArray::kMapOffset)); 1917 __ sw(t1, FieldMemOperand(t0, FixedArray::kMapOffset));
1928 __ sw(a1, FieldMemOperand(t0, FixedArray::kLengthOffset)); 1918 __ sw(a2, FieldMemOperand(t0, FixedArray::kLengthOffset));
1929 // Untag the length for the loop. 1919 __ SmiUntag(a2);
1930 __ srl(a1, a1, kSmiTagSize);
1931 1920
1932 // Copy the fixed array slots. 1921 // Copy the fixed array slots.
1933 Label loop; 1922 Label loop;
1934 // Set up t0 to point to the first array slot. 1923 // Set up t0 to point to the first array slot.
1935 __ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 1924 __ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1936 __ bind(&loop); 1925 __ bind(&loop);
1937 // Pre-decrement a2 with kPointerSize on each iteration. 1926 // Pre-decrement a3 with kPointerSize on each iteration.
1938 // Pre-decrement in order to skip receiver. 1927 // Pre-decrement in order to skip receiver.
1939 __ Addu(a2, a2, Operand(-kPointerSize)); 1928 __ Addu(a3, a3, Operand(-kPointerSize));
1940 __ lw(a3, MemOperand(a2)); 1929 __ lw(t1, MemOperand(a3));
1941 // Post-increment t0 with kPointerSize on each iteration. 1930 // Post-increment t0 with kPointerSize on each iteration.
1942 __ sw(a3, MemOperand(t0)); 1931 __ sw(t1, MemOperand(t0));
1943 __ Addu(t0, t0, Operand(kPointerSize)); 1932 __ Addu(t0, t0, Operand(kPointerSize));
1944 __ Subu(a1, a1, Operand(1)); 1933 __ Subu(a2, a2, Operand(1));
1945 __ Branch(&loop, ne, a1, Operand(zero_reg)); 1934 __ Branch(&loop, ne, a2, Operand(zero_reg));
1946 1935
1947 // Return and remove the on-stack parameters. 1936 // Return.
1948 __ bind(&done); 1937 __ bind(&done);
1949 __ DropAndRet(3); 1938 __ Ret();
1950 1939
1951 // Do the runtime call to allocate the arguments object. 1940 // Do the runtime call to allocate the arguments object.
1952 __ bind(&runtime); 1941 __ bind(&runtime);
1942 __ Push(a1, a3, a2);
1953 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 1943 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1954 } 1944 }
1955 1945
1956 1946
1957 void RegExpExecStub::Generate(MacroAssembler* masm) { 1947 void RegExpExecStub::Generate(MacroAssembler* masm) {
1958 // Just jump directly to runtime if native RegExp is not selected at compile 1948 // Just jump directly to runtime if native RegExp is not selected at compile
1959 // time or if regexp entry in generated code is turned off runtime switch or 1949 // time or if regexp entry in generated code is turned off runtime switch or
1960 // at compilation. 1950 // at compilation.
1961 #ifdef V8_INTERPRETED_REGEXP 1951 #ifdef V8_INTERPRETED_REGEXP
1962 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 1952 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
(...skipping 3785 matching lines...) Expand 10 before | Expand all | Expand 10 after
5748 MemOperand(fp, 6 * kPointerSize), NULL); 5738 MemOperand(fp, 6 * kPointerSize), NULL);
5749 } 5739 }
5750 5740
5751 5741
5752 #undef __ 5742 #undef __
5753 5743
5754 } // namespace internal 5744 } // namespace internal
5755 } // namespace v8 5745 } // namespace v8
5756 5746
5757 #endif // V8_TARGET_ARCH_MIPS 5747 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/mips/interface-descriptors-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698