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

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

Issue 83753002: Use the HandlerFrontendHeader in most call compilers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: X64 port Created 7 years 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 | « no previous file | src/ia32/stub-cache-ia32.cc » ('j') | src/ia32/stub-cache-ia32.cc » ('J')
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 // 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 // ----------- S t a t e ------------- 750 // ----------- S t a t e -------------
751 // -- r0: receiver 751 // -- r0: receiver
752 // -- r1: function to call 752 // -- r1: function to call
753 // ----------------------------------- 753 // -----------------------------------
754 754
755 // Check that the function really is a function. 755 // Check that the function really is a function.
756 __ JumpIfSmi(r1, miss); 756 __ JumpIfSmi(r1, miss);
757 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); 757 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
758 __ b(ne, miss); 758 __ b(ne, miss);
759 759
760 // Patch the receiver on the stack with the global proxy if
761 // necessary.
762 if (object->IsGlobalObject()) { 760 if (object->IsGlobalObject()) {
Igor Sheludko 2013/11/28 12:54:27 Looks like PatchGlobalProxy(object); Why don't mak
761 const int argc = arguments.immediate();
762 const int receiver_offset = argc * kPointerSize;
763 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); 763 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
764 __ str(r3, MemOperand(sp, arguments.immediate() * kPointerSize)); 764 __ str(r3, MemOperand(sp, receiver_offset));
765 } 765 }
766 766
767 // Invoke the function. 767 // Invoke the function.
768 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) 768 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
769 ? CALL_AS_FUNCTION 769 ? CALL_AS_FUNCTION
770 : CALL_AS_METHOD; 770 : CALL_AS_METHOD;
771 __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); 771 __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
772 } 772 }
773 773
774 774
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1542
1543 1543
1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1545 if (kind_ == Code::KEYED_CALL_IC) { 1545 if (kind_ == Code::KEYED_CALL_IC) {
1546 __ cmp(r2, Operand(name)); 1546 __ cmp(r2, Operand(name));
1547 __ b(ne, miss); 1547 __ b(ne, miss);
1548 } 1548 }
1549 } 1549 }
1550 1550
1551 1551
1552 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1553 Handle<JSObject> holder,
1554 Handle<Name> name,
1555 Label* miss) {
1556 ASSERT(holder->IsGlobalObject());
1557
1558 // Get the number of arguments.
1559 const int argc = arguments().immediate();
1560
1561 // Get the receiver from the stack.
1562 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
1563
1564 // Check that the maps haven't changed.
1565 __ JumpIfSmi(r0, miss);
1566 CheckPrototypes(
1567 IC::CurrentTypeOf(object, isolate()), r0, holder, r3, r1, r4, name, miss);
1568 }
1569
1570
1571 void CallStubCompiler::GenerateLoadFunctionFromCell( 1552 void CallStubCompiler::GenerateLoadFunctionFromCell(
1572 Handle<Cell> cell, 1553 Handle<Cell> cell,
1573 Handle<JSFunction> function, 1554 Handle<JSFunction> function,
1574 Label* miss) { 1555 Label* miss) {
1575 // Get the value from the cell. 1556 // Get the value from the cell.
1576 __ mov(r3, Operand(cell)); 1557 __ mov(r3, Operand(cell));
1577 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); 1558 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset));
1578 1559
1579 // Check that the cell contains the same function. 1560 // Check that the cell contains the same function.
1580 if (heap()->InNewSpace(*function)) { 1561 if (heap()->InNewSpace(*function)) {
(...skipping 23 matching lines...) Expand all
1604 kind_, 1585 kind_,
1605 extra_state_); 1586 extra_state_);
1606 __ Jump(code, RelocInfo::CODE_TARGET); 1587 __ Jump(code, RelocInfo::CODE_TARGET);
1607 } 1588 }
1608 1589
1609 1590
1610 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1591 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1611 Handle<JSObject> holder, 1592 Handle<JSObject> holder,
1612 PropertyIndex index, 1593 PropertyIndex index,
1613 Handle<Name> name) { 1594 Handle<Name> name) {
1614 // ----------- S t a t e -------------
1615 // -- r2 : name
1616 // -- lr : return address
1617 // -----------------------------------
1618 Label miss; 1595 Label miss;
1619 1596
1620 GenerateNameCheck(name, &miss); 1597 Register reg = HandlerFrontendHeader(
1621 1598 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1622 const int argc = arguments().immediate();
1623
1624 // Get the receiver of the function from the stack into r0.
1625 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
1626 // Check that the receiver isn't a smi.
1627 __ JumpIfSmi(r0, &miss);
1628
1629 // Do the right check and compute the holder register.
1630 Register reg = CheckPrototypes(
1631 IC::CurrentTypeOf(object, isolate()),
1632 r0, holder, r1, r3, r4, name, &miss);
1633 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), 1599 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder),
1634 index.translate(holder), Representation::Tagged()); 1600 index.translate(holder), Representation::Tagged());
1635 1601
1636 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); 1602 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
1637 1603
1638 // Handle call cache miss. 1604 HandlerFrontendFooter(&miss);
1639 __ bind(&miss);
1640 GenerateMissBranch();
1641 1605
1642 // Return the generated code. 1606 // Return the generated code.
1643 return GetCode(Code::FAST, name); 1607 return GetCode(Code::FAST, name);
1644 } 1608 }
1645 1609
1646 1610
1647 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1648 Handle<Object> object, 1612 Handle<Object> object,
1649 Handle<JSObject> holder, 1613 Handle<JSObject> holder,
1650 Handle<Cell> cell, 1614 Handle<Cell> cell,
1651 Handle<JSFunction> function, 1615 Handle<JSFunction> function,
1652 Handle<String> name, 1616 Handle<String> name,
1653 Code::StubType type) { 1617 Code::StubType type) {
1654 Label miss; 1618 Label miss;
1655 1619
1656 // Check that function is still array 1620 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1657 const int argc = arguments().immediate(); 1621 if (!cell.is_null()) {
1658 GenerateNameCheck(name, &miss);
1659 Register receiver = r1;
1660
1661 if (cell.is_null()) {
1662 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
1663
1664 // Check that the receiver isn't a smi.
1665 __ JumpIfSmi(receiver, &miss);
1666
1667 // Check that the maps haven't changed.
1668 CheckPrototypes(
1669 IC::CurrentTypeOf(object, isolate()), receiver, holder,
1670 r3, r0, r4, name, &miss);
1671 } else {
1672 ASSERT(cell->value() == *function); 1622 ASSERT(cell->value() == *function);
1673 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1674 &miss);
1675 GenerateLoadFunctionFromCell(cell, function, &miss); 1623 GenerateLoadFunctionFromCell(cell, function, &miss);
1676 } 1624 }
1677 1625
1678 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1626 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1679 site->SetElementsKind(GetInitialFastElementsKind()); 1627 site->SetElementsKind(GetInitialFastElementsKind());
1680 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1628 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1629 const int argc = arguments().immediate();
1681 __ mov(r0, Operand(argc)); 1630 __ mov(r0, Operand(argc));
1682 __ mov(r2, Operand(site_feedback_cell)); 1631 __ mov(r2, Operand(site_feedback_cell));
1683 __ mov(r1, Operand(function)); 1632 __ mov(r1, Operand(function));
1684 1633
1685 ArrayConstructorStub stub(isolate()); 1634 ArrayConstructorStub stub(isolate());
1686 __ TailCallStub(&stub); 1635 __ TailCallStub(&stub);
1687 1636
1688 __ bind(&miss); 1637 HandlerFrontendFooter(&miss);
1689 GenerateMissBranch();
1690 1638
1691 // Return the generated code. 1639 // Return the generated code.
1692 return GetCode(type, name); 1640 return GetCode(type, name);
1693 } 1641 }
1694 1642
1695 1643
1696 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1644 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1697 Handle<Object> object, 1645 Handle<Object> object,
1698 Handle<JSObject> holder, 1646 Handle<JSObject> holder,
1699 Handle<Cell> cell, 1647 Handle<Cell> cell,
1700 Handle<JSFunction> function, 1648 Handle<JSFunction> function,
1701 Handle<String> name, 1649 Handle<String> name,
1702 Code::StubType type) { 1650 Code::StubType type) {
1703 // ----------- S t a t e -------------
1704 // -- r2 : name
1705 // -- lr : return address
1706 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1707 // -- ...
1708 // -- sp[argc * 4] : receiver
1709 // -----------------------------------
1710
1711 // If object is not an array or is observed, bail out to regular call. 1651 // If object is not an array or is observed, bail out to regular call.
1712 if (!object->IsJSArray() || 1652 if (!object->IsJSArray() ||
1713 !cell.is_null() || 1653 !cell.is_null() ||
1714 Handle<JSArray>::cast(object)->map()->is_observed()) { 1654 Handle<JSArray>::cast(object)->map()->is_observed()) {
1715 return Handle<Code>::null(); 1655 return Handle<Code>::null();
1716 } 1656 }
1717 1657
1718 Label miss; 1658 Label miss;
1719 GenerateNameCheck(name, &miss);
1720 1659
1721 Register receiver = r1; 1660 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1722 // Get the receiver from the stack 1661 Register receiver = r0;
1662 Register scratch = r1;
1663
1723 const int argc = arguments().immediate(); 1664 const int argc = arguments().immediate();
1724 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
1725
1726 // Check that the receiver isn't a smi.
1727 __ JumpIfSmi(receiver, &miss);
1728
1729 // Check that the maps haven't changed.
1730 CheckPrototypes(
1731 IC::CurrentTypeOf(object, isolate()), receiver, holder,
1732 r3, r0, r4, name, &miss);
1733
1734 if (argc == 0) { 1665 if (argc == 0) {
1735 // Nothing to do, just return the length. 1666 // Nothing to do, just return the length.
1736 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1667 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1737 __ Drop(argc + 1); 1668 __ Drop(argc + 1);
1738 __ Ret(); 1669 __ Ret();
1739 } else { 1670 } else {
1740 Label call_builtin; 1671 Label call_builtin;
1741 1672
1742 if (argc == 1) { // Otherwise fall through to call the builtin. 1673 if (argc == 1) { // Otherwise fall through to call the builtin.
1743 Label attempt_to_grow_elements, with_write_barrier, check_double; 1674 Label attempt_to_grow_elements, with_write_barrier, check_double;
1744 1675
1745 Register elements = r6; 1676 Register elements = r6;
1746 Register end_elements = r5; 1677 Register end_elements = r5;
1747 // Get the elements array of the object. 1678 // Get the elements array of the object.
1748 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1679 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1749 1680
1750 // Check that the elements are in fast mode and writable. 1681 // Check that the elements are in fast mode and writable.
1751 __ CheckMap(elements, 1682 __ CheckMap(elements,
1752 r0, 1683 scratch,
1753 Heap::kFixedArrayMapRootIndex, 1684 Heap::kFixedArrayMapRootIndex,
1754 &check_double, 1685 &check_double,
1755 DONT_DO_SMI_CHECK); 1686 DONT_DO_SMI_CHECK);
1756 1687
1757 // Get the array's length into r0 and calculate new length. 1688 // Get the array's length into scratch and calculate new length.
1758 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1689 __ ldr(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1759 __ add(r0, r0, Operand(Smi::FromInt(argc))); 1690 __ add(scratch, scratch, Operand(Smi::FromInt(argc)));
1760 1691
1761 // Get the elements' length. 1692 // Get the elements' length.
1762 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1693 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
1763 1694
1764 // Check if we could survive without allocation. 1695 // Check if we could survive without allocation.
1765 __ cmp(r0, r4); 1696 __ cmp(scratch, r4);
1766 __ b(gt, &attempt_to_grow_elements); 1697 __ b(gt, &attempt_to_grow_elements);
1767 1698
1768 // Check if value is a smi. 1699 // Check if value is a smi.
1769 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); 1700 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
1770 __ JumpIfNotSmi(r4, &with_write_barrier); 1701 __ JumpIfNotSmi(r4, &with_write_barrier);
1771 1702
1772 // Save new length. 1703 // Save new length.
1773 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1704 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1774 1705
1775 // Store the value. 1706 // Store the value.
1776 // We may need a register containing the address end_elements below, 1707 // We may need a register containing the address end_elements below,
1777 // so write back the value in end_elements. 1708 // so write back the value in end_elements.
1778 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0)); 1709 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
1779 const int kEndElementsOffset = 1710 const int kEndElementsOffset =
1780 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1711 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1781 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1712 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1782 1713
1783 // Check for a smi. 1714 // Check for a smi.
1784 __ Drop(argc + 1); 1715 __ Drop(argc + 1);
1716 __ mov(r0, scratch);
1785 __ Ret(); 1717 __ Ret();
1786 1718
1787 __ bind(&check_double); 1719 __ bind(&check_double);
1788 1720
1789 // Check that the elements are in fast mode and writable. 1721 // Check that the elements are in fast mode and writable.
1790 __ CheckMap(elements, 1722 __ CheckMap(elements,
1791 r0, 1723 scratch,
1792 Heap::kFixedDoubleArrayMapRootIndex, 1724 Heap::kFixedDoubleArrayMapRootIndex,
1793 &call_builtin, 1725 &call_builtin,
1794 DONT_DO_SMI_CHECK); 1726 DONT_DO_SMI_CHECK);
1795 1727
1796 // Get the array's length into r0 and calculate new length. 1728 // Get the array's length into scratch and calculate new length.
1797 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1729 __ ldr(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1798 __ add(r0, r0, Operand(Smi::FromInt(argc))); 1730 __ add(scratch, scratch, Operand(Smi::FromInt(argc)));
1799 1731
1800 // Get the elements' length. 1732 // Get the elements' length.
1801 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1733 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
1802 1734
1803 // Check if we could survive without allocation. 1735 // Check if we could survive without allocation.
1804 __ cmp(r0, r4); 1736 __ cmp(scratch, r4);
1805 __ b(gt, &call_builtin); 1737 __ b(gt, &call_builtin);
1806 1738
1807 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); 1739 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
1808 __ StoreNumberToDoubleElements(r4, r0, elements, r5, d0, 1740 __ StoreNumberToDoubleElements(r4, scratch, elements, r5, d0,
1809 &call_builtin, argc * kDoubleSize); 1741 &call_builtin, argc * kDoubleSize);
1810 1742
1811 // Save new length. 1743 // Save new length.
1812 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1744 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1813 1745
1814 // Check for a smi.
1815 __ Drop(argc + 1); 1746 __ Drop(argc + 1);
1747 __ mov(r0, scratch);
1816 __ Ret(); 1748 __ Ret();
1817 1749
1818 __ bind(&with_write_barrier); 1750 __ bind(&with_write_barrier);
1819 1751
1820 __ ldr(r3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1752 __ ldr(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1821 1753
1822 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { 1754 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1823 Label fast_object, not_fast_object; 1755 Label fast_object, not_fast_object;
1824 __ CheckFastObjectElements(r3, r9, &not_fast_object); 1756 __ CheckFastObjectElements(r3, r9, &not_fast_object);
1825 __ jmp(&fast_object); 1757 __ jmp(&fast_object);
(...skipping 30 matching lines...) Expand all
1856 ElementsTransitionGenerator:: 1788 ElementsTransitionGenerator::
1857 GenerateMapChangeElementsTransition(masm(), 1789 GenerateMapChangeElementsTransition(masm(),
1858 DONT_TRACK_ALLOCATION_SITE, 1790 DONT_TRACK_ALLOCATION_SITE,
1859 NULL); 1791 NULL);
1860 __ bind(&fast_object); 1792 __ bind(&fast_object);
1861 } else { 1793 } else {
1862 __ CheckFastObjectElements(r3, r3, &call_builtin); 1794 __ CheckFastObjectElements(r3, r3, &call_builtin);
1863 } 1795 }
1864 1796
1865 // Save new length. 1797 // Save new length.
1866 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1798 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1867 1799
1868 // Store the value. 1800 // Store the value.
1869 // We may need a register containing the address end_elements below, 1801 // We may need a register containing the address end_elements below,
1870 // so write back the value in end_elements. 1802 // so write back the value in end_elements.
1871 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0)); 1803 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
1872 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1804 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1873 1805
1874 __ RecordWrite(elements, 1806 __ RecordWrite(elements,
1875 end_elements, 1807 end_elements,
1876 r4, 1808 r4,
1877 kLRHasNotBeenSaved, 1809 kLRHasNotBeenSaved,
1878 kDontSaveFPRegs, 1810 kDontSaveFPRegs,
1879 EMIT_REMEMBERED_SET, 1811 EMIT_REMEMBERED_SET,
1880 OMIT_SMI_CHECK); 1812 OMIT_SMI_CHECK);
1881 __ Drop(argc + 1); 1813 __ Drop(argc + 1);
1814 __ mov(r0, scratch);
1882 __ Ret(); 1815 __ Ret();
1883 1816
1884 __ bind(&attempt_to_grow_elements); 1817 __ bind(&attempt_to_grow_elements);
1885 // r0: array's length + 1. 1818 // scratch: array's length + 1.
1886 1819
1887 if (!FLAG_inline_new) { 1820 if (!FLAG_inline_new) {
1888 __ b(&call_builtin); 1821 __ b(&call_builtin);
1889 } 1822 }
1890 1823
1891 __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize)); 1824 __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize));
1892 // Growing elements that are SMI-only requires special handling in case 1825 // Growing elements that are SMI-only requires special handling in case
1893 // the new element is non-Smi. For now, delegate to the builtin. 1826 // the new element is non-Smi. For now, delegate to the builtin.
1894 Label no_fast_elements_check; 1827 Label no_fast_elements_check;
1895 __ JumpIfSmi(r2, &no_fast_elements_check); 1828 __ JumpIfSmi(r2, &no_fast_elements_check);
1896 __ ldr(r9, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1829 __ ldr(r9, FieldMemOperand(receiver, HeapObject::kMapOffset));
1897 __ CheckFastObjectElements(r9, r9, &call_builtin); 1830 __ CheckFastObjectElements(r9, r9, &call_builtin);
1898 __ bind(&no_fast_elements_check); 1831 __ bind(&no_fast_elements_check);
1899 1832
1900 ExternalReference new_space_allocation_top = 1833 ExternalReference new_space_allocation_top =
1901 ExternalReference::new_space_allocation_top_address(isolate()); 1834 ExternalReference::new_space_allocation_top_address(isolate());
1902 ExternalReference new_space_allocation_limit = 1835 ExternalReference new_space_allocation_limit =
1903 ExternalReference::new_space_allocation_limit_address(isolate()); 1836 ExternalReference::new_space_allocation_limit_address(isolate());
1904 1837
1905 const int kAllocationDelta = 4; 1838 const int kAllocationDelta = 4;
1906 // Load top and check if it is the end of elements. 1839 // Load top and check if it is the end of elements.
1907 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0)); 1840 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
1908 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); 1841 __ add(end_elements, end_elements, Operand(kEndElementsOffset));
1909 __ mov(r4, Operand(new_space_allocation_top)); 1842 __ mov(r4, Operand(new_space_allocation_top));
1910 __ ldr(r3, MemOperand(r4)); 1843 __ ldr(r3, MemOperand(r4));
1911 __ cmp(end_elements, r3); 1844 __ cmp(end_elements, r3);
1912 __ b(ne, &call_builtin); 1845 __ b(ne, &call_builtin);
1913 1846
1914 __ mov(r9, Operand(new_space_allocation_limit)); 1847 __ mov(r9, Operand(new_space_allocation_limit));
1915 __ ldr(r9, MemOperand(r9)); 1848 __ ldr(r9, MemOperand(r9));
1916 __ add(r3, r3, Operand(kAllocationDelta * kPointerSize)); 1849 __ add(r3, r3, Operand(kAllocationDelta * kPointerSize));
1917 __ cmp(r3, r9); 1850 __ cmp(r3, r9);
1918 __ b(hi, &call_builtin); 1851 __ b(hi, &call_builtin);
1919 1852
1920 // We fit and could grow elements. 1853 // We fit and could grow elements.
1921 // Update new_space_allocation_top. 1854 // Update new_space_allocation_top.
1922 __ str(r3, MemOperand(r4)); 1855 __ str(r3, MemOperand(r4));
1923 // Push the argument. 1856 // Push the argument.
1924 __ str(r2, MemOperand(end_elements)); 1857 __ str(r2, MemOperand(end_elements));
1925 // Fill the rest with holes. 1858 // Fill the rest with holes.
1926 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); 1859 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
1927 for (int i = 1; i < kAllocationDelta; i++) { 1860 for (int i = 1; i < kAllocationDelta; i++) {
1928 __ str(r3, MemOperand(end_elements, i * kPointerSize)); 1861 __ str(r3, MemOperand(end_elements, i * kPointerSize));
1929 } 1862 }
1930 1863
1931 // Update elements' and array's sizes. 1864 // Update elements' and array's sizes.
1932 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1865 __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1933 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1866 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
1934 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); 1867 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta)));
1935 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1868 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
1936 1869
1937 // Elements are in new space, so write barrier is not required. 1870 // Elements are in new space, so write barrier is not required.
1938 __ Drop(argc + 1); 1871 __ Drop(argc + 1);
1872 __ mov(r0, scratch);
1939 __ Ret(); 1873 __ Ret();
1940 } 1874 }
1941 __ bind(&call_builtin); 1875 __ bind(&call_builtin);
1942 __ TailCallExternalReference( 1876 __ TailCallExternalReference(
1943 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); 1877 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1);
1944 } 1878 }
1945 1879
1946 // Handle call cache miss. 1880 HandlerFrontendFooter(&miss);
1947 __ bind(&miss);
1948 GenerateMissBranch();
1949 1881
1950 // Return the generated code. 1882 // Return the generated code.
1951 return GetCode(type, name); 1883 return GetCode(type, name);
1952 } 1884 }
1953 1885
1954 1886
1955 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1887 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1956 Handle<Object> object, 1888 Handle<Object> object,
1957 Handle<JSObject> holder, 1889 Handle<JSObject> holder,
1958 Handle<Cell> cell, 1890 Handle<Cell> cell,
1959 Handle<JSFunction> function, 1891 Handle<JSFunction> function,
1960 Handle<String> name, 1892 Handle<String> name,
1961 Code::StubType type) { 1893 Code::StubType type) {
1962 // ----------- S t a t e -------------
1963 // -- r2 : name
1964 // -- lr : return address
1965 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1966 // -- ...
1967 // -- sp[argc * 4] : receiver
1968 // -----------------------------------
1969
1970 // If object is not an array or is observed, bail out to regular call. 1894 // If object is not an array or is observed, bail out to regular call.
1971 if (!object->IsJSArray() || 1895 if (!object->IsJSArray() ||
1972 !cell.is_null() || 1896 !cell.is_null() ||
1973 Handle<JSArray>::cast(object)->map()->is_observed()) { 1897 Handle<JSArray>::cast(object)->map()->is_observed()) {
1974 return Handle<Code>::null(); 1898 return Handle<Code>::null();
1975 } 1899 }
1976 1900
1977 Label miss, return_undefined, call_builtin; 1901 Label miss, return_undefined, call_builtin;
1978 Register receiver = r1; 1902 Register receiver = r0;
1903 Register scratch = r1;
1979 Register elements = r3; 1904 Register elements = r3;
1980 GenerateNameCheck(name, &miss);
1981 1905
1982 // Get the receiver from the stack 1906 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1983 const int argc = arguments().immediate();
1984 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
1985 // Check that the receiver isn't a smi.
1986 __ JumpIfSmi(receiver, &miss);
1987
1988 // Check that the maps haven't changed.
1989 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), receiver, holder,
1990 elements, r4, r0, name, &miss);
1991 1907
1992 // Get the elements array of the object. 1908 // Get the elements array of the object.
1993 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1909 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1994 1910
1995 // Check that the elements are in fast mode and writable. 1911 // Check that the elements are in fast mode and writable.
1996 __ CheckMap(elements, 1912 __ CheckMap(elements,
1997 r0, 1913 scratch,
1998 Heap::kFixedArrayMapRootIndex, 1914 Heap::kFixedArrayMapRootIndex,
1999 &call_builtin, 1915 &call_builtin,
2000 DONT_DO_SMI_CHECK); 1916 DONT_DO_SMI_CHECK);
2001 1917
2002 // Get the array's length into r4 and calculate new length. 1918 // Get the array's length into r4 and calculate new length.
2003 __ ldr(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1919 __ ldr(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
2004 __ sub(r4, r4, Operand(Smi::FromInt(1)), SetCC); 1920 __ sub(r4, r4, Operand(Smi::FromInt(1)), SetCC);
2005 __ b(lt, &return_undefined); 1921 __ b(lt, &return_undefined);
2006 1922
2007 // Get the last element. 1923 // Get the last element.
2008 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); 1924 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex);
2009 // We can't address the last element in one operation. Compute the more 1925 // We can't address the last element in one operation. Compute the more
2010 // expensive shift first, and use an offset later on. 1926 // expensive shift first, and use an offset later on.
2011 __ add(elements, elements, Operand::PointerOffsetFromSmiKey(r4)); 1927 __ add(elements, elements, Operand::PointerOffsetFromSmiKey(r4));
2012 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1928 __ ldr(scratch, FieldMemOperand(elements, FixedArray::kHeaderSize));
2013 __ cmp(r0, r6); 1929 __ cmp(scratch, r6);
2014 __ b(eq, &call_builtin); 1930 __ b(eq, &call_builtin);
2015 1931
2016 // Set the array's length. 1932 // Set the array's length.
2017 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1933 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
2018 1934
2019 // Fill with the hole. 1935 // Fill with the hole.
2020 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1936 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize));
1937 const int argc = arguments().immediate();
2021 __ Drop(argc + 1); 1938 __ Drop(argc + 1);
1939 __ mov(r0, scratch);
2022 __ Ret(); 1940 __ Ret();
2023 1941
2024 __ bind(&return_undefined); 1942 __ bind(&return_undefined);
2025 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1943 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2026 __ Drop(argc + 1); 1944 __ Drop(argc + 1);
2027 __ Ret(); 1945 __ Ret();
2028 1946
2029 __ bind(&call_builtin); 1947 __ bind(&call_builtin);
2030 __ TailCallExternalReference( 1948 __ TailCallExternalReference(
2031 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); 1949 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1);
2032 1950
2033 // Handle call cache miss. 1951 HandlerFrontendFooter(&miss);
2034 __ bind(&miss);
2035 GenerateMissBranch();
2036 1952
2037 // Return the generated code. 1953 // Return the generated code.
2038 return GetCode(type, name); 1954 return GetCode(type, name);
2039 } 1955 }
2040 1956
2041 1957
2042 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1958 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2043 Handle<Object> object, 1959 Handle<Object> object,
2044 Handle<JSObject> holder, 1960 Handle<JSObject> holder,
2045 Handle<Cell> cell, 1961 Handle<Cell> cell,
2046 Handle<JSFunction> function, 1962 Handle<JSFunction> function,
2047 Handle<String> name, 1963 Handle<String> name,
2048 Code::StubType type) { 1964 Code::StubType type) {
2049 // ----------- S t a t e -------------
2050 // -- r2 : function name
2051 // -- lr : return address
2052 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2053 // -- ...
2054 // -- sp[argc * 4] : receiver
2055 // -----------------------------------
2056
2057 // If object is not a string, bail out to regular call. 1965 // If object is not a string, bail out to regular call.
2058 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1966 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2059 1967
2060 const int argc = arguments().immediate();
2061 Label miss; 1968 Label miss;
2062 Label name_miss; 1969 Label name_miss;
2063 Label index_out_of_range; 1970 Label index_out_of_range;
2064 Label* index_out_of_range_label = &index_out_of_range; 1971 Label* index_out_of_range_label = &index_out_of_range;
2065 1972
2066 if (kind_ == Code::CALL_IC && 1973 if (kind_ == Code::CALL_IC &&
2067 (CallICBase::StringStubState::decode(extra_state_) == 1974 (CallICBase::StringStubState::decode(extra_state_) ==
2068 DEFAULT_STRING_STUB)) { 1975 DEFAULT_STRING_STUB)) {
2069 index_out_of_range_label = &miss; 1976 index_out_of_range_label = &miss;
2070 } 1977 }
2071 GenerateNameCheck(name, &name_miss);
2072 1978
2073 // Check that the maps starting from the prototype haven't changed. 1979 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2074 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2075 Context::STRING_FUNCTION_INDEX,
2076 r0,
2077 &miss);
2078 ASSERT(!object.is_identical_to(holder));
2079 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate())));
2080 CheckPrototypes(
2081 IC::CurrentTypeOf(prototype, isolate()),
2082 r0, holder, r1, r3, r4, name, &miss);
2083 1980
2084 Register receiver = r1; 1981 Register receiver = r0;
2085 Register index = r4; 1982 Register index = r4;
2086 Register result = r0; 1983 Register result = r1;
1984 const int argc = arguments().immediate();
2087 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); 1985 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
2088 if (argc > 0) { 1986 if (argc > 0) {
2089 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1987 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize));
2090 } else { 1988 } else {
2091 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 1989 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2092 } 1990 }
2093 1991
2094 StringCharCodeAtGenerator generator(receiver, 1992 StringCharCodeAtGenerator generator(receiver,
2095 index, 1993 index,
2096 result, 1994 result,
2097 &miss, // When not a string. 1995 &miss, // When not a string.
2098 &miss, // When not a number. 1996 &miss, // When not a number.
2099 index_out_of_range_label, 1997 index_out_of_range_label,
2100 STRING_INDEX_IS_NUMBER); 1998 STRING_INDEX_IS_NUMBER);
2101 generator.GenerateFast(masm()); 1999 generator.GenerateFast(masm());
2102 __ Drop(argc + 1); 2000 __ Drop(argc + 1);
2001 __ mov(r0, result);
2103 __ Ret(); 2002 __ Ret();
2104 2003
2105 StubRuntimeCallHelper call_helper; 2004 StubRuntimeCallHelper call_helper;
2106 generator.GenerateSlow(masm(), call_helper); 2005 generator.GenerateSlow(masm(), call_helper);
2107 2006
2108 if (index_out_of_range.is_linked()) { 2007 if (index_out_of_range.is_linked()) {
2109 __ bind(&index_out_of_range); 2008 __ bind(&index_out_of_range);
2110 __ LoadRoot(r0, Heap::kNanValueRootIndex); 2009 __ LoadRoot(r0, Heap::kNanValueRootIndex);
2111 __ Drop(argc + 1); 2010 __ Drop(argc + 1);
2112 __ Ret(); 2011 __ Ret();
(...skipping 10 matching lines...) Expand all
2123 } 2022 }
2124 2023
2125 2024
2126 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2127 Handle<Object> object, 2026 Handle<Object> object,
2128 Handle<JSObject> holder, 2027 Handle<JSObject> holder,
2129 Handle<Cell> cell, 2028 Handle<Cell> cell,
2130 Handle<JSFunction> function, 2029 Handle<JSFunction> function,
2131 Handle<String> name, 2030 Handle<String> name,
2132 Code::StubType type) { 2031 Code::StubType type) {
2133 // ----------- S t a t e -------------
2134 // -- r2 : function name
2135 // -- lr : return address
2136 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2137 // -- ...
2138 // -- sp[argc * 4] : receiver
2139 // -----------------------------------
2140
2141 // If object is not a string, bail out to regular call. 2032 // If object is not a string, bail out to regular call.
2142 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2033 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2143 2034
2144 const int argc = arguments().immediate(); 2035 const int argc = arguments().immediate();
2145 Label miss; 2036 Label miss;
2146 Label name_miss; 2037 Label name_miss;
2147 Label index_out_of_range; 2038 Label index_out_of_range;
2148 Label* index_out_of_range_label = &index_out_of_range; 2039 Label* index_out_of_range_label = &index_out_of_range;
2149 if (kind_ == Code::CALL_IC && 2040 if (kind_ == Code::CALL_IC &&
2150 (CallICBase::StringStubState::decode(extra_state_) == 2041 (CallICBase::StringStubState::decode(extra_state_) ==
2151 DEFAULT_STRING_STUB)) { 2042 DEFAULT_STRING_STUB)) {
2152 index_out_of_range_label = &miss; 2043 index_out_of_range_label = &miss;
2153 } 2044 }
2154 GenerateNameCheck(name, &name_miss);
2155 2045
2156 // Check that the maps starting from the prototype haven't changed. 2046 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2157 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2158 Context::STRING_FUNCTION_INDEX,
2159 r0,
2160 &miss);
2161 ASSERT(!object.is_identical_to(holder));
2162 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate())));
2163 CheckPrototypes(
2164 IC::CurrentTypeOf(prototype, isolate()),
2165 r0, holder, r1, r3, r4, name, &miss);
2166 2047
2167 Register receiver = r0; 2048 Register receiver = r0;
2168 Register index = r4; 2049 Register index = r4;
2169 Register scratch = r3; 2050 Register scratch = r3;
2170 Register result = r0; 2051 Register result = r1;
2171 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
2172 if (argc > 0) { 2052 if (argc > 0) {
2173 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); 2053 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize));
2174 } else { 2054 } else {
2175 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2055 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2176 } 2056 }
2177 2057
2178 StringCharAtGenerator generator(receiver, 2058 StringCharAtGenerator generator(receiver,
2179 index, 2059 index,
2180 scratch, 2060 scratch,
2181 result, 2061 result,
2182 &miss, // When not a string. 2062 &miss, // When not a string.
2183 &miss, // When not a number. 2063 &miss, // When not a number.
2184 index_out_of_range_label, 2064 index_out_of_range_label,
2185 STRING_INDEX_IS_NUMBER); 2065 STRING_INDEX_IS_NUMBER);
2186 generator.GenerateFast(masm()); 2066 generator.GenerateFast(masm());
2187 __ Drop(argc + 1); 2067 __ Drop(argc + 1);
2068 __ mov(r0, result);
2188 __ Ret(); 2069 __ Ret();
2189 2070
2190 StubRuntimeCallHelper call_helper; 2071 StubRuntimeCallHelper call_helper;
2191 generator.GenerateSlow(masm(), call_helper); 2072 generator.GenerateSlow(masm(), call_helper);
2192 2073
2193 if (index_out_of_range.is_linked()) { 2074 if (index_out_of_range.is_linked()) {
2194 __ bind(&index_out_of_range); 2075 __ bind(&index_out_of_range);
2195 __ LoadRoot(r0, Heap::kempty_stringRootIndex); 2076 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
2196 __ Drop(argc + 1); 2077 __ Drop(argc + 1);
2197 __ Ret(); 2078 __ Ret();
(...skipping 10 matching lines...) Expand all
2208 } 2089 }
2209 2090
2210 2091
2211 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2092 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2212 Handle<Object> object, 2093 Handle<Object> object,
2213 Handle<JSObject> holder, 2094 Handle<JSObject> holder,
2214 Handle<Cell> cell, 2095 Handle<Cell> cell,
2215 Handle<JSFunction> function, 2096 Handle<JSFunction> function,
2216 Handle<String> name, 2097 Handle<String> name,
2217 Code::StubType type) { 2098 Code::StubType type) {
2218 // ----------- S t a t e -------------
2219 // -- r2 : function name
2220 // -- lr : return address
2221 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2222 // -- ...
2223 // -- sp[argc * 4] : receiver
2224 // -----------------------------------
2225
2226 const int argc = arguments().immediate(); 2099 const int argc = arguments().immediate();
2227 2100
2228 // If the object is not a JSObject or we got an unexpected number of 2101 // If the object is not a JSObject or we got an unexpected number of
2229 // arguments, bail out to the regular call. 2102 // arguments, bail out to the regular call.
2230 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2103 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2231 2104
2232 Label miss; 2105 Label miss;
2233 GenerateNameCheck(name, &miss);
2234 2106
2235 if (cell.is_null()) { 2107 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2236 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2108 if (!cell.is_null()) {
2237
2238 __ JumpIfSmi(r1, &miss);
2239
2240 CheckPrototypes(
2241 IC::CurrentTypeOf(object, isolate()),
2242 r1, holder, r0, r3, r4, name, &miss);
2243 } else {
2244 ASSERT(cell->value() == *function); 2109 ASSERT(cell->value() == *function);
2245 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2246 &miss);
2247 GenerateLoadFunctionFromCell(cell, function, &miss); 2110 GenerateLoadFunctionFromCell(cell, function, &miss);
2248 } 2111 }
2249 2112
2250 // Load the char code argument. 2113 // Load the char code argument.
2251 Register code = r1; 2114 Register code = r1;
2252 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); 2115 __ ldr(code, MemOperand(sp, 0 * kPointerSize));
2253 2116
2254 // Check the code is a smi. 2117 // Check the code is a smi.
2255 Label slow; 2118 Label slow;
2256 __ JumpIfNotSmi(code, &slow); 2119 __ JumpIfNotSmi(code, &slow);
2257 2120
2258 // Convert the smi code to uint16. 2121 // Convert the smi code to uint16.
2259 __ and_(code, code, Operand(Smi::FromInt(0xffff))); 2122 __ and_(code, code, Operand(Smi::FromInt(0xffff)));
2260 2123
2261 StringCharFromCodeGenerator generator(code, r0); 2124 StringCharFromCodeGenerator generator(code, r0);
2262 generator.GenerateFast(masm()); 2125 generator.GenerateFast(masm());
2263 __ Drop(argc + 1); 2126 __ Drop(argc + 1);
2264 __ Ret(); 2127 __ Ret();
2265 2128
2266 StubRuntimeCallHelper call_helper; 2129 StubRuntimeCallHelper call_helper;
2267 generator.GenerateSlow(masm(), call_helper); 2130 generator.GenerateSlow(masm(), call_helper);
2268 2131
2269 // Tail call the full function. We do not have to patch the receiver 2132 // Tail call the full function. We do not have to patch the receiver
2270 // because the function makes no use of it. 2133 // because the function makes no use of it.
2271 __ bind(&slow); 2134 __ bind(&slow);
2272 ParameterCount expected(function); 2135 ParameterCount expected(function);
2273 __ InvokeFunction(function, expected, arguments(), 2136 __ InvokeFunction(function, expected, arguments(),
2274 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2137 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2275 2138
2276 __ bind(&miss); 2139 HandlerFrontendFooter(&miss);
2277 // r2: function name.
2278 GenerateMissBranch();
2279 2140
2280 // Return the generated code. 2141 // Return the generated code.
2281 return GetCode(type, name); 2142 return GetCode(type, name);
2282 } 2143 }
2283 2144
2284 2145
2285 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2146 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2286 Handle<Object> object, 2147 Handle<Object> object,
2287 Handle<JSObject> holder, 2148 Handle<JSObject> holder,
2288 Handle<Cell> cell, 2149 Handle<Cell> cell,
2289 Handle<JSFunction> function, 2150 Handle<JSFunction> function,
2290 Handle<String> name, 2151 Handle<String> name,
2291 Code::StubType type) { 2152 Code::StubType type) {
2292 // ----------- S t a t e -------------
2293 // -- r2 : function name
2294 // -- lr : return address
2295 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2296 // -- ...
2297 // -- sp[argc * 4] : receiver
2298 // -----------------------------------
2299
2300 const int argc = arguments().immediate(); 2153 const int argc = arguments().immediate();
2301 // If the object is not a JSObject or we got an unexpected number of 2154 // If the object is not a JSObject or we got an unexpected number of
2302 // arguments, bail out to the regular call. 2155 // arguments, bail out to the regular call.
2303 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2156 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2304 2157
2305 Label miss, slow; 2158 Label miss, slow;
2306 GenerateNameCheck(name, &miss);
2307 2159
2308 if (cell.is_null()) { 2160 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2309 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2161 if (!cell.is_null()) {
2310 __ JumpIfSmi(r1, &miss);
2311 CheckPrototypes(
2312 IC::CurrentTypeOf(object, isolate()),
2313 r1, holder, r0, r3, r4, name, &miss);
2314 } else {
2315 ASSERT(cell->value() == *function); 2162 ASSERT(cell->value() == *function);
2316 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2317 &miss);
2318 GenerateLoadFunctionFromCell(cell, function, &miss); 2163 GenerateLoadFunctionFromCell(cell, function, &miss);
2319 } 2164 }
2320 2165
2321 // Load the (only) argument into r0. 2166 // Load the (only) argument into r0.
2322 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); 2167 __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
2323 2168
2324 // If the argument is a smi, just return. 2169 // If the argument is a smi, just return.
2325 __ SmiTst(r0); 2170 __ SmiTst(r0);
2326 __ Drop(argc + 1, eq); 2171 __ Drop(argc + 1, eq);
2327 __ Ret(eq); 2172 __ Ret(eq);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 __ Drop(argc + 1); 2221 __ Drop(argc + 1);
2377 __ Ret(); 2222 __ Ret();
2378 2223
2379 __ bind(&slow); 2224 __ bind(&slow);
2380 // Tail call the full function. We do not have to patch the receiver 2225 // Tail call the full function. We do not have to patch the receiver
2381 // because the function makes no use of it. 2226 // because the function makes no use of it.
2382 ParameterCount expected(function); 2227 ParameterCount expected(function);
2383 __ InvokeFunction(function, expected, arguments(), 2228 __ InvokeFunction(function, expected, arguments(),
2384 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2229 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2385 2230
2386 __ bind(&miss); 2231 HandlerFrontendFooter(&miss);
2387 // r2: function name.
2388 GenerateMissBranch();
2389 2232
2390 // Return the generated code. 2233 // Return the generated code.
2391 return GetCode(type, name); 2234 return GetCode(type, name);
2392 } 2235 }
2393 2236
2394 2237
2395 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2238 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2396 Handle<Object> object, 2239 Handle<Object> object,
2397 Handle<JSObject> holder, 2240 Handle<JSObject> holder,
2398 Handle<Cell> cell, 2241 Handle<Cell> cell,
2399 Handle<JSFunction> function, 2242 Handle<JSFunction> function,
2400 Handle<String> name, 2243 Handle<String> name,
2401 Code::StubType type) { 2244 Code::StubType type) {
2402 // ----------- S t a t e -------------
2403 // -- r2 : function name
2404 // -- lr : return address
2405 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2406 // -- ...
2407 // -- sp[argc * 4] : receiver
2408 // -----------------------------------
2409
2410 const int argc = arguments().immediate(); 2245 const int argc = arguments().immediate();
2411 // If the object is not a JSObject or we got an unexpected number of 2246 // If the object is not a JSObject or we got an unexpected number of
2412 // arguments, bail out to the regular call. 2247 // arguments, bail out to the regular call.
2413 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2248 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2414 2249
2415 Label miss; 2250 Label miss;
2416 GenerateNameCheck(name, &miss); 2251
2417 if (cell.is_null()) { 2252 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2418 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2253 if (!cell.is_null()) {
2419 __ JumpIfSmi(r1, &miss);
2420 CheckPrototypes(
2421 IC::CurrentTypeOf(object, isolate()),
2422 r1, holder, r0, r3, r4, name, &miss);
2423 } else {
2424 ASSERT(cell->value() == *function); 2254 ASSERT(cell->value() == *function);
2425 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2426 &miss);
2427 GenerateLoadFunctionFromCell(cell, function, &miss); 2255 GenerateLoadFunctionFromCell(cell, function, &miss);
2428 } 2256 }
2429 2257
2430 // Load the (only) argument into r0. 2258 // Load the (only) argument into r0.
2431 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); 2259 __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
2432 2260
2433 // Check if the argument is a smi. 2261 // Check if the argument is a smi.
2434 Label not_smi; 2262 Label not_smi;
2435 __ JumpIfNotSmi(r0, &not_smi); 2263 __ JumpIfNotSmi(r0, &not_smi);
2436 2264
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 __ Drop(argc + 1); 2304 __ Drop(argc + 1);
2477 __ Ret(); 2305 __ Ret();
2478 2306
2479 // Tail call the full function. We do not have to patch the receiver 2307 // Tail call the full function. We do not have to patch the receiver
2480 // because the function makes no use of it. 2308 // because the function makes no use of it.
2481 __ bind(&slow); 2309 __ bind(&slow);
2482 ParameterCount expected(function); 2310 ParameterCount expected(function);
2483 __ InvokeFunction(function, expected, arguments(), 2311 __ InvokeFunction(function, expected, arguments(),
2484 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2312 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2485 2313
2486 __ bind(&miss); 2314 HandlerFrontendFooter(&miss);
2487 // r2: function name.
2488 GenerateMissBranch();
2489 2315
2490 // Return the generated code. 2316 // Return the generated code.
2491 return GetCode(type, name); 2317 return GetCode(type, name);
2492 } 2318 }
2493 2319
2494 2320
2495 Handle<Code> CallStubCompiler::CompileFastApiCall( 2321 Handle<Code> CallStubCompiler::CompileFastApiCall(
2496 const CallOptimization& optimization, 2322 const CallOptimization& optimization,
2497 Handle<Object> object, 2323 Handle<Object> object,
2498 Handle<JSObject> holder, 2324 Handle<JSObject> holder,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 2376 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
2551 __ cmp(object, ip); 2377 __ cmp(object, ip);
2552 __ b(eq, &success); 2378 __ b(eq, &success);
2553 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 2379 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
2554 __ cmp(object, ip); 2380 __ cmp(object, ip);
2555 __ b(ne, miss); 2381 __ b(ne, miss);
2556 __ bind(&success); 2382 __ bind(&success);
2557 } 2383 }
2558 2384
2559 2385
2560 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2386 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2561 Handle<JSObject> holder, 2387 if (object->IsGlobalObject()) {
2562 Handle<Name> name, 2388 const int argc = arguments().immediate();
2563 CheckType check) { 2389 const int receiver_offset = argc * kPointerSize;
2390 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
2391 __ str(r3, MemOperand(sp, receiver_offset));
2392 }
2393 }
2394
2395
2396 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2397 Handle<JSObject> holder,
2398 Handle<Name> name,
2399 CheckType check,
2400 Label* miss) {
2564 // ----------- S t a t e ------------- 2401 // ----------- S t a t e -------------
2565 // -- r2 : name 2402 // -- r2 : name
2566 // -- lr : return address 2403 // -- lr : return address
2567 // ----------------------------------- 2404 // -----------------------------------
2568 Label miss; 2405 GenerateNameCheck(name, miss);
2569 GenerateNameCheck(name, &miss); 2406
2407 Register reg = r0;
2570 2408
2571 // Get the receiver from the stack 2409 // Get the receiver from the stack
2572 const int argc = arguments().immediate(); 2410 const int argc = arguments().immediate();
2573 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2411 const int receiver_offset = argc * kPointerSize;
2412 __ ldr(r0, MemOperand(sp, receiver_offset));
2574 2413
2575 // Check that the receiver isn't a smi. 2414 // Check that the receiver isn't a smi.
2576 if (check != NUMBER_CHECK) { 2415 if (check != NUMBER_CHECK) {
2577 __ JumpIfSmi(r1, &miss); 2416 __ JumpIfSmi(r0, miss);
2578 } 2417 }
2579 2418
2580 // Make sure that it's okay not to patch the on stack receiver 2419 // Make sure that it's okay not to patch the on stack receiver
2581 // unless we're doing a receiver map check. 2420 // unless we're doing a receiver map check.
2582 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2421 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2583 switch (check) { 2422 switch (check) {
2584 case RECEIVER_MAP_CHECK: 2423 case RECEIVER_MAP_CHECK:
2585 __ IncrementCounter(isolate()->counters()->call_const(), 1, r0, r3); 2424 __ IncrementCounter(isolate()->counters()->call_const(), 1, r1, r3);
2586 2425
2587 // Check that the maps haven't changed. 2426 // Check that the maps haven't changed.
2588 CheckPrototypes( 2427 reg = CheckPrototypes(
2589 IC::CurrentTypeOf(object, isolate()), 2428 IC::CurrentTypeOf(object, isolate()),
2590 r1, holder, r0, r3, r4, name, &miss); 2429 reg, holder, r1, r3, r4, name, miss);
2591
2592 // Patch the receiver on the stack with the global proxy if
2593 // necessary.
2594 if (object->IsGlobalObject()) {
2595 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2596 __ str(r3, MemOperand(sp, argc * kPointerSize));
2597 }
2598 break; 2430 break;
2599 2431
2600 case STRING_CHECK: { 2432 case STRING_CHECK: {
2601 // Check that the object is a string. 2433 // Check that the object is a string.
2602 __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); 2434 __ CompareObjectType(reg, r3, r3, FIRST_NONSTRING_TYPE);
2603 __ b(ge, &miss); 2435 __ b(ge, miss);
2604 // Check that the maps starting from the prototype haven't changed. 2436 // Check that the maps starting from the prototype haven't changed.
2605 GenerateDirectLoadGlobalFunctionPrototype( 2437 GenerateDirectLoadGlobalFunctionPrototype(
2606 masm(), Context::STRING_FUNCTION_INDEX, r0, &miss); 2438 masm(), Context::STRING_FUNCTION_INDEX, r1, miss);
2607 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2608 CheckPrototypes(
2609 IC::CurrentTypeOf(prototype, isolate()),
2610 r0, holder, r3, r1, r4, name, &miss);
2611 break; 2439 break;
2612 } 2440 }
2613 case SYMBOL_CHECK: { 2441 case SYMBOL_CHECK: {
2614 // Check that the object is a symbol. 2442 // Check that the object is a symbol.
2615 __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE); 2443 __ CompareObjectType(reg, r3, r3, SYMBOL_TYPE);
2616 __ b(ne, &miss); 2444 __ b(ne, miss);
2617 // Check that the maps starting from the prototype haven't changed. 2445 // Check that the maps starting from the prototype haven't changed.
2618 GenerateDirectLoadGlobalFunctionPrototype( 2446 GenerateDirectLoadGlobalFunctionPrototype(
2619 masm(), Context::SYMBOL_FUNCTION_INDEX, r0, &miss); 2447 masm(), Context::SYMBOL_FUNCTION_INDEX, r1, miss);
2620 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2621 CheckPrototypes(
2622 IC::CurrentTypeOf(prototype, isolate()),
2623 r0, holder, r3, r1, r4, name, &miss);
2624 break; 2448 break;
2625 } 2449 }
2626 case NUMBER_CHECK: { 2450 case NUMBER_CHECK: {
2627 Label fast; 2451 Label fast;
2628 // Check that the object is a smi or a heap number. 2452 // Check that the object is a smi or a heap number.
2629 __ JumpIfSmi(r1, &fast); 2453 __ JumpIfSmi(reg, &fast);
2630 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); 2454 __ CompareObjectType(reg, r3, r3, HEAP_NUMBER_TYPE);
2631 __ b(ne, &miss); 2455 __ b(ne, miss);
2632 __ bind(&fast); 2456 __ bind(&fast);
2633 // Check that the maps starting from the prototype haven't changed. 2457 // Check that the maps starting from the prototype haven't changed.
2634 GenerateDirectLoadGlobalFunctionPrototype( 2458 GenerateDirectLoadGlobalFunctionPrototype(
2635 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); 2459 masm(), Context::NUMBER_FUNCTION_INDEX, r1, miss);
2636 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2637 CheckPrototypes(
2638 IC::CurrentTypeOf(prototype, isolate()),
2639 r0, holder, r3, r1, r4, name, &miss);
2640 break; 2460 break;
2641 } 2461 }
2642 case BOOLEAN_CHECK: { 2462 case BOOLEAN_CHECK: {
2643 GenerateBooleanCheck(r1, &miss); 2463 GenerateBooleanCheck(reg, miss);
2644 2464
2645 // Check that the maps starting from the prototype haven't changed. 2465 // Check that the maps starting from the prototype haven't changed.
2646 GenerateDirectLoadGlobalFunctionPrototype( 2466 GenerateDirectLoadGlobalFunctionPrototype(
2647 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); 2467 masm(), Context::BOOLEAN_FUNCTION_INDEX, r1, miss);
2648 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2649 CheckPrototypes(
2650 IC::CurrentTypeOf(prototype, isolate()),
2651 r0, holder, r3, r1, r4, name, &miss);
2652 break; 2468 break;
2653 } 2469 }
2654 } 2470 }
2655 2471
2656 Label success; 2472 if (check != RECEIVER_MAP_CHECK) {
2657 __ b(&success); 2473 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2474 reg = CheckPrototypes(
2475 IC::CurrentTypeOf(prototype, isolate()),
2476 r1, holder, r1, r3, r4, name, miss);
2477 }
2658 2478
2659 // Handle call cache miss. 2479 return reg;
2660 __ bind(&miss);
2661 GenerateMissBranch();
2662
2663 __ bind(&success);
2664 } 2480 }
2665 2481
2666 2482
2667 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2483 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2668 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2484 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2669 ? CALL_AS_FUNCTION 2485 ? CALL_AS_FUNCTION
2670 : CALL_AS_METHOD; 2486 : CALL_AS_METHOD;
2671 ParameterCount expected(function); 2487 ParameterCount expected(function);
2672 __ InvokeFunction(function, expected, arguments(), 2488 __ InvokeFunction(function, expected, arguments(),
2673 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2489 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2674 } 2490 }
2675 2491
2676 2492
2677 Handle<Code> CallStubCompiler::CompileCallConstant( 2493 Handle<Code> CallStubCompiler::CompileCallConstant(
2678 Handle<Object> object, 2494 Handle<Object> object,
2679 Handle<JSObject> holder, 2495 Handle<JSObject> holder,
2680 Handle<Name> name, 2496 Handle<Name> name,
2681 CheckType check, 2497 CheckType check,
2682 Handle<JSFunction> function) { 2498 Handle<JSFunction> function) {
2683 if (HasCustomCallGenerator(function)) { 2499 if (HasCustomCallGenerator(function)) {
2684 Handle<Code> code = CompileCustomCall(object, holder, 2500 Handle<Code> code = CompileCustomCall(object, holder,
2685 Handle<Cell>::null(), 2501 Handle<Cell>::null(),
2686 function, Handle<String>::cast(name), 2502 function, Handle<String>::cast(name),
2687 Code::FAST); 2503 Code::FAST);
2688 // A null handle means bail out to the regular compiler code below. 2504 // A null handle means bail out to the regular compiler code below.
2689 if (!code.is_null()) return code; 2505 if (!code.is_null()) return code;
2690 } 2506 }
2691 2507
2692 CompileHandlerFrontend(object, holder, name, check); 2508 Label miss;
2509 HandlerFrontendHeader(object, holder, name, check, &miss);
2510 PatchGlobalProxy(object);
2693 CompileHandlerBackend(function); 2511 CompileHandlerBackend(function);
2512 HandlerFrontendFooter(&miss);
2694 2513
2695 // Return the generated code. 2514 // Return the generated code.
2696 return GetCode(function); 2515 return GetCode(function);
2697 } 2516 }
2698 2517
2699 2518
2700 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2519 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2701 Handle<JSObject> holder, 2520 Handle<JSObject> holder,
2702 Handle<Name> name) { 2521 Handle<Name> name) {
2703 // ----------- S t a t e -------------
2704 // -- r2 : name
2705 // -- lr : return address
2706 // -----------------------------------
2707 Label miss; 2522 Label miss;
2708 GenerateNameCheck(name, &miss); 2523 GenerateNameCheck(name, &miss);
2709 2524
2710 // Get the number of arguments. 2525 // Get the number of arguments.
2711 const int argc = arguments().immediate(); 2526 const int argc = arguments().immediate();
2712 LookupResult lookup(isolate()); 2527 LookupResult lookup(isolate());
2713 LookupPostInterceptor(holder, name, &lookup); 2528 LookupPostInterceptor(holder, name, &lookup);
2714 2529
2715 // Get the receiver from the stack. 2530 // Get the receiver from the stack.
2716 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2531 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
(...skipping 17 matching lines...) Expand all
2734 return GetCode(Code::FAST, name); 2549 return GetCode(Code::FAST, name);
2735 } 2550 }
2736 2551
2737 2552
2738 Handle<Code> CallStubCompiler::CompileCallGlobal( 2553 Handle<Code> CallStubCompiler::CompileCallGlobal(
2739 Handle<JSObject> object, 2554 Handle<JSObject> object,
2740 Handle<GlobalObject> holder, 2555 Handle<GlobalObject> holder,
2741 Handle<PropertyCell> cell, 2556 Handle<PropertyCell> cell,
2742 Handle<JSFunction> function, 2557 Handle<JSFunction> function,
2743 Handle<Name> name) { 2558 Handle<Name> name) {
2744 // ----------- S t a t e -------------
2745 // -- r2 : name
2746 // -- lr : return address
2747 // -----------------------------------
2748 if (HasCustomCallGenerator(function)) { 2559 if (HasCustomCallGenerator(function)) {
2749 Handle<Code> code = CompileCustomCall( 2560 Handle<Code> code = CompileCustomCall(
2750 object, holder, cell, function, Handle<String>::cast(name), 2561 object, holder, cell, function, Handle<String>::cast(name),
2751 Code::NORMAL); 2562 Code::NORMAL);
2752 // A null handle means bail out to the regular compiler code below. 2563 // A null handle means bail out to the regular compiler code below.
2753 if (!code.is_null()) return code; 2564 if (!code.is_null()) return code;
2754 } 2565 }
2755 2566
2756 Label miss; 2567 Label miss;
2757 GenerateNameCheck(name, &miss); 2568 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2758
2759 // Get the number of arguments.
2760 const int argc = arguments().immediate();
2761 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2762 GenerateLoadFunctionFromCell(cell, function, &miss); 2569 GenerateLoadFunctionFromCell(cell, function, &miss);
2763 2570 PatchGlobalProxy(object);
2764 // Patch the receiver on the stack with the global proxy if
2765 // necessary.
2766 if (object->IsGlobalObject()) {
2767 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
2768 __ str(r3, MemOperand(sp, argc * kPointerSize));
2769 }
2770 2571
2771 // Set up the context (function already in r1). 2572 // Set up the context (function already in r1).
2772 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 2573 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2773 2574
2774 // Jump to the cached code (tail call). 2575 // Jump to the cached code (tail call).
2775 Counters* counters = isolate()->counters(); 2576 Counters* counters = isolate()->counters();
2776 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); 2577 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
2777 ParameterCount expected(function->shared()->formal_parameter_count()); 2578 ParameterCount expected(function->shared()->formal_parameter_count());
2778 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2579 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2779 ? CALL_AS_FUNCTION 2580 ? CALL_AS_FUNCTION
2780 : CALL_AS_METHOD; 2581 : CALL_AS_METHOD;
2781 // We call indirectly through the code field in the function to 2582 // We call indirectly through the code field in the function to
2782 // allow recompilation to take effect without changing any of the 2583 // allow recompilation to take effect without changing any of the
2783 // call sites. 2584 // call sites.
2784 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 2585 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2785 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, 2586 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION,
2786 NullCallWrapper(), call_kind); 2587 NullCallWrapper(), call_kind);
2787 2588
2788 // Handle call cache miss. 2589 HandlerFrontendFooter(&miss);
2789 __ bind(&miss);
2790 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3);
2791 GenerateMissBranch();
2792 2590
2793 // Return the generated code. 2591 // Return the generated code.
2794 return GetCode(Code::NORMAL, name); 2592 return GetCode(Code::NORMAL, name);
2795 } 2593 }
2796 2594
2797 2595
2798 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2596 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2799 Handle<JSObject> object, 2597 Handle<JSObject> object,
2800 Handle<JSObject> holder, 2598 Handle<JSObject> holder,
2801 Handle<Name> name, 2599 Handle<Name> name,
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
3175 // ----------------------------------- 2973 // -----------------------------------
3176 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2974 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3177 } 2975 }
3178 2976
3179 2977
3180 #undef __ 2978 #undef __
3181 2979
3182 } } // namespace v8::internal 2980 } } // namespace v8::internal
3183 2981
3184 #endif // V8_TARGET_ARCH_ARM 2982 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/ia32/stub-cache-ia32.cc » ('j') | src/ia32/stub-cache-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698