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

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

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

Powered by Google App Engine
This is Rietveld 408576698