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

Side by Side Diff: src/a64/stub-cache-a64.cc

Issue 148343005: A64: Synchronize with r18147. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/a64/ic-a64.cc ('k') | src/allocation-site-scopes.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 __ Mov(this->name(), Operand(name)); 702 __ Mov(this->name(), Operand(name));
703 } 703 }
704 } 704 }
705 705
706 706
707 // The function to called must be passed in x1. 707 // The function to called must be passed in x1.
708 static void GenerateCallFunction(MacroAssembler* masm, 708 static void GenerateCallFunction(MacroAssembler* masm,
709 Handle<Object> object, 709 Handle<Object> object,
710 const ParameterCount& arguments, 710 const ParameterCount& arguments,
711 Label* miss, 711 Label* miss,
712 Code::ExtraICState extra_ic_state, 712 ExtraICState extra_ic_state,
713 Register function, 713 Register function,
714 Register receiver, 714 Register receiver,
715 Register scratch) { 715 Register scratch) {
716 ASSERT(!AreAliased(function, receiver, scratch)); 716 ASSERT(!AreAliased(function, receiver, scratch));
717 ASSERT(function.Is(x1)); 717 ASSERT(function.Is(x1));
718 718
719 // Check that the function really is a function. 719 // Check that the function really is a function.
720 __ JumpIfSmi(function, miss); 720 __ JumpIfSmi(function, miss);
721 __ JumpIfNotObjectType(function, scratch, scratch, JS_FUNCTION_TYPE, miss); 721 __ JumpIfNotObjectType(function, scratch, scratch, JS_FUNCTION_TYPE, miss);
722 722
723 // Patch the receiver on the stack with the global proxy if necessary.
724 if (object->IsGlobalObject()) { 723 if (object->IsGlobalObject()) {
724 const int argc = arguments.immediate();
725 const int receiver_offset = argc * kPointerSize;
725 __ Ldr(scratch, 726 __ Ldr(scratch,
726 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 727 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset));
727 __ Poke(scratch, arguments.immediate() * kPointerSize); 728 __ Poke(scratch, receiver_offset);
728 } 729 }
729 730
730 // Invoke the function. 731 // Invoke the function.
731 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) 732 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
732 ? CALL_AS_FUNCTION 733 ? CALL_AS_FUNCTION
733 : CALL_AS_METHOD; 734 : CALL_AS_METHOD;
734 __ InvokeFunction( 735 __ InvokeFunction(
735 function, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); 736 function, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
736 } 737 }
737 738
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 934
934 GenerateFastApiDirectCall(masm, optimization, argc, true); 935 GenerateFastApiDirectCall(masm, optimization, argc, true);
935 } 936 }
936 937
937 938
938 class CallInterceptorCompiler BASE_EMBEDDED { 939 class CallInterceptorCompiler BASE_EMBEDDED {
939 public: 940 public:
940 CallInterceptorCompiler(StubCompiler* stub_compiler, 941 CallInterceptorCompiler(StubCompiler* stub_compiler,
941 const ParameterCount& arguments, 942 const ParameterCount& arguments,
942 Register name, 943 Register name,
943 Code::ExtraICState extra_ic_state) 944 ExtraICState extra_ic_state)
944 : stub_compiler_(stub_compiler), 945 : stub_compiler_(stub_compiler),
945 arguments_(arguments), 946 arguments_(arguments),
946 name_(name), 947 name_(name),
947 extra_ic_state_(extra_ic_state) {} 948 extra_ic_state_(extra_ic_state) {}
948 949
949 void Compile(MacroAssembler* masm, 950 void Compile(MacroAssembler* masm,
950 Handle<JSObject> object, 951 Handle<JSObject> object,
951 Handle<JSObject> holder, 952 Handle<JSObject> holder,
952 Handle<Name> name, 953 Handle<Name> name,
953 LookupResult* lookup, 954 LookupResult* lookup,
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 1120
1120 // If interceptor returns no-result sentinel, call the constant function. 1121 // If interceptor returns no-result sentinel, call the constant function.
1121 __ JumpIfNotRoot(x0, 1122 __ JumpIfNotRoot(x0,
1122 Heap::kNoInterceptorResultSentinelRootIndex, 1123 Heap::kNoInterceptorResultSentinelRootIndex,
1123 interceptor_succeeded); 1124 interceptor_succeeded);
1124 } 1125 }
1125 1126
1126 StubCompiler* stub_compiler_; 1127 StubCompiler* stub_compiler_;
1127 const ParameterCount& arguments_; 1128 const ParameterCount& arguments_;
1128 Register name_; 1129 Register name_;
1129 Code::ExtraICState extra_ic_state_; 1130 ExtraICState extra_ic_state_;
1130 }; 1131 };
1131 1132
1132 1133
1133 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1134 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1134 __ Jump(code, RelocInfo::CODE_TARGET); 1135 __ Jump(code, RelocInfo::CODE_TARGET);
1135 } 1136 }
1136 1137
1137 1138
1138 #undef __ 1139 #undef __
1139 #define __ ACCESS_MASM(masm()) 1140 #define __ ACCESS_MASM(masm())
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1562 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1562 Register name_reg = x2; 1563 Register name_reg = x2;
1563 1564
1564 if (kind_ == Code::KEYED_CALL_IC) { 1565 if (kind_ == Code::KEYED_CALL_IC) {
1565 __ Cmp(name_reg, Operand(name)); 1566 __ Cmp(name_reg, Operand(name));
1566 __ B(ne, miss); 1567 __ B(ne, miss);
1567 } 1568 }
1568 } 1569 }
1569 1570
1570 1571
1571 // The receiver is loaded from the stack and left in x0 register.
1572 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1573 Handle<JSObject> holder,
1574 Handle<Name> name,
1575 Label* miss) {
1576 ASSERT(holder->IsGlobalObject());
1577
1578 const int argc = arguments().immediate();
1579
1580 // Get the receiver from the stack.
1581 Register receiver = x0;
1582 __ Peek(receiver, argc * kPointerSize);
1583
1584 // Check that the maps haven't changed.
1585 __ JumpIfSmi(receiver, miss);
1586 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
1587 receiver, holder, x3, x1, x4, name, miss);
1588 }
1589
1590
1591 // Load the function object into x1 register. 1572 // Load the function object into x1 register.
1592 void CallStubCompiler::GenerateLoadFunctionFromCell( 1573 void CallStubCompiler::GenerateLoadFunctionFromCell(
1593 Handle<Cell> cell, 1574 Handle<Cell> cell,
1594 Handle<JSFunction> function, 1575 Handle<JSFunction> function,
1595 Label* miss) { 1576 Label* miss) {
1596 // Get the value from the cell. 1577 // Get the value from the cell.
1597 __ Mov(x3, Operand(cell)); 1578 __ Mov(x3, Operand(cell));
1598 Register function_reg = x1; 1579 Register function_reg = x1;
1599 __ Ldr(function_reg, FieldMemOperand(x3, Cell::kValueOffset)); 1580 __ Ldr(function_reg, FieldMemOperand(x3, Cell::kValueOffset));
1600 1581
(...skipping 25 matching lines...) Expand all
1626 kind_, 1607 kind_,
1627 extra_state_); 1608 extra_state_);
1628 __ Jump(code, RelocInfo::CODE_TARGET); 1609 __ Jump(code, RelocInfo::CODE_TARGET);
1629 } 1610 }
1630 1611
1631 1612
1632 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1613 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1633 Handle<JSObject> holder, 1614 Handle<JSObject> holder,
1634 PropertyIndex index, 1615 PropertyIndex index,
1635 Handle<Name> name) { 1616 Handle<Name> name) {
1636 // ----------- S t a t e -------------
1637 // -- x2 : name
1638 // -- lr : return address
1639 // -----------------------------------
1640 Label miss; 1617 Label miss;
1641 const int argc = arguments().immediate(); 1618 Register receiver = x0;
1619 Register function = x1;
1642 1620
1643 GenerateNameCheck(name, &miss); 1621 Register holder_reg = HandlerFrontendHeader(
1622 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1644 1623
1645 // Get the receiver of the function from the stack.
1646 Register receiver = x0;
1647 __ Peek(receiver, argc * kXRegSizeInBytes);
1648 // Check that the receiver isn't a smi.
1649 __ JumpIfSmi(receiver, &miss);
1650
1651 // Do the right check and compute the holder register.
1652 Register holder_reg = CheckPrototypes(
1653 IC::CurrentTypeOf(object, isolate()),
1654 receiver, holder, x1, x3, x4, name, &miss);
1655 Register function = x1;
1656 GenerateFastPropertyLoad(masm(), function, holder_reg, 1624 GenerateFastPropertyLoad(masm(), function, holder_reg,
1657 index.is_inobject(holder), 1625 index.is_inobject(holder),
1658 index.translate(holder), 1626 index.translate(holder),
1659 Representation::Tagged()); 1627 Representation::Tagged());
1660 1628
1661 GenerateCallFunction( 1629 GenerateCallFunction(
1662 masm(), object, arguments(), &miss, extra_state_, function, receiver, x3); 1630 masm(), object, arguments(), &miss, extra_state_, function, receiver, x3);
1663 1631
1664 // Handle call cache miss. 1632 HandlerFrontendFooter(&miss);
1665 __ Bind(&miss);
1666 GenerateMissBranch();
1667 1633
1668 // Return the generated code. 1634 // Return the generated code.
1669 return GetCode(Code::FAST, name); 1635 return GetCode(Code::FAST, name);
1670 } 1636 }
1671 1637
1672 1638
1673 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1639 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1674 Handle<Object> object, 1640 Handle<Object> object,
1675 Handle<JSObject> holder, 1641 Handle<JSObject> holder,
1676 Handle<Cell> cell, 1642 Handle<Cell> cell,
1677 Handle<JSFunction> function, 1643 Handle<JSFunction> function,
1678 Handle<String> name, 1644 Handle<String> name,
1679 Code::StubType type) { 1645 Code::StubType type) {
1680 // ----------- S t a t e -------------
1681 // -- x2 : name
1682 // -- lr : return address
1683 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
1684 // -- ...
1685 // -- sp[argc * 8] : receiver
1686 // -----------------------------------
1687 Label miss; 1646 Label miss;
1688 1647
1689 // Check that function is still array. 1648 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1690 const int argc = arguments().immediate(); 1649 if (!cell.is_null()) {
1691 GenerateNameCheck(name, &miss);
1692
1693 Register receiver = x1;
1694 if (cell.is_null()) {
1695 __ Peek(receiver, argc * kPointerSize);
1696
1697 // Check that the receiver isn't a smi.
1698 __ JumpIfSmi(receiver, &miss);
1699
1700 // Check that the maps haven't changed.
1701 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
1702 receiver, holder, x3, x0, x4, name, &miss);
1703 } else {
1704 ASSERT(cell->value() == *function); 1650 ASSERT(cell->value() == *function);
1705 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1706 &miss);
1707 GenerateLoadFunctionFromCell(cell, function, &miss); 1651 GenerateLoadFunctionFromCell(cell, function, &miss);
1708 } 1652 }
1709 1653
1710 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1654 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1711 site->SetElementsKind(GetInitialFastElementsKind()); 1655 site->SetElementsKind(GetInitialFastElementsKind());
1712 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1656 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1657 const int argc = arguments().immediate();
1713 __ Mov(x0, argc); 1658 __ Mov(x0, argc);
1714 __ Mov(x1, Operand(function)); 1659 __ Mov(x1, Operand(function));
1715 __ Mov(x2, Operand(site_feedback_cell)); 1660 __ Mov(x2, Operand(site_feedback_cell));
1716 1661
1717 ArrayConstructorStub stub(isolate()); 1662 ArrayConstructorStub stub(isolate());
1718 __ TailCallStub(&stub); 1663 __ TailCallStub(&stub);
1719 1664
1720 __ Bind(&miss); 1665 HandlerFrontendFooter(&miss);
1721 GenerateMissBranch();
1722 1666
1723 // Return the generated code. 1667 // Return the generated code.
1724 return GetCode(type, name); 1668 return GetCode(type, name);
1725 } 1669 }
1726 1670
1727 1671
1728 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1672 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1729 Handle<Object> object, 1673 Handle<Object> object,
1730 Handle<JSObject> holder, 1674 Handle<JSObject> holder,
1731 Handle<Cell> cell, 1675 Handle<Cell> cell,
1732 Handle<JSFunction> function, 1676 Handle<JSFunction> function,
1733 Handle<String> name, 1677 Handle<String> name,
1734 Code::StubType type) { 1678 Code::StubType type) {
1735 // ----------- S t a t e -------------
1736 // -- x2 : name (Must be preserved on miss.)
1737 // -- lr : return address
1738 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
1739 // -- ...
1740 // -- sp[argc * 8] : receiver
1741 // -----------------------------------
1742
1743 // If object is not an array or is observed, bail out to regular call. 1679 // If object is not an array or is observed, bail out to regular call.
1744 if (!object->IsJSArray() || 1680 if (!object->IsJSArray() ||
1745 !cell.is_null() || 1681 !cell.is_null() ||
1746 Handle<JSArray>::cast(object)->map()->is_observed()) { 1682 Handle<JSArray>::cast(object)->map()->is_observed()) {
1747 return Handle<Code>::null(); 1683 return Handle<Code>::null();
1748 } 1684 }
1749 1685
1750 Label miss; 1686 Label miss;
1751 Register result = x0; 1687
1688 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1689
1690 Register receiver = x0;
1691
1752 const int argc = arguments().immediate(); 1692 const int argc = arguments().immediate();
1753
1754 GenerateNameCheck(name, &miss);
1755
1756 // Get the receiver from the stack
1757 Register receiver = x1;
1758 __ Peek(receiver, argc * kPointerSize);
1759
1760 // Check that the receiver isn't a smi.
1761 __ JumpIfSmi(receiver, &miss);
1762
1763 // Check that the maps haven't changed.
1764 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
1765 receiver, holder, x3, x0, x4, name, &miss);
1766
1767 if (argc == 0) { 1693 if (argc == 0) {
1768 // Nothing to do, just return the length. 1694 // Nothing to do, just return the length.
1769 __ Ldr(result, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1695 __ Ldr(x0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1770 __ Drop(argc + 1); 1696 __ Drop(argc + 1);
1771 __ Ret(); 1697 __ Ret();
1772 } else { 1698 } else {
1773 Label call_builtin; 1699 Label call_builtin;
1774 1700
1775 if (argc == 1) { // Otherwise fall through to call the builtin. 1701 if (argc == 1) { // Otherwise fall through to call the builtin.
1776 Label attempt_to_grow_elements, with_write_barrier, check_double; 1702 Label attempt_to_grow_elements, with_write_barrier, check_double;
1777 1703
1778 // Note that even though we assign the array length to x0 and the value 1704 Register elements_length = x8;
1779 // to push in x4, they are not always live. Both x0 and x4 can be locally 1705 Register length = x7;
1780 // reused as scratch registers.
1781 Register length = x0;
1782 Register value = x4;
1783 Register elements = x6; 1706 Register elements = x6;
1784 Register end_elements = x5; 1707 Register end_elements = x5;
1708 Register value = x4;
1785 // Get the elements array of the object. 1709 // Get the elements array of the object.
1786 __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1710 __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1787 1711
1788 // Check that the elements are in fast mode and writable. 1712 // Check that the elements are in fast mode and writable.
1789 __ CheckMap(elements, 1713 __ CheckMap(elements,
1790 x0, 1714 x10,
1791 Heap::kFixedArrayMapRootIndex, 1715 Heap::kFixedArrayMapRootIndex,
1792 &check_double, 1716 &check_double,
1793 DONT_DO_SMI_CHECK); 1717 DONT_DO_SMI_CHECK);
1794 1718
1795 // Get the array's length and calculate new length. 1719 // Get the array's length and calculate new length.
1796 __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1720 __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
1797 STATIC_ASSERT(kSmiTag == 0); 1721 STATIC_ASSERT(kSmiTag == 0);
1798 __ Add(length, length, Operand(Smi::FromInt(argc))); 1722 __ Add(length, length, Operand(Smi::FromInt(argc)));
1799 1723
1800 // Check if we could survive without allocation. 1724 // Check if we could survive without allocation.
1801 __ Ldr(x4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1725 __ Ldr(elements_length,
1802 __ Cmp(length, x4); 1726 FieldMemOperand(elements, FixedArray::kLengthOffset));
1727 __ Cmp(length, elements_length);
1803 __ B(gt, &attempt_to_grow_elements); 1728 __ B(gt, &attempt_to_grow_elements);
1804 1729
1805 // Check if value is a smi. 1730 // Check if value is a smi.
1806 __ Peek(value, (argc - 1) * kPointerSize); 1731 __ Peek(value, (argc - 1) * kPointerSize);
1807 __ JumpIfNotSmi(value, &with_write_barrier); 1732 __ JumpIfNotSmi(value, &with_write_barrier);
1808 1733
1809 // Save new length. 1734 // Save new length.
1810 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1735 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
1811 1736
1812 // Store the value. 1737 // Store the value.
1813 // We may need a register containing the address end_elements below, 1738 // We may need a register containing the address end_elements below,
1814 // so write back the value in end_elements. 1739 // so write back the value in end_elements.
1815 __ Add(end_elements, elements, 1740 __ Add(end_elements, elements,
1816 Operand::UntagSmiAndScale(length, kPointerSizeLog2)); 1741 Operand::UntagSmiAndScale(length, kPointerSizeLog2));
1817 const int kEndElementsOffset = 1742 const int kEndElementsOffset =
1818 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1743 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1819 __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1744 __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1820 1745
1821 // Check for a smi. 1746 // Return length.
1822 __ Drop(argc + 1); 1747 __ Drop(argc + 1);
1748 __ Mov(x0, length);
1823 __ Ret(); 1749 __ Ret();
1824 1750
1825 __ Bind(&check_double); 1751 __ Bind(&check_double);
1826 // Check that the elements are in fast mode and writable. 1752 // Check that the elements are in fast mode and writable.
1827 __ CheckMap(elements, 1753 __ CheckMap(elements,
1828 x0, 1754 x0,
1829 Heap::kFixedDoubleArrayMapRootIndex, 1755 Heap::kFixedDoubleArrayMapRootIndex,
1830 &call_builtin, 1756 &call_builtin,
1831 DONT_DO_SMI_CHECK); 1757 DONT_DO_SMI_CHECK);
1832 1758
1833 // Get the array's length and calculate new length. 1759 // Get the array's length and calculate new length.
1834 Register old_length = x5; 1760 Register old_length = x5;
1835 __ Ldr(old_length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1761 __ Ldr(old_length, FieldMemOperand(receiver, JSArray::kLengthOffset));
1836 STATIC_ASSERT(kSmiTag == 0); 1762 STATIC_ASSERT(kSmiTag == 0);
1837 __ Add(length, old_length, Operand(Smi::FromInt(argc))); 1763 __ Add(length, old_length, Operand(Smi::FromInt(argc)));
1838 1764
1839 // Check if we could survive without allocation. 1765 // Check if we could survive without allocation.
1840 __ Ldr(x4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1766 __ Ldr(x10, FieldMemOperand(elements, FixedArray::kLengthOffset));
1841 __ Cmp(length, x4); 1767 __ Cmp(length, x10);
1842 __ B(gt, &call_builtin); 1768 __ B(gt, &call_builtin);
1843 1769
1844 __ Peek(value, (argc - 1) * kPointerSize); 1770 __ Peek(value, (argc - 1) * kPointerSize);
1845 __ StoreNumberToDoubleElements( 1771 __ StoreNumberToDoubleElements(
1846 value, old_length, elements, x3, d0, d1, 1772 value, old_length, elements, x10, d0, d1,
1847 &call_builtin); 1773 &call_builtin);
1848 1774
1849 // Save new length. 1775 // Save new length.
1850 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1776 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
1851 1777
1852 // Check for a smi. 1778 // Return length.
1853 __ Drop(argc + 1); 1779 __ Drop(argc + 1);
1780 __ Mov(x0, length);
1854 __ Ret(); 1781 __ Ret();
1855 1782
1856 1783
1857 __ Bind(&with_write_barrier); 1784 __ Bind(&with_write_barrier);
1858 Register map = x3; 1785 Register map = x3;
1859 __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1786 __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1860 1787
1861 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { 1788 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1862 Label fast_object, not_fast_object; 1789 Label fast_object, not_fast_object;
1863 __ CheckFastObjectElements(map, x7, &not_fast_object); 1790 __ CheckFastObjectElements(map, x10, &not_fast_object);
1864 __ B(&fast_object); 1791 __ B(&fast_object);
1865 1792
1866 // In case of fast smi-only, convert to fast object, otherwise bail out. 1793 // In case of fast smi-only, convert to fast object, otherwise bail out.
1867 __ Bind(&not_fast_object); 1794 __ Bind(&not_fast_object);
1868 __ CheckFastSmiElements(map, x7, &call_builtin); 1795 __ CheckFastSmiElements(map, x10, &call_builtin);
1869 1796
1870 __ Ldr(x7, FieldMemOperand(x4, HeapObject::kMapOffset)); 1797 __ Ldr(x10, FieldMemOperand(value, HeapObject::kMapOffset));
1871 __ JumpIfRoot(x7, Heap::kHeapNumberMapRootIndex, &call_builtin); 1798 __ JumpIfRoot(x10, Heap::kHeapNumberMapRootIndex, &call_builtin);
1872 1799
1873 Label try_holey_map; 1800 Label try_holey_map;
1874 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 1801 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
1875 FAST_ELEMENTS, 1802 FAST_ELEMENTS,
1876 map, 1803 map,
1877 x7, 1804 x10,
1878 &try_holey_map); 1805 &try_holey_map);
1879 // GenerateMapChangeElementsTransition expects the receiver to be in x2. 1806 // GenerateMapChangeElementsTransition expects the receiver to be in x2.
1880 // Since from this point we cannot jump on 'miss' it is ok to clobber 1807 // Since from this point we cannot jump on 'miss' it is ok to clobber
1881 // x2 (which initialy contained called function name). 1808 // x2 (which initialy contained called function name).
1882 __ Mov(x2, receiver); 1809 __ Mov(x2, receiver);
1883 ElementsTransitionGenerator:: 1810 ElementsTransitionGenerator::
1884 GenerateMapChangeElementsTransition(masm(), 1811 GenerateMapChangeElementsTransition(masm(),
1885 DONT_TRACK_ALLOCATION_SITE, 1812 DONT_TRACK_ALLOCATION_SITE,
1886 NULL); 1813 NULL);
1887 __ B(&fast_object); 1814 __ B(&fast_object);
1888 1815
1889 __ Bind(&try_holey_map); 1816 __ Bind(&try_holey_map);
1890 __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS, 1817 __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS,
1891 FAST_HOLEY_ELEMENTS, 1818 FAST_HOLEY_ELEMENTS,
1892 map, 1819 map,
1893 x7, 1820 x10,
1894 &call_builtin); 1821 &call_builtin);
1895 // The previous comment about x2 usage also applies here. 1822 // The previous comment about x2 usage also applies here.
1896 __ Mov(x2, receiver); 1823 __ Mov(x2, receiver);
1897 ElementsTransitionGenerator:: 1824 ElementsTransitionGenerator::
1898 GenerateMapChangeElementsTransition(masm(), 1825 GenerateMapChangeElementsTransition(masm(),
1899 DONT_TRACK_ALLOCATION_SITE, 1826 DONT_TRACK_ALLOCATION_SITE,
1900 NULL); 1827 NULL);
1901 __ Bind(&fast_object); 1828 __ Bind(&fast_object);
1902 } else { 1829 } else {
1903 __ CheckFastObjectElements(map, x3, &call_builtin); 1830 __ CheckFastObjectElements(map, x3, &call_builtin);
1904 } 1831 }
1905 1832
1906 // Save new length. 1833 // Save new length.
1907 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1834 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
1908 1835
1909 // Store the value. 1836 // Store the value.
1910 // We may need a register containing the address end_elements below, 1837 // We may need a register containing the address end_elements below,
1911 // so write back the value in end_elements. 1838 // so write back the value in end_elements.
1912 __ Add(end_elements, elements, 1839 __ Add(end_elements, elements,
1913 Operand::UntagSmiAndScale(length, kPointerSizeLog2)); 1840 Operand::UntagSmiAndScale(length, kPointerSizeLog2));
1914 __ Str(x4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1841 __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1915 1842
1916 __ RecordWrite(elements, 1843 __ RecordWrite(elements,
1917 end_elements, 1844 end_elements,
1918 x4, 1845 value,
1919 kLRHasNotBeenSaved, 1846 kLRHasNotBeenSaved,
1920 kDontSaveFPRegs, 1847 kDontSaveFPRegs,
1921 EMIT_REMEMBERED_SET, 1848 EMIT_REMEMBERED_SET,
1922 OMIT_SMI_CHECK); 1849 OMIT_SMI_CHECK);
1923 __ Drop(argc + 1); 1850 __ Drop(argc + 1);
1851 __ Mov(x0, length);
1924 __ Ret(); 1852 __ Ret();
1925 1853
1926 1854
1927 __ Bind(&attempt_to_grow_elements); 1855 __ Bind(&attempt_to_grow_elements);
1928 // When we jump here, x4 must hold the length of elements.
1929 Register elements_length = x4;
1930 1856
1931 if (!FLAG_inline_new) { 1857 if (!FLAG_inline_new) {
1932 __ B(&call_builtin); 1858 __ B(&call_builtin);
1933 } 1859 }
1934 1860
1935 __ Peek(x2, (argc - 1) * kPointerSize); 1861 Register argument = x2;
1862 __ Peek(argument, (argc - 1) * kPointerSize);
1936 // Growing elements that are SMI-only requires special handling in case 1863 // Growing elements that are SMI-only requires special handling in case
1937 // the new element is non-Smi. For now, delegate to the builtin. 1864 // the new element is non-Smi. For now, delegate to the builtin.
1938 Label no_fast_elements_check; 1865 Label no_fast_elements_check;
1939 __ JumpIfSmi(x2, &no_fast_elements_check); 1866 __ JumpIfSmi(argument, &no_fast_elements_check);
1940 __ Ldr(x7, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1867 __ Ldr(x10, FieldMemOperand(receiver, HeapObject::kMapOffset));
1941 __ CheckFastObjectElements(x7, x7, &call_builtin); 1868 __ CheckFastObjectElements(x10, x10, &call_builtin);
1942 __ Bind(&no_fast_elements_check); 1869 __ Bind(&no_fast_elements_check);
1943 1870
1944 ExternalReference new_space_allocation_top = 1871 ExternalReference new_space_allocation_top =
1945 ExternalReference::new_space_allocation_top_address(isolate()); 1872 ExternalReference::new_space_allocation_top_address(isolate());
1946 ExternalReference new_space_allocation_limit = 1873 ExternalReference new_space_allocation_limit =
1947 ExternalReference::new_space_allocation_limit_address(isolate()); 1874 ExternalReference::new_space_allocation_limit_address(isolate());
1948 1875
1949 const int kAllocationDelta = 4; 1876 const int kAllocationDelta = 4;
1877 Register allocation_top_addr = x5;
1878 Register allocation_top = x9;
1950 // Load top and check if it is the end of elements. 1879 // Load top and check if it is the end of elements.
1951 __ Add(end_elements, elements, 1880 __ Add(end_elements, elements,
1952 Operand::UntagSmiAndScale(length, kPointerSizeLog2)); 1881 Operand::UntagSmiAndScale(length, kPointerSizeLog2));
1953 __ Add(end_elements, end_elements, kEndElementsOffset); 1882 __ Add(end_elements, end_elements, kEndElementsOffset);
1954 __ Mov(x7, Operand(new_space_allocation_top)); 1883 __ Mov(allocation_top_addr, Operand(new_space_allocation_top));
1955 __ Ldr(x3, MemOperand(x7)); 1884 __ Ldr(allocation_top, MemOperand(allocation_top_addr));
1956 __ Cmp(end_elements, x3); 1885 __ Cmp(end_elements, allocation_top);
1957 __ B(ne, &call_builtin); 1886 __ B(ne, &call_builtin);
1958 1887
1959 __ Mov(x10, Operand(new_space_allocation_limit)); 1888 __ Mov(x10, Operand(new_space_allocation_limit));
1960 __ Ldr(x10, MemOperand(x10)); 1889 __ Ldr(x10, MemOperand(x10));
1961 __ Add(x3, x3, kAllocationDelta * kPointerSize); 1890 __ Add(allocation_top, allocation_top, kAllocationDelta * kPointerSize);
1962 __ Cmp(x3, x10); 1891 __ Cmp(allocation_top, x10);
1963 __ B(hi, &call_builtin); 1892 __ B(hi, &call_builtin);
1964 1893
1965 // We fit and could grow elements. 1894 // We fit and could grow elements.
1966 // Update new_space_allocation_top. 1895 // Update new_space_allocation_top.
1967 __ Str(x3, MemOperand(x7)); 1896 __ Str(allocation_top, MemOperand(allocation_top_addr));
1968 // Push the argument. 1897 // Push the argument.
1969 __ Str(x2, MemOperand(end_elements)); 1898 __ Str(argument, MemOperand(end_elements));
1970 // Fill the rest with holes. 1899 // Fill the rest with holes.
1971 __ LoadRoot(x3, Heap::kTheHoleValueRootIndex); 1900 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
1972 for (int i = 1; i < kAllocationDelta; i++) { 1901 for (int i = 1; i < kAllocationDelta; i++) {
1973 __ Str(x3, MemOperand(end_elements, i * kPointerSize)); 1902 // TODO(all): Try to use stp here.
1903 __ Str(x10, MemOperand(end_elements, i * kPointerSize));
1974 } 1904 }
1975 1905
1976 // Update elements' and array's sizes. 1906 // Update elements' and array's sizes.
1977 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1907 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
1978 __ Add(elements_length, 1908 __ Add(elements_length,
1979 elements_length, 1909 elements_length,
1980 Operand(Smi::FromInt(kAllocationDelta))); 1910 Operand(Smi::FromInt(kAllocationDelta)));
1981 __ Str(elements_length, 1911 __ Str(elements_length,
1982 FieldMemOperand(elements, FixedArray::kLengthOffset)); 1912 FieldMemOperand(elements, FixedArray::kLengthOffset));
1983 1913
1984 // Elements are in new space, so write barrier is not required. 1914 // Elements are in new space, so write barrier is not required.
1985 __ Drop(argc + 1); 1915 __ Drop(argc + 1);
1916 __ Mov(x0, length);
1986 __ Ret(); 1917 __ Ret();
1987 } 1918 }
1988 __ Bind(&call_builtin); 1919 __ Bind(&call_builtin);
1989 __ TailCallExternalReference( 1920 __ TailCallExternalReference(
1990 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); 1921 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1);
1991 } 1922 }
1992 1923
1993 // Handle call cache miss. 1924 HandlerFrontendFooter(&miss);
1994 __ Bind(&miss);
1995 GenerateMissBranch();
1996 1925
1997 // Return the generated code. 1926 // Return the generated code.
1998 return GetCode(type, name); 1927 return GetCode(type, name);
1999 } 1928 }
2000 1929
2001 1930
2002 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1931 Handle<Code> CallStubCompiler::CompileArrayPopCall(
2003 Handle<Object> object, 1932 Handle<Object> object,
2004 Handle<JSObject> holder, 1933 Handle<JSObject> holder,
2005 Handle<Cell> cell, 1934 Handle<Cell> cell,
2006 Handle<JSFunction> function, 1935 Handle<JSFunction> function,
2007 Handle<String> name, 1936 Handle<String> name,
2008 Code::StubType type) { 1937 Code::StubType type) {
2009 // ----------- S t a t e -------------
2010 // -- x2 : name
2011 // -- lr : return address
2012 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2013 // -- ...
2014 // -- sp[argc * 8] : receiver
2015 // -----------------------------------
2016
2017 // If object is not an array or is observed, bail out to regular call. 1938 // If object is not an array or is observed, bail out to regular call.
2018 if (!object->IsJSArray() || 1939 if (!object->IsJSArray() ||
2019 !cell.is_null() || 1940 !cell.is_null() ||
2020 Handle<JSArray>::cast(object)->map()->is_observed()) { 1941 Handle<JSArray>::cast(object)->map()->is_observed()) {
2021 return Handle<Code>::null(); 1942 return Handle<Code>::null();
2022 } 1943 }
2023 1944
2024 const int argc = arguments().immediate(); 1945 const int argc = arguments().immediate();
2025 Register result = x0;
2026 Label miss, return_undefined, call_builtin; 1946 Label miss, return_undefined, call_builtin;
1947 Register receiver = x0;
1948 Register result = x1;
1949 Register elements = x3;
1950 Register length = x4;
2027 1951
2028 GenerateNameCheck(name, &miss); 1952 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2029
2030 // Get the receiver from the stack
2031 Register receiver = x1;
2032 __ Peek(receiver, argc * kPointerSize);
2033 // Check that the receiver isn't a smi.
2034 __ JumpIfSmi(receiver, &miss);
2035
2036 // Check that the maps haven't changed.
2037 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
2038 receiver, holder, x3, x4, x0, name, &miss);
2039 1953
2040 // Get the elements array of the object. 1954 // Get the elements array of the object.
2041 Register elements = x3;
2042 __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1955 __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
2043 1956
2044 // Check that the elements are in fast mode and writable. 1957 // Check that the elements are in fast mode and writable.
2045 __ CheckMap(elements, 1958 __ CheckMap(elements,
2046 x0, 1959 x10,
2047 Heap::kFixedArrayMapRootIndex, 1960 Heap::kFixedArrayMapRootIndex,
2048 &call_builtin, 1961 &call_builtin,
2049 DONT_DO_SMI_CHECK); 1962 DONT_DO_SMI_CHECK);
2050 1963
2051 // Get the array's length and calculate new length. 1964 // Get the array's length and calculate new length.
2052 Register length = x4;
2053 __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1965 __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
2054 __ Subs(length, length, Operand(Smi::FromInt(1))); 1966 __ Subs(length, length, Operand(Smi::FromInt(1)));
2055 __ B(lt, &return_undefined); 1967 __ B(lt, &return_undefined);
2056 1968
2057 // Get the last element. 1969 // Get the last element.
2058 __ Add(elements, elements, 1970 __ Add(elements, elements,
2059 Operand::UntagSmiAndScale(length, kPointerSizeLog2)); 1971 Operand::UntagSmiAndScale(length, kPointerSizeLog2));
2060 __ Ldr(result, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1972 __ Ldr(result, FieldMemOperand(elements, FixedArray::kHeaderSize));
2061 __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &call_builtin); 1973 __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &call_builtin);
2062 1974
2063 // Set the array's length. 1975 // Set the array's length.
2064 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1976 __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
2065 1977
2066 // Fill with the hole. 1978 // Fill with the hole.
2067 Register hole_value = x6; 1979 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
2068 __ LoadRoot(hole_value, Heap::kTheHoleValueRootIndex); 1980 __ Str(x10, FieldMemOperand(elements, FixedArray::kHeaderSize));
2069 __ Str(hole_value, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1981 __ Drop(argc + 1);
1982 __ Mov(x0, result);
1983 __ Ret();
1984
1985 __ Bind(&return_undefined);
1986 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
2070 __ Drop(argc + 1); 1987 __ Drop(argc + 1);
2071 __ Ret(); 1988 __ Ret();
2072 1989
2073 __ Bind(&return_undefined);
2074 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2075 __ Drop(argc + 1);
2076 __ Ret();
2077
2078 __ Bind(&call_builtin); 1990 __ Bind(&call_builtin);
2079 __ TailCallExternalReference( 1991 __ TailCallExternalReference(
2080 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); 1992 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1);
2081 1993
2082 // Handle call cache miss. 1994 HandlerFrontendFooter(&miss);
2083 __ Bind(&miss);
2084 GenerateMissBranch();
2085 1995
2086 // Return the generated code. 1996 // Return the generated code.
2087 return GetCode(type, name); 1997 return GetCode(type, name);
2088 } 1998 }
2089 1999
2090 2000
2091 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 2001 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2092 Handle<Object> object, 2002 Handle<Object> object,
2093 Handle<JSObject> holder, 2003 Handle<JSObject> holder,
2094 Handle<Cell> cell, 2004 Handle<Cell> cell,
2095 Handle<JSFunction> function, 2005 Handle<JSFunction> function,
2096 Handle<String> name, 2006 Handle<String> name,
2097 Code::StubType type) { 2007 Code::StubType type) {
2098 // ----------- S t a t e -------------
2099 // -- x2 : function name
2100 // -- lr : return address
2101 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2102 // -- ...
2103 // -- sp[argc * 8] : receiver
2104 // -----------------------------------
2105
2106 // If object is not a string, bail out to regular call. 2008 // If object is not a string, bail out to regular call.
2107 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2009 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2108 2010
2109 const int argc = arguments().immediate();
2110 Label miss; 2011 Label miss;
2111 Label name_miss; 2012 Label name_miss;
2112 Label index_out_of_range; 2013 Label index_out_of_range;
2113 Label* index_out_of_range_label = &index_out_of_range; 2014 Label* index_out_of_range_label = &index_out_of_range;
2114 2015
2115 if (kind_ == Code::CALL_IC && 2016 if (kind_ == Code::CALL_IC &&
2116 (CallICBase::StringStubState::decode(extra_state_) == 2017 (CallICBase::StringStubState::decode(extra_state_) ==
2117 DEFAULT_STRING_STUB)) { 2018 DEFAULT_STRING_STUB)) {
2118 index_out_of_range_label = &miss; 2019 index_out_of_range_label = &miss;
2119 } 2020 }
2120 GenerateNameCheck(name, &name_miss); 2021 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2121 2022
2122 // Check that the maps starting from the prototype haven't changed. 2023 Register receiver = x0;
2123 Register prototype_reg = x0; 2024 Register result = x1;
2124 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2125 Context::STRING_FUNCTION_INDEX,
2126 prototype_reg,
2127 &miss);
2128 ASSERT(!object.is_identical_to(holder));
2129 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate())));
2130 CheckPrototypes(IC::CurrentTypeOf(prototype, isolate()),
2131 prototype_reg, holder, x1, x3, x4, name, &miss);
2132
2133 Register result = x0;
2134 Register receiver = x1;
2135 Register index = x4; 2025 Register index = x4;
2136 2026
2027 const int argc = arguments().immediate();
2137 __ Peek(receiver, argc * kPointerSize); 2028 __ Peek(receiver, argc * kPointerSize);
2138 if (argc > 0) { 2029 if (argc > 0) {
2139 __ Peek(index, (argc - 1) * kPointerSize); 2030 __ Peek(index, (argc - 1) * kPointerSize);
2140 } else { 2031 } else {
2141 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2032 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2142 } 2033 }
2143 2034
2144 StringCharCodeAtGenerator generator(receiver, 2035 StringCharCodeAtGenerator generator(receiver,
2145 index, 2036 index,
2146 result, 2037 result,
2147 &miss, // When not a string. 2038 &miss, // When not a string.
2148 &miss, // When not a number. 2039 &miss, // When not a number.
2149 index_out_of_range_label, 2040 index_out_of_range_label,
2150 STRING_INDEX_IS_NUMBER); 2041 STRING_INDEX_IS_NUMBER);
2151 generator.GenerateFast(masm()); 2042 generator.GenerateFast(masm());
2152 __ Drop(argc + 1); 2043 __ Drop(argc + 1);
2044 __ Mov(x0, result);
2153 __ Ret(); 2045 __ Ret();
2154 2046
2155 StubRuntimeCallHelper call_helper; 2047 StubRuntimeCallHelper call_helper;
2156 generator.GenerateSlow(masm(), call_helper); 2048 generator.GenerateSlow(masm(), call_helper);
2157 2049
2158 if (index_out_of_range.is_linked()) { 2050 if (index_out_of_range.is_linked()) {
2159 __ Bind(&index_out_of_range); 2051 __ Bind(&index_out_of_range);
2160 __ LoadRoot(result, Heap::kNanValueRootIndex); 2052 __ LoadRoot(result, Heap::kNanValueRootIndex);
2161 __ Drop(argc + 1); 2053 __ Drop(argc + 1);
2162 __ Ret(); 2054 __ Ret();
(...skipping 10 matching lines...) Expand all
2173 } 2065 }
2174 2066
2175 2067
2176 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2068 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2177 Handle<Object> object, 2069 Handle<Object> object,
2178 Handle<JSObject> holder, 2070 Handle<JSObject> holder,
2179 Handle<Cell> cell, 2071 Handle<Cell> cell,
2180 Handle<JSFunction> function, 2072 Handle<JSFunction> function,
2181 Handle<String> name, 2073 Handle<String> name,
2182 Code::StubType type) { 2074 Code::StubType type) {
2183 // ----------- S t a t e -------------
2184 // -- x2 : function name
2185 // -- lr : return address
2186 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2187 // -- ...
2188 // -- sp[argc * 8] : receiver
2189 // -----------------------------------
2190
2191 // If object is not a string, bail out to regular call. 2075 // If object is not a string, bail out to regular call.
2192 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2076 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2193 2077
2194 const int argc = arguments().immediate(); 2078 const int argc = arguments().immediate();
2195 Label miss; 2079 Label miss;
2196 Label name_miss; 2080 Label name_miss;
2197 Label index_out_of_range; 2081 Label index_out_of_range;
2198 Label* index_out_of_range_label = &index_out_of_range; 2082 Label* index_out_of_range_label = &index_out_of_range;
2199 2083
2200 if (kind_ == Code::CALL_IC && 2084 if (kind_ == Code::CALL_IC &&
2201 (CallICBase::StringStubState::decode(extra_state_) == 2085 (CallICBase::StringStubState::decode(extra_state_) ==
2202 DEFAULT_STRING_STUB)) { 2086 DEFAULT_STRING_STUB)) {
2203 index_out_of_range_label = &miss; 2087 index_out_of_range_label = &miss;
2204 } 2088 }
2205 GenerateNameCheck(name, &name_miss);
2206 2089
2207 // Check that the maps starting from the prototype haven't changed. 2090 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2208 Register prototype_reg = x0;
2209 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2210 Context::STRING_FUNCTION_INDEX,
2211 prototype_reg,
2212 &miss);
2213 ASSERT(!object.is_identical_to(holder));
2214 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate())));
2215 CheckPrototypes(IC::CurrentTypeOf(prototype, isolate()),
2216 prototype_reg, holder, x1, x3, x4, name, &miss);
2217 2091
2218 Register receiver = x0; 2092 Register receiver = x0;
2219 Register index = x4; 2093 Register index = x4;
2220 Register scratch = x3; 2094 Register scratch = x3;
2221 Register result = x0; 2095 Register result = x1;
2222 2096
2223 __ Peek(receiver, argc * kPointerSize);
2224 if (argc > 0) { 2097 if (argc > 0) {
2225 __ Peek(index, (argc - 1) * kPointerSize); 2098 __ Peek(index, (argc - 1) * kPointerSize);
2226 } else { 2099 } else {
2227 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2100 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2228 } 2101 }
2229 2102
2230 StringCharAtGenerator generator(receiver, 2103 StringCharAtGenerator generator(receiver,
2231 index, 2104 index,
2232 scratch, 2105 scratch,
2233 result, 2106 result,
2234 &miss, // When not a string. 2107 &miss, // When not a string.
2235 &miss, // When not a number. 2108 &miss, // When not a number.
2236 index_out_of_range_label, 2109 index_out_of_range_label,
2237 STRING_INDEX_IS_NUMBER); 2110 STRING_INDEX_IS_NUMBER);
2238 generator.GenerateFast(masm()); 2111 generator.GenerateFast(masm());
2239 __ Drop(argc + 1); 2112 __ Drop(argc + 1);
2113 __ Mov(x0, result);
2240 __ Ret(); 2114 __ Ret();
2241 2115
2242 StubRuntimeCallHelper call_helper; 2116 StubRuntimeCallHelper call_helper;
2243 generator.GenerateSlow(masm(), call_helper); 2117 generator.GenerateSlow(masm(), call_helper);
2244 2118
2245 if (index_out_of_range.is_linked()) { 2119 if (index_out_of_range.is_linked()) {
2246 __ Bind(&index_out_of_range); 2120 __ Bind(&index_out_of_range);
2247 __ LoadRoot(result, Heap::kempty_stringRootIndex); 2121 __ LoadRoot(result, Heap::kempty_stringRootIndex);
2248 __ Drop(argc + 1); 2122 __ Drop(argc + 1);
2249 __ Ret(); 2123 __ Ret();
(...skipping 10 matching lines...) Expand all
2260 } 2134 }
2261 2135
2262 2136
2263 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2137 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2264 Handle<Object> object, 2138 Handle<Object> object,
2265 Handle<JSObject> holder, 2139 Handle<JSObject> holder,
2266 Handle<Cell> cell, 2140 Handle<Cell> cell,
2267 Handle<JSFunction> function, 2141 Handle<JSFunction> function,
2268 Handle<String> name, 2142 Handle<String> name,
2269 Code::StubType type) { 2143 Code::StubType type) {
2270 // ----------- S t a t e -------------
2271 // -- x2 : function name
2272 // -- lr : return address
2273 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2274 // -- ...
2275 // -- sp[argc * 8] : receiver
2276 // -----------------------------------
2277 const int argc = arguments().immediate(); 2144 const int argc = arguments().immediate();
2278 2145
2279 // If the object is not a JSObject or we got an unexpected number of 2146 // If the object is not a JSObject or we got an unexpected number of
2280 // arguments, bail out to the regular call. 2147 // arguments, bail out to the regular call.
2281 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2148 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2282 2149
2283 Label miss; 2150 Label miss;
2284 GenerateNameCheck(name, &miss);
2285 2151
2286 if (cell.is_null()) { 2152 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2287 Register receiver = x1; 2153 if (!cell.is_null()) {
2288 __ Peek(receiver, kPointerSize);
2289 __ JumpIfSmi(receiver, &miss);
2290
2291 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
2292 receiver, holder, x0, x3, x4, name, &miss);
2293 } else {
2294 ASSERT(cell->value() == *function); 2154 ASSERT(cell->value() == *function);
2295 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2296 &miss);
2297 GenerateLoadFunctionFromCell(cell, function, &miss); 2155 GenerateLoadFunctionFromCell(cell, function, &miss);
2298 } 2156 }
2299 2157
2300 // Load the char code argument. 2158 // Load the char code argument.
2301 Register code = x1; 2159 Register code = x1;
2302 __ Peek(code, 0); 2160 __ Peek(code, 0);
2303 2161
2304 // Check the code is a smi. 2162 // Check the code is a smi.
2305 Label slow; 2163 Label slow;
2306 __ JumpIfNotSmi(code, &slow); 2164 __ JumpIfNotSmi(code, &slow);
(...skipping 10 matching lines...) Expand all
2317 StubRuntimeCallHelper call_helper; 2175 StubRuntimeCallHelper call_helper;
2318 generator.GenerateSlow(masm(), call_helper); 2176 generator.GenerateSlow(masm(), call_helper);
2319 2177
2320 // Tail call the full function. We do not have to patch the receiver 2178 // Tail call the full function. We do not have to patch the receiver
2321 // because the function makes no use of it. 2179 // because the function makes no use of it.
2322 __ Bind(&slow); 2180 __ Bind(&slow);
2323 ParameterCount expected(function); 2181 ParameterCount expected(function);
2324 __ InvokeFunction(function, expected, arguments(), 2182 __ InvokeFunction(function, expected, arguments(),
2325 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2183 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2326 2184
2327 __ Bind(&miss); 2185 HandlerFrontendFooter(&miss);
2328 GenerateMissBranch();
2329 2186
2330 // Return the generated code. 2187 // Return the generated code.
2331 return GetCode(type, name); 2188 return GetCode(type, name);
2332 } 2189 }
2333 2190
2334 2191
2335 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2192 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2336 Handle<Object> object, 2193 Handle<Object> object,
2337 Handle<JSObject> holder, 2194 Handle<JSObject> holder,
2338 Handle<Cell> cell, 2195 Handle<Cell> cell,
2339 Handle<JSFunction> function, 2196 Handle<JSFunction> function,
2340 Handle<String> name, 2197 Handle<String> name,
2341 Code::StubType type) { 2198 Code::StubType type) {
2342 // ----------- S t a t e -------------
2343 // -- x2 : function name (must be preserved on miss)
2344 // -- lr : return address
2345 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2346 // -- ...
2347 // -- sp[argc * 8] : receiver
2348 // -----------------------------------
2349 Label miss; 2199 Label miss;
2350 Label return_result; 2200 Label return_result;
2351 Register result = x0; 2201 Register result = x0;
2352 const int argc = arguments().immediate(); 2202 const int argc = arguments().immediate();
2353 2203
2354 // If the object is not a JSObject or we got an unexpected number of 2204 // If the object is not a JSObject or we got an unexpected number of
2355 // arguments, bail out to the regular call. 2205 // arguments, bail out to the regular call.
2356 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2206 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2357 2207
2358 GenerateNameCheck(name, &miss); 2208 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2359 2209 if (!cell.is_null()) {
2360 if (cell.is_null()) {
2361 Register receiver = x1;
2362 __ Peek(receiver, kPointerSize);
2363 __ JumpIfSmi(receiver, &miss);
2364 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
2365 receiver, holder, x0, x3, x4, name, &miss);
2366 } else {
2367 ASSERT(cell->value() == *function); 2210 ASSERT(cell->value() == *function);
2368 GenerateGlobalReceiverCheck(
2369 Handle<JSObject>::cast(object), holder, name, &miss);
2370 GenerateLoadFunctionFromCell(cell, function, &miss); 2211 GenerateLoadFunctionFromCell(cell, function, &miss);
2371 } 2212 }
2372 2213
2373 // Load the (only) argument. 2214 // Load the (only) argument.
2374 Register arg = x0; 2215 Register arg = x0;
2375 __ Peek(arg, 0); 2216 __ Peek(arg, 0);
2376 2217
2377 // If the argument is a smi, just return. 2218 // If the argument is a smi, just return.
2378 __ JumpIfSmi(arg, &return_result); 2219 __ JumpIfSmi(arg, &return_result);
2379 2220
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2433 __ Drop(argc + 1); 2274 __ Drop(argc + 1);
2434 __ Ret(); 2275 __ Ret();
2435 2276
2436 __ Bind(&slow); 2277 __ Bind(&slow);
2437 // Tail call the full function. We do not have to patch the receiver 2278 // Tail call the full function. We do not have to patch the receiver
2438 // because the function makes no use of it. 2279 // because the function makes no use of it.
2439 ParameterCount expected(function); 2280 ParameterCount expected(function);
2440 __ InvokeFunction(function, expected, arguments(), 2281 __ InvokeFunction(function, expected, arguments(),
2441 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2282 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2442 2283
2443 __ Bind(&miss); 2284 HandlerFrontendFooter(&miss);
2444 GenerateMissBranch();
2445 2285
2446 // Return the generated code. 2286 // Return the generated code.
2447 return GetCode(type, name); 2287 return GetCode(type, name);
2448 } 2288 }
2449 2289
2450 2290
2451 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2291 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2452 Handle<Object> object, 2292 Handle<Object> object,
2453 Handle<JSObject> holder, 2293 Handle<JSObject> holder,
2454 Handle<Cell> cell, 2294 Handle<Cell> cell,
2455 Handle<JSFunction> function, 2295 Handle<JSFunction> function,
2456 Handle<String> name, 2296 Handle<String> name,
2457 Code::StubType type) { 2297 Code::StubType type) {
2458 // ----------- S t a t e -------------
2459 // -- x2 : function name
2460 // -- lr : return address
2461 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2462 // -- ...
2463 // -- sp[argc * 8] : receiver
2464 // -----------------------------------
2465
2466 const int argc = arguments().immediate(); 2298 const int argc = arguments().immediate();
2467 2299
2468 // If the object is not a JSObject or we got an unexpected number of 2300 // If the object is not a JSObject or we got an unexpected number of
2469 // arguments, bail out to the regular call. 2301 // arguments, bail out to the regular call.
2470 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2302 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2471 2303
2472 Register result = x0; 2304 Register result = x0;
2473 Label miss, slow; 2305 Label miss, slow;
2474 GenerateNameCheck(name, &miss); 2306 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2475 2307 if (!cell.is_null()) {
2476 if (cell.is_null()) {
2477 Register receiver = x1;
2478 __ Peek(receiver, kPointerSize);
2479 __ JumpIfSmi(receiver, &miss);
2480 CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
2481 receiver, holder, x0, x3, x4, name, &miss);
2482 } else {
2483 ASSERT(cell->value() == *function); 2308 ASSERT(cell->value() == *function);
2484 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2485 &miss);
2486 GenerateLoadFunctionFromCell(cell, function, &miss); 2309 GenerateLoadFunctionFromCell(cell, function, &miss);
2487 } 2310 }
2488 2311
2489 // Load the (only) argument. 2312 // Load the (only) argument.
2490 Register arg = x0; 2313 Register arg = x0;
2491 __ Peek(arg, 0); 2314 __ Peek(arg, 0);
2492 2315
2493 // Check if the argument is a smi. 2316 // Check if the argument is a smi.
2494 Label not_smi; 2317 Label not_smi;
2495 __ JumpIfNotSmi(arg, &not_smi); 2318 __ JumpIfNotSmi(arg, &not_smi);
(...skipping 24 matching lines...) Expand all
2520 __ Drop(argc + 1); 2343 __ Drop(argc + 1);
2521 __ Ret(); 2344 __ Ret();
2522 2345
2523 // Tail call the full function. We do not have to patch the receiver 2346 // Tail call the full function. We do not have to patch the receiver
2524 // because the function makes no use of it. 2347 // because the function makes no use of it.
2525 __ Bind(&slow); 2348 __ Bind(&slow);
2526 ParameterCount expected(function); 2349 ParameterCount expected(function);
2527 __ InvokeFunction(function, expected, arguments(), 2350 __ InvokeFunction(function, expected, arguments(),
2528 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2351 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2529 2352
2530 __ Bind(&miss); 2353 HandlerFrontendFooter(&miss);
2531 GenerateMissBranch();
2532 2354
2533 // Return the generated code. 2355 // Return the generated code.
2534 return GetCode(type, name); 2356 return GetCode(type, name);
2535 } 2357 }
2536 2358
2537 2359
2538 Handle<Code> CallStubCompiler::CompileFastApiCall( 2360 Handle<Code> CallStubCompiler::CompileFastApiCall(
2539 const CallOptimization& optimization, 2361 const CallOptimization& optimization,
2540 Handle<Object> object, 2362 Handle<Object> object,
2541 Handle<JSObject> holder, 2363 Handle<JSObject> holder,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2591 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2413 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2592 Label success; 2414 Label success;
2593 // Check that the object is a boolean. 2415 // Check that the object is a boolean.
2594 // TODO(all): Optimize this like LCodeGen::DoDeferredTaggedToI. 2416 // TODO(all): Optimize this like LCodeGen::DoDeferredTaggedToI.
2595 __ JumpIfRoot(object, Heap::kTrueValueRootIndex, &success); 2417 __ JumpIfRoot(object, Heap::kTrueValueRootIndex, &success);
2596 __ JumpIfNotRoot(object, Heap::kFalseValueRootIndex, miss); 2418 __ JumpIfNotRoot(object, Heap::kFalseValueRootIndex, miss);
2597 __ Bind(&success); 2419 __ Bind(&success);
2598 } 2420 }
2599 2421
2600 2422
2601 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2423 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2602 Handle<JSObject> holder, 2424 // TODO(all): What is x0 here? Is the use of x3 significant?
2603 Handle<Name> name, 2425 if (object->IsGlobalObject()) {
2604 CheckType check) { 2426 const int argc = arguments().immediate();
2427 const int receiver_offset = argc * kPointerSize;
2428 __ Ldr(x3, FieldMemOperand(x0, GlobalObject::kGlobalReceiverOffset));
2429 __ Poke(x3, receiver_offset);
2430 }
2431 }
2432
2433
2434 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2435 Handle<JSObject> holder,
2436 Handle<Name> name,
2437 CheckType check,
2438 Label* miss) {
2605 // ----------- S t a t e ------------- 2439 // ----------- S t a t e -------------
2606 // -- x2 : name 2440 // -- x2 : name
2607 // -- lr : return address 2441 // -- lr : return address
2608 // ----------------------------------- 2442 // -----------------------------------
2609 Label miss; 2443 GenerateNameCheck(name, miss);
2610 GenerateNameCheck(name, &miss); 2444
2445 Register receiver = x0;
2446 Register prototype_reg = x1;
2611 2447
2612 // Get the receiver from the stack. 2448 // Get the receiver from the stack.
2613 const int argc = arguments().immediate(); 2449 const int argc = arguments().immediate();
2614 Register receiver = x1; 2450 const int receiver_offset = argc * kPointerSize;
2615 __ Peek(receiver, argc * kPointerSize); 2451 __ Peek(receiver, receiver_offset);
2616 2452
2617 // Check that the receiver isn't a smi. 2453 // Check that the receiver isn't a smi.
2618 if (check != NUMBER_CHECK) { 2454 if (check != NUMBER_CHECK) {
2619 __ JumpIfSmi(receiver, &miss); 2455 __ JumpIfSmi(receiver, miss);
2620 } 2456 }
2621 2457
2622 // Make sure that it's okay not to patch the on stack receiver 2458 // Make sure that it's okay not to patch the on stack receiver
2623 // unless we're doing a receiver map check. 2459 // unless we're doing a receiver map check.
2624 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2460 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2625 2461
2626 switch (check) { 2462 switch (check) {
2627 case RECEIVER_MAP_CHECK: { 2463 case RECEIVER_MAP_CHECK: {
2628 __ IncrementCounter(isolate()->counters()->call_const(), 1, x0, x3); 2464 __ IncrementCounter(isolate()->counters()->call_const(), 1, x1, x3);
2629 2465
2630 // Check that the maps haven't changed. 2466 // Check that the maps haven't changed.
2631 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), 2467 receiver = CheckPrototypes(IC::CurrentTypeOf(object, isolate()),
2632 receiver, holder, x0, x3, x4, name, &miss); 2468 receiver, holder, x1, x3, x4, name, miss);
2633
2634 // Patch the receiver on the stack with the global proxy if necessary.
2635 if (object->IsGlobalObject()) {
2636 __ Ldr(x3,
2637 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset));
2638 __ Poke(x3, argc * kPointerSize);
2639 }
2640 break; 2469 break;
2641 } 2470 }
2642 case STRING_CHECK: { 2471 case STRING_CHECK: {
2643 // Check that the object is a string. 2472 // Check that the object is a string.
2644 __ JumpIfObjectType(receiver, x3, x3, FIRST_NONSTRING_TYPE, &miss, ge); 2473 __ JumpIfObjectType(receiver, x3, x3, FIRST_NONSTRING_TYPE, miss, ge);
2645 // Check that the maps starting from the prototype haven't changed. 2474 // Check that the maps starting from the prototype_reg haven't changed.
2646 Register prototype_reg = x0;
2647 GenerateDirectLoadGlobalFunctionPrototype( 2475 GenerateDirectLoadGlobalFunctionPrototype(
2648 masm(), Context::STRING_FUNCTION_INDEX, prototype_reg, &miss); 2476 masm(), Context::STRING_FUNCTION_INDEX, prototype_reg, miss);
2649 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2650 CheckPrototypes(
2651 IC::CurrentTypeOf(prototype, isolate()),
2652 prototype_reg, holder, x3, x1, x4, name, &miss);
2653 break; 2477 break;
2654 } 2478 }
2655 case SYMBOL_CHECK: { 2479 case SYMBOL_CHECK: {
2656 // Check that the object is a symbol. 2480 // Check that the object is a symbol.
2657 __ JumpIfNotObjectType(receiver, x3, x3, SYMBOL_TYPE, &miss); 2481 __ JumpIfNotObjectType(receiver, x3, x3, SYMBOL_TYPE, miss);
2658 // Check that the maps starting from the prototype haven't changed. 2482 // Check that the maps starting from the prototype_reg haven't changed.
2659 Register prototype_reg = x0;
2660 GenerateDirectLoadGlobalFunctionPrototype( 2483 GenerateDirectLoadGlobalFunctionPrototype(
2661 masm(), Context::SYMBOL_FUNCTION_INDEX, prototype_reg, &miss); 2484 masm(), Context::SYMBOL_FUNCTION_INDEX, prototype_reg, miss);
2662 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2663 CheckPrototypes(
2664 IC::CurrentTypeOf(prototype, isolate()),
2665 prototype_reg, holder, x3, x1, x4, name, &miss);
2666 break; 2485 break;
2667 } 2486 }
2668 case NUMBER_CHECK: { 2487 case NUMBER_CHECK: {
2669 Label fast; 2488 Label fast;
2670 // Check that the object is a smi or a heap number. 2489 // Check that the object is a smi or a heap number.
2671 __ JumpIfSmi(receiver, &fast); 2490 __ JumpIfSmi(receiver, &fast);
2672 __ JumpIfNotObjectType(receiver, x0, x0, HEAP_NUMBER_TYPE, &miss); 2491 __ JumpIfNotObjectType(receiver, x3, x3, HEAP_NUMBER_TYPE, miss);
2673 2492
2674 __ Bind(&fast); 2493 __ Bind(&fast);
2675 // Check that the maps starting from the prototype haven't changed. 2494 // Check that the maps starting from the prototype_reg haven't changed.
2676 Register prototype_reg = x0;
2677 GenerateDirectLoadGlobalFunctionPrototype( 2495 GenerateDirectLoadGlobalFunctionPrototype(
2678 masm(), Context::NUMBER_FUNCTION_INDEX, prototype_reg, &miss); 2496 masm(), Context::NUMBER_FUNCTION_INDEX, prototype_reg, miss);
2679 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2680 CheckPrototypes(
2681 IC::CurrentTypeOf(prototype, isolate()),
2682 prototype_reg, holder, x3, x1, x4, name, &miss);
2683 break; 2497 break;
2684 } 2498 }
2685 case BOOLEAN_CHECK: { 2499 case BOOLEAN_CHECK: {
2686 GenerateBooleanCheck(receiver, &miss); 2500 GenerateBooleanCheck(receiver, miss);
2687 2501
2688 // Check that the maps starting from the prototype haven't changed. 2502 // Check that the maps starting from the prototype_reg haven't changed.
2689 Register prototype_reg = x0;
2690 GenerateDirectLoadGlobalFunctionPrototype( 2503 GenerateDirectLoadGlobalFunctionPrototype(
2691 masm(), Context::BOOLEAN_FUNCTION_INDEX, prototype_reg, &miss); 2504 masm(), Context::BOOLEAN_FUNCTION_INDEX, prototype_reg, miss);
2692 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2693 CheckPrototypes(
2694 IC::CurrentTypeOf(prototype, isolate()),
2695 prototype_reg, holder, x3, x1, x4, name, &miss);
2696 break; 2505 break;
2697 } 2506 }
2698 } 2507 }
2699 2508
2700 Label success; 2509 if (check != RECEIVER_MAP_CHECK) {
2701 __ B(&success); 2510 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2511 receiver = CheckPrototypes(
2512 IC::CurrentTypeOf(prototype, isolate()),
2513 prototype_reg, holder, x1, x3, x4, name, miss);
2514 }
2702 2515
2703 // Handle call cache miss. 2516 return receiver;
2704 __ Bind(&miss);
2705 GenerateMissBranch();
2706
2707 __ Bind(&success);
2708 } 2517 }
2709 2518
2710 2519
2711 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2520 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2712 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2521 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2713 ? CALL_AS_FUNCTION 2522 ? CALL_AS_FUNCTION
2714 : CALL_AS_METHOD; 2523 : CALL_AS_METHOD;
2715 ParameterCount expected(function); 2524 ParameterCount expected(function);
2716 __ InvokeFunction(function, expected, arguments(), 2525 __ InvokeFunction(function, expected, arguments(),
2717 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2526 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2718 } 2527 }
2719 2528
2720 2529
2721 Handle<Code> CallStubCompiler::CompileCallConstant( 2530 Handle<Code> CallStubCompiler::CompileCallConstant(
2722 Handle<Object> object, 2531 Handle<Object> object,
2723 Handle<JSObject> holder, 2532 Handle<JSObject> holder,
2724 Handle<Name> name, 2533 Handle<Name> name,
2725 CheckType check, 2534 CheckType check,
2726 Handle<JSFunction> function) { 2535 Handle<JSFunction> function) {
2727 if (HasCustomCallGenerator(function)) { 2536 if (HasCustomCallGenerator(function)) {
2728 Handle<Code> code = CompileCustomCall(object, holder, 2537 Handle<Code> code = CompileCustomCall(object, holder,
2729 Handle<Cell>::null(), 2538 Handle<Cell>::null(),
2730 function, Handle<String>::cast(name), 2539 function, Handle<String>::cast(name),
2731 Code::FAST); 2540 Code::FAST);
2732 // A null handle means bail out to the regular compiler code below. 2541 // A null handle means bail out to the regular compiler code below.
2733 if (!code.is_null()) return code; 2542 if (!code.is_null()) return code;
2734 } 2543 }
2735 2544
2736 CompileHandlerFrontend(object, holder, name, check); 2545 Label miss;
2546 HandlerFrontendHeader(object, holder, name, check, &miss);
2547 PatchGlobalProxy(object);
2737 CompileHandlerBackend(function); 2548 CompileHandlerBackend(function);
2549 HandlerFrontendFooter(&miss);
2738 2550
2739 // Return the generated code. 2551 // Return the generated code.
2740 return GetCode(function); 2552 return GetCode(function);
2741 } 2553 }
2742 2554
2743 2555
2744 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2556 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2745 Handle<JSObject> holder, 2557 Handle<JSObject> holder,
2746 Handle<Name> name) { 2558 Handle<Name> name) {
2747 // ----------- S t a t e -------------
2748 // -- x2 : name
2749 // -- lr : return address
2750 // -----------------------------------
2751 Label miss; 2559 Label miss;
2752 Register name_reg = x2; 2560 Register name_reg = x2;
2753 2561
2754 GenerateNameCheck(name, &miss); 2562 GenerateNameCheck(name, &miss);
2755 2563
2756 const int argc = arguments().immediate(); 2564 const int argc = arguments().immediate();
2757 LookupResult lookup(isolate()); 2565 LookupResult lookup(isolate());
2758 LookupPostInterceptor(holder, name, &lookup); 2566 LookupPostInterceptor(holder, name, &lookup);
2759 2567
2760 // Get the receiver from the stack. 2568 // Get the receiver from the stack.
(...skipping 23 matching lines...) Expand all
2784 return GetCode(Code::FAST, name); 2592 return GetCode(Code::FAST, name);
2785 } 2593 }
2786 2594
2787 2595
2788 Handle<Code> CallStubCompiler::CompileCallGlobal( 2596 Handle<Code> CallStubCompiler::CompileCallGlobal(
2789 Handle<JSObject> object, 2597 Handle<JSObject> object,
2790 Handle<GlobalObject> holder, 2598 Handle<GlobalObject> holder,
2791 Handle<PropertyCell> cell, 2599 Handle<PropertyCell> cell,
2792 Handle<JSFunction> function, 2600 Handle<JSFunction> function,
2793 Handle<Name> name) { 2601 Handle<Name> name) {
2794 // ----------- S t a t e -------------
2795 // -- x2 : name
2796 // -- lr : return address
2797 // -----------------------------------
2798 if (HasCustomCallGenerator(function)) { 2602 if (HasCustomCallGenerator(function)) {
2799 Handle<Code> code = CompileCustomCall( 2603 Handle<Code> code = CompileCustomCall(
2800 object, holder, cell, function, Handle<String>::cast(name), 2604 object, holder, cell, function, Handle<String>::cast(name),
2801 Code::NORMAL); 2605 Code::NORMAL);
2802 // A null handle means bail out to the regular compiler code below. 2606 // A null handle means bail out to the regular compiler code below.
2803 if (!code.is_null()) return code; 2607 if (!code.is_null()) return code;
2804 } 2608 }
2805 2609
2806 Label miss; 2610 Label miss;
2807 GenerateNameCheck(name, &miss); 2611 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2808
2809 // Get the number of arguments.
2810 const int argc = arguments().immediate();
2811
2812 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2813 GenerateLoadFunctionFromCell(cell, function, &miss); 2612 GenerateLoadFunctionFromCell(cell, function, &miss);
2814 // After these two calls the receiver is left in x0 and the function in x1. 2613 // After these two calls the receiver is left in x0 and the function in x1.
2815 Register receiver_reg = x0;
2816 Register function_reg = x1; 2614 Register function_reg = x1;
2817 2615
2818 // Patch the receiver on the stack with the global proxy if necessary. 2616 PatchGlobalProxy(object);
2819 if (object->IsGlobalObject()) {
2820 __ Ldr(x3,
2821 FieldMemOperand(receiver_reg, GlobalObject::kGlobalReceiverOffset));
2822 __ Poke(x3, argc * kPointerSize);
2823 }
2824 2617
2825 // Set up the context. 2618 // Set up the context.
2826 __ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset)); 2619 __ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset));
2827 2620
2828 // Jump to the cached code (tail call). 2621 // Jump to the cached code (tail call).
2829 Counters* counters = isolate()->counters(); 2622 Counters* counters = isolate()->counters();
2830 __ IncrementCounter(counters->call_global_inline(), 1, x3, x4); 2623 __ IncrementCounter(counters->call_global_inline(), 1, x3, x4);
2831 ParameterCount expected(function->shared()->formal_parameter_count()); 2624 ParameterCount expected(function->shared()->formal_parameter_count());
2832 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2625 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2833 ? CALL_AS_FUNCTION 2626 ? CALL_AS_FUNCTION
2834 : CALL_AS_METHOD; 2627 : CALL_AS_METHOD;
2835 // We call indirectly through the code field in the function to 2628 // We call indirectly through the code field in the function to
2836 // allow recompilation to take effect without changing any of the 2629 // allow recompilation to take effect without changing any of the
2837 // call sites. 2630 // call sites.
2838 __ Ldr(x3, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset)); 2631 __ Ldr(x3, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset));
2839 __ InvokeCode( 2632 __ InvokeCode(
2840 x3, expected, arguments(), JUMP_FUNCTION, NullCallWrapper(), call_kind); 2633 x3, expected, arguments(), JUMP_FUNCTION, NullCallWrapper(), call_kind);
2841 2634
2842 // Handle call cache miss. 2635 HandlerFrontendFooter(&miss);
2843 __ Bind(&miss);
2844 __ IncrementCounter(counters->call_global_inline_miss(), 1, x1, x3);
2845 GenerateMissBranch();
2846 2636
2847 // Return the generated code. 2637 // Return the generated code.
2848 return GetCode(Code::NORMAL, name); 2638 return GetCode(Code::NORMAL, name);
2849 } 2639 }
2850 2640
2851 2641
2852 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2642 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2853 Handle<JSObject> object, 2643 Handle<JSObject> object,
2854 Handle<JSObject> holder, 2644 Handle<JSObject> holder,
2855 Handle<Name> name, 2645 Handle<Name> name,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 DO_SMI_CHECK); 2727 DO_SMI_CHECK);
2938 2728
2939 // Perform global security token check if needed. 2729 // Perform global security token check if needed.
2940 if (object->IsJSGlobalProxy()) { 2730 if (object->IsJSGlobalProxy()) {
2941 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss); 2731 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
2942 } 2732 }
2943 2733
2944 // Stub is never generated for non-global objects that require access checks. 2734 // Stub is never generated for non-global objects that require access checks.
2945 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2735 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2946 2736
2947 __ Mov(scratch1(), Operand(Smi::FromInt(strict_mode()))); 2737 __ Push(receiver(), this->name(), value());
2948 __ Push(receiver(), this->name(), value(), scratch1());
2949 2738
2950 // Do tail-call to the runtime system. 2739 // Do tail-call to the runtime system.
2951 ExternalReference store_ic_property = 2740 ExternalReference store_ic_property =
2952 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2741 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2953 __ TailCallExternalReference(store_ic_property, 4, 1); 2742 __ TailCallExternalReference(store_ic_property, 3, 1);
2954 2743
2955 // Handle store cache miss. 2744 // Handle store cache miss.
2956 __ Bind(&miss); 2745 __ Bind(&miss);
2957 TailCallBuiltin(masm(), MissBuiltin(kind())); 2746 TailCallBuiltin(masm(), MissBuiltin(kind()));
2958 2747
2959 // Return the generated code. 2748 // Return the generated code.
2960 return GetCode(kind(), Code::FAST, name); 2749 return GetCode(kind(), Code::FAST, name);
2961 } 2750 }
2962 2751
2963 2752
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
3217 3006
3218 // Miss case, call the runtime. 3007 // Miss case, call the runtime.
3219 __ Bind(&miss); 3008 __ Bind(&miss);
3220 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3009 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3221 } 3010 }
3222 3011
3223 3012
3224 } } // namespace v8::internal 3013 } } // namespace v8::internal
3225 3014
3226 #endif // V8_TARGET_ARCH_A64 3015 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/ic-a64.cc ('k') | src/allocation-site-scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698