OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1684 } | 1684 } |
1685 context()->Plug(r0); | 1685 context()->Plug(r0); |
1686 } | 1686 } |
1687 | 1687 |
1688 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1688 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1689 Handle<Object> name, | 1689 Handle<Object> name, |
1690 RelocInfo::Mode mode) { | 1690 RelocInfo::Mode mode) { |
1691 // Code common for calls using the IC. | 1691 // Code common for calls using the IC. |
1692 ZoneList<Expression*>* args = expr->arguments(); | 1692 ZoneList<Expression*>* args = expr->arguments(); |
1693 int arg_count = args->length(); | 1693 int arg_count = args->length(); |
1694 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1694 { PreservePositionScope scope(masm()->positions_recorder()); |
1695 for (int i = 0; i < arg_count; i++) { | 1695 for (int i = 0; i < arg_count; i++) { |
1696 VisitForStackValue(args->at(i)); | 1696 VisitForStackValue(args->at(i)); |
1697 } | 1697 } |
1698 __ mov(r2, Operand(name)); | 1698 __ mov(r2, Operand(name)); |
1699 } | 1699 } |
1700 // Record source position for debugger. | 1700 // Record source position for debugger. |
1701 SetSourcePosition(expr->position(), FORCED_POSITION); | 1701 SetSourcePosition(expr->position()); |
1702 // Call the IC initialization code. | 1702 // Call the IC initialization code. |
1703 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1703 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1704 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); | 1704 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); |
1705 EmitCallIC(ic, mode); | 1705 EmitCallIC(ic, mode); |
1706 // Restore context register. | 1706 // Restore context register. |
1707 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1707 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1708 context()->Plug(r0); | 1708 context()->Plug(r0); |
1709 } | 1709 } |
1710 | 1710 |
1711 | 1711 |
1712 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 1712 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
1713 Expression* key, | 1713 Expression* key, |
1714 RelocInfo::Mode mode) { | 1714 RelocInfo::Mode mode) { |
1715 // Load the key. | 1715 // Load the key. |
1716 VisitForAccumulatorValue(key); | 1716 VisitForAccumulatorValue(key); |
1717 | 1717 |
1718 // Swap the name of the function and the receiver on the stack to follow | 1718 // Swap the name of the function and the receiver on the stack to follow |
1719 // the calling convention for call ICs. | 1719 // the calling convention for call ICs. |
1720 __ pop(r1); | 1720 __ pop(r1); |
1721 __ push(r0); | 1721 __ push(r0); |
1722 __ push(r1); | 1722 __ push(r1); |
1723 | 1723 |
1724 // Code common for calls using the IC. | 1724 // Code common for calls using the IC. |
1725 ZoneList<Expression*>* args = expr->arguments(); | 1725 ZoneList<Expression*>* args = expr->arguments(); |
1726 int arg_count = args->length(); | 1726 int arg_count = args->length(); |
1727 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1727 { PreservePositionScope scope(masm()->positions_recorder()); |
1728 for (int i = 0; i < arg_count; i++) { | 1728 for (int i = 0; i < arg_count; i++) { |
1729 VisitForStackValue(args->at(i)); | 1729 VisitForStackValue(args->at(i)); |
1730 } | 1730 } |
1731 } | 1731 } |
1732 // Record source position for debugger. | 1732 // Record source position for debugger. |
1733 SetSourcePosition(expr->position(), FORCED_POSITION); | 1733 SetSourcePosition(expr->position()); |
1734 // Call the IC initialization code. | 1734 // Call the IC initialization code. |
1735 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1735 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1736 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); | 1736 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); |
1737 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 1737 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
1738 EmitCallIC(ic, mode); | 1738 EmitCallIC(ic, mode); |
1739 // Restore context register. | 1739 // Restore context register. |
1740 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1740 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1741 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 1741 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
1742 } | 1742 } |
1743 | 1743 |
1744 | 1744 |
1745 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1745 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
1746 // Code common for calls using the call stub. | 1746 // Code common for calls using the call stub. |
1747 ZoneList<Expression*>* args = expr->arguments(); | 1747 ZoneList<Expression*>* args = expr->arguments(); |
1748 int arg_count = args->length(); | 1748 int arg_count = args->length(); |
1749 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1749 { PreservePositionScope scope(masm()->positions_recorder()); |
1750 for (int i = 0; i < arg_count; i++) { | 1750 for (int i = 0; i < arg_count; i++) { |
1751 VisitForStackValue(args->at(i)); | 1751 VisitForStackValue(args->at(i)); |
1752 } | 1752 } |
1753 } | 1753 } |
1754 // Record source position for debugger. | 1754 // Record source position for debugger. |
1755 SetSourcePosition(expr->position(), FORCED_POSITION); | 1755 SetSourcePosition(expr->position()); |
1756 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1756 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1757 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1757 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1758 __ CallStub(&stub); | 1758 __ CallStub(&stub); |
1759 // Restore context register. | 1759 // Restore context register. |
1760 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1760 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1761 context()->DropAndPlug(1, r0); | 1761 context()->DropAndPlug(1, r0); |
1762 } | 1762 } |
1763 | 1763 |
1764 | 1764 |
1765 void FullCodeGenerator::VisitCall(Call* expr) { | 1765 void FullCodeGenerator::VisitCall(Call* expr) { |
1766 Comment cmnt(masm_, "[ Call"); | 1766 Comment cmnt(masm_, "[ Call"); |
1767 Expression* fun = expr->expression(); | 1767 Expression* fun = expr->expression(); |
1768 Variable* var = fun->AsVariableProxy()->AsVariable(); | 1768 Variable* var = fun->AsVariableProxy()->AsVariable(); |
1769 | 1769 |
1770 if (var != NULL && var->is_possibly_eval()) { | 1770 if (var != NULL && var->is_possibly_eval()) { |
1771 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 1771 // In a call to eval, we first call %ResolvePossiblyDirectEval to |
1772 // resolve the function we need to call and the receiver of the | 1772 // resolve the function we need to call and the receiver of the |
1773 // call. Then we call the resolved function using the given | 1773 // call. Then we call the resolved function using the given |
1774 // arguments. | 1774 // arguments. |
1775 ZoneList<Expression*>* args = expr->arguments(); | 1775 ZoneList<Expression*>* args = expr->arguments(); |
1776 int arg_count = args->length(); | 1776 int arg_count = args->length(); |
1777 | 1777 |
1778 { PreserveStatementPositionScope pos_scope(masm()->positions_recorder()); | 1778 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
1779 VisitForStackValue(fun); | 1779 VisitForStackValue(fun); |
1780 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 1780 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
1781 __ push(r2); // Reserved receiver slot. | 1781 __ push(r2); // Reserved receiver slot. |
1782 | 1782 |
1783 // Push the arguments. | 1783 // Push the arguments. |
1784 for (int i = 0; i < arg_count; i++) { | 1784 for (int i = 0; i < arg_count; i++) { |
1785 VisitForStackValue(args->at(i)); | 1785 VisitForStackValue(args->at(i)); |
1786 } | 1786 } |
1787 | 1787 |
1788 // Push copy of the function - found below the arguments. | 1788 // Push copy of the function - found below the arguments. |
(...skipping 14 matching lines...) Expand all Loading... |
1803 __ push(r1); | 1803 __ push(r1); |
1804 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); | 1804 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); |
1805 | 1805 |
1806 // The runtime call returns a pair of values in r0 (function) and | 1806 // The runtime call returns a pair of values in r0 (function) and |
1807 // r1 (receiver). Touch up the stack with the right values. | 1807 // r1 (receiver). Touch up the stack with the right values. |
1808 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 1808 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
1809 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | 1809 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
1810 } | 1810 } |
1811 | 1811 |
1812 // Record source position for debugger. | 1812 // Record source position for debugger. |
1813 SetSourcePosition(expr->position(), FORCED_POSITION); | 1813 SetSourcePosition(expr->position()); |
1814 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1814 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1815 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1815 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1816 __ CallStub(&stub); | 1816 __ CallStub(&stub); |
1817 // Restore context register. | 1817 // Restore context register. |
1818 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1818 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1819 context()->DropAndPlug(1, r0); | 1819 context()->DropAndPlug(1, r0); |
1820 } else if (var != NULL && !var->is_this() && var->is_global()) { | 1820 } else if (var != NULL && !var->is_this() && var->is_global()) { |
1821 // Push global object as receiver for the call IC. | 1821 // Push global object as receiver for the call IC. |
1822 __ ldr(r0, GlobalObjectOperand()); | 1822 __ ldr(r0, GlobalObjectOperand()); |
1823 __ push(r0); | 1823 __ push(r0); |
1824 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 1824 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
1825 } else if (var != NULL && var->AsSlot() != NULL && | 1825 } else if (var != NULL && var->AsSlot() != NULL && |
1826 var->AsSlot()->type() == Slot::LOOKUP) { | 1826 var->AsSlot()->type() == Slot::LOOKUP) { |
1827 // Call to a lookup slot (dynamically introduced variable). | 1827 // Call to a lookup slot (dynamically introduced variable). |
1828 Label slow, done; | 1828 Label slow, done; |
1829 | 1829 |
1830 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1830 { PreservePositionScope scope(masm()->positions_recorder()); |
1831 // Generate code for loading from variables potentially shadowed | 1831 // Generate code for loading from variables potentially shadowed |
1832 // by eval-introduced variables. | 1832 // by eval-introduced variables. |
1833 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), | 1833 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), |
1834 NOT_INSIDE_TYPEOF, | 1834 NOT_INSIDE_TYPEOF, |
1835 &slow, | 1835 &slow, |
1836 &done); | 1836 &done); |
1837 } | 1837 } |
1838 | 1838 |
1839 __ bind(&slow); | 1839 __ bind(&slow); |
1840 // Call the runtime to find the function to call (returned in r0) | 1840 // Call the runtime to find the function to call (returned in r0) |
(...skipping 20 matching lines...) Expand all Loading... |
1861 __ bind(&call); | 1861 __ bind(&call); |
1862 } | 1862 } |
1863 | 1863 |
1864 EmitCallWithStub(expr); | 1864 EmitCallWithStub(expr); |
1865 } else if (fun->AsProperty() != NULL) { | 1865 } else if (fun->AsProperty() != NULL) { |
1866 // Call to an object property. | 1866 // Call to an object property. |
1867 Property* prop = fun->AsProperty(); | 1867 Property* prop = fun->AsProperty(); |
1868 Literal* key = prop->key()->AsLiteral(); | 1868 Literal* key = prop->key()->AsLiteral(); |
1869 if (key != NULL && key->handle()->IsSymbol()) { | 1869 if (key != NULL && key->handle()->IsSymbol()) { |
1870 // Call to a named property, use call IC. | 1870 // Call to a named property, use call IC. |
1871 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1871 { PreservePositionScope scope(masm()->positions_recorder()); |
1872 VisitForStackValue(prop->obj()); | 1872 VisitForStackValue(prop->obj()); |
1873 } | 1873 } |
1874 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 1874 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
1875 } else { | 1875 } else { |
1876 // Call to a keyed property. | 1876 // Call to a keyed property. |
1877 // For a synthetic property use keyed load IC followed by function call, | 1877 // For a synthetic property use keyed load IC followed by function call, |
1878 // for a regular property use keyed CallIC. | 1878 // for a regular property use keyed CallIC. |
1879 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1879 { PreservePositionScope scope(masm()->positions_recorder()); |
1880 VisitForStackValue(prop->obj()); | 1880 VisitForStackValue(prop->obj()); |
1881 } | 1881 } |
1882 if (prop->is_synthetic()) { | 1882 if (prop->is_synthetic()) { |
1883 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1883 { PreservePositionScope scope(masm()->positions_recorder()); |
1884 VisitForAccumulatorValue(prop->key()); | 1884 VisitForAccumulatorValue(prop->key()); |
1885 } | 1885 } |
1886 // Record source code position for IC call. | 1886 // Record source code position for IC call. |
1887 SetSourcePosition(prop->position(), FORCED_POSITION); | 1887 SetSourcePosition(prop->position()); |
1888 __ pop(r1); // We do not need to keep the receiver. | 1888 __ pop(r1); // We do not need to keep the receiver. |
1889 | 1889 |
1890 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1890 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1891 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1891 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1892 __ ldr(r1, GlobalObjectOperand()); | 1892 __ ldr(r1, GlobalObjectOperand()); |
1893 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1893 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
1894 __ Push(r0, r1); // Function, receiver. | 1894 __ Push(r0, r1); // Function, receiver. |
1895 EmitCallWithStub(expr); | 1895 EmitCallWithStub(expr); |
1896 } else { | 1896 } else { |
1897 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 1897 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
1898 } | 1898 } |
1899 } | 1899 } |
1900 } else { | 1900 } else { |
1901 // Call to some other expression. If the expression is an anonymous | 1901 // Call to some other expression. If the expression is an anonymous |
1902 // function literal not called in a loop, mark it as one that should | 1902 // function literal not called in a loop, mark it as one that should |
1903 // also use the fast code generator. | 1903 // also use the fast code generator. |
1904 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1904 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
1905 if (lit != NULL && | 1905 if (lit != NULL && |
1906 lit->name()->Equals(Heap::empty_string()) && | 1906 lit->name()->Equals(Heap::empty_string()) && |
1907 loop_depth() == 0) { | 1907 loop_depth() == 0) { |
1908 lit->set_try_full_codegen(true); | 1908 lit->set_try_full_codegen(true); |
1909 } | 1909 } |
1910 | 1910 |
1911 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1911 { PreservePositionScope scope(masm()->positions_recorder()); |
1912 VisitForStackValue(fun); | 1912 VisitForStackValue(fun); |
1913 } | 1913 } |
1914 // Load global receiver object. | 1914 // Load global receiver object. |
1915 __ ldr(r1, GlobalObjectOperand()); | 1915 __ ldr(r1, GlobalObjectOperand()); |
1916 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1916 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
1917 __ push(r1); | 1917 __ push(r1); |
1918 // Emit function call. | 1918 // Emit function call. |
1919 EmitCallWithStub(expr); | 1919 EmitCallWithStub(expr); |
1920 } | 1920 } |
1921 } | 1921 } |
(...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3438 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3438 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
3439 __ add(pc, r1, Operand(masm_->CodeObject())); | 3439 __ add(pc, r1, Operand(masm_->CodeObject())); |
3440 } | 3440 } |
3441 | 3441 |
3442 | 3442 |
3443 #undef __ | 3443 #undef __ |
3444 | 3444 |
3445 } } // namespace v8::internal | 3445 } } // namespace v8::internal |
3446 | 3446 |
3447 #endif // V8_TARGET_ARCH_ARM | 3447 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |