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

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

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

Powered by Google App Engine
This is Rietveld 408576698