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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 4469002: Improve positions recording for calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 10 years, 1 month 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
OLDNEW
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 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 } 1681 }
1682 context()->Plug(r0); 1682 context()->Plug(r0);
1683 } 1683 }
1684 1684
1685 void FullCodeGenerator::EmitCallWithIC(Call* expr, 1685 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1686 Handle<Object> name, 1686 Handle<Object> name,
1687 RelocInfo::Mode mode) { 1687 RelocInfo::Mode mode) {
1688 // Code common for calls using the IC. 1688 // Code common for calls using the IC.
1689 ZoneList<Expression*>* args = expr->arguments(); 1689 ZoneList<Expression*>* args = expr->arguments();
1690 int arg_count = args->length(); 1690 int arg_count = args->length();
1691 for (int i = 0; i < arg_count; i++) { 1691 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1692 VisitForStackValue(args->at(i)); 1692 for (int i = 0; i < arg_count; i++) {
1693 VisitForStackValue(args->at(i));
1694 }
1695 __ mov(r2, Operand(name));
1693 } 1696 }
1694 __ mov(r2, Operand(name));
1695 // Record source position for debugger. 1697 // Record source position for debugger.
1696 SetSourcePosition(expr->position()); 1698 SetSourcePosition(expr->position(), FORCED_POSITION);
1697 // Call the IC initialization code. 1699 // Call the IC initialization code.
1698 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1700 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1699 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 1701 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1700 EmitCallIC(ic, mode); 1702 EmitCallIC(ic, mode);
1701 // Restore context register. 1703 // Restore context register.
1702 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1704 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1703 context()->Plug(r0); 1705 context()->Plug(r0);
1704 } 1706 }
1705 1707
1706 1708
1707 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 1709 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
1708 Expression* key, 1710 Expression* key,
1709 RelocInfo::Mode mode) { 1711 RelocInfo::Mode mode) {
1710 // Code common for calls using the IC. 1712 // Code common for calls using the IC.
1711 ZoneList<Expression*>* args = expr->arguments(); 1713 ZoneList<Expression*>* args = expr->arguments();
1712 int arg_count = args->length(); 1714 int arg_count = args->length();
1713 for (int i = 0; i < arg_count; i++) { 1715 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1714 VisitForStackValue(args->at(i)); 1716 for (int i = 0; i < arg_count; i++) {
1717 VisitForStackValue(args->at(i));
1718 }
1719 VisitForAccumulatorValue(key);
1720 __ mov(r2, r0);
1715 } 1721 }
1716 VisitForAccumulatorValue(key);
1717 __ mov(r2, r0);
1718 // Record source position for debugger. 1722 // Record source position for debugger.
1719 SetSourcePosition(expr->position()); 1723 SetSourcePosition(expr->position(), FORCED_POSITION);
1720 // Call the IC initialization code. 1724 // Call the IC initialization code.
1721 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1725 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1722 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, 1726 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
1723 in_loop); 1727 in_loop);
1724 EmitCallIC(ic, mode); 1728 EmitCallIC(ic, mode);
1725 // Restore context register. 1729 // Restore context register.
1726 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1730 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1727 context()->Plug(r0); 1731 context()->Plug(r0);
1728 } 1732 }
1729 1733
1730 1734
1731 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 1735 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1732 // Code common for calls using the call stub. 1736 // Code common for calls using the call stub.
1733 ZoneList<Expression*>* args = expr->arguments(); 1737 ZoneList<Expression*>* args = expr->arguments();
1734 int arg_count = args->length(); 1738 int arg_count = args->length();
1735 for (int i = 0; i < arg_count; i++) { 1739 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1736 VisitForStackValue(args->at(i)); 1740 for (int i = 0; i < arg_count; i++) {
1741 VisitForStackValue(args->at(i));
1742 }
1737 } 1743 }
1738 // Record source position for debugger. 1744 // Record source position for debugger.
1739 SetSourcePosition(expr->position()); 1745 SetSourcePosition(expr->position(), FORCED_POSITION);
1740 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1746 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1741 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 1747 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1742 __ CallStub(&stub); 1748 __ CallStub(&stub);
1743 // Restore context register. 1749 // Restore context register.
1744 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1750 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1745 context()->DropAndPlug(1, r0); 1751 context()->DropAndPlug(1, r0);
1746 } 1752 }
1747 1753
1748 1754
1749 void FullCodeGenerator::VisitCall(Call* expr) { 1755 void FullCodeGenerator::VisitCall(Call* expr) {
1750 Comment cmnt(masm_, "[ Call"); 1756 Comment cmnt(masm_, "[ Call");
1751 Expression* fun = expr->expression(); 1757 Expression* fun = expr->expression();
1752 Variable* var = fun->AsVariableProxy()->AsVariable(); 1758 Variable* var = fun->AsVariableProxy()->AsVariable();
1753 1759
1754 if (var != NULL && var->is_possibly_eval()) { 1760 if (var != NULL && var->is_possibly_eval()) {
1755 // In a call to eval, we first call %ResolvePossiblyDirectEval to 1761 // In a call to eval, we first call %ResolvePossiblyDirectEval to
1756 // resolve the function we need to call and the receiver of the 1762 // resolve the function we need to call and the receiver of the
1757 // call. Then we call the resolved function using the given 1763 // call. Then we call the resolved function using the given
1758 // arguments. 1764 // arguments.
1759 VisitForStackValue(fun);
1760 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1761 __ push(r2); // Reserved receiver slot.
1762
1763 // Push the arguments.
1764 ZoneList<Expression*>* args = expr->arguments(); 1765 ZoneList<Expression*>* args = expr->arguments();
1765 int arg_count = args->length(); 1766 int arg_count = args->length();
1766 for (int i = 0; i < arg_count; i++) { 1767
1767 VisitForStackValue(args->at(i)); 1768 { PreserveStatementPositionScope pos_scope(masm()->positions_recorder());
1769
1770 VisitForStackValue(fun);
1771 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1772 __ push(r2); // Reserved receiver slot.
1773
1774 // Push the arguments.
1775 for (int i = 0; i < arg_count; i++) {
1776 VisitForStackValue(args->at(i));
1777 }
1778
1779 // Push copy of the function - found below the arguments.
1780 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
1781 __ push(r1);
1782
1783 // Push copy of the first argument or undefined if it doesn't exist.
1784 if (arg_count > 0) {
1785 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
1786 __ push(r1);
1787 } else {
1788 __ push(r2);
1789 }
1790
1791 // Push the receiver of the enclosing function and do runtime call.
1792 __ ldr(r1,
1793 MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
1794 __ push(r1);
1795 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
1796
1797 // The runtime call returns a pair of values in r0 (function) and
1798 // r1 (receiver). Touch up the stack with the right values.
1799 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
1800 __ str(r1, MemOperand(sp, arg_count * kPointerSize));
1768 } 1801 }
1769 1802
1770 // Push copy of the function - found below the arguments.
1771 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
1772 __ push(r1);
1773
1774 // Push copy of the first argument or undefined if it doesn't exist.
1775 if (arg_count > 0) {
1776 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
1777 __ push(r1);
1778 } else {
1779 __ push(r2);
1780 }
1781
1782 // Push the receiver of the enclosing function and do runtime call.
1783 __ ldr(r1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
1784 __ push(r1);
1785 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
1786
1787 // The runtime call returns a pair of values in r0 (function) and
1788 // r1 (receiver). Touch up the stack with the right values.
1789 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
1790 __ str(r1, MemOperand(sp, arg_count * kPointerSize));
1791
1792 // Record source position for debugger. 1803 // Record source position for debugger.
1793 SetSourcePosition(expr->position()); 1804 SetSourcePosition(expr->position(), FORCED_POSITION);
1794 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1805 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1795 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 1806 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1796 __ CallStub(&stub); 1807 __ CallStub(&stub);
1797 // Restore context register. 1808 // Restore context register.
1798 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1809 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1799 context()->DropAndPlug(1, r0); 1810 context()->DropAndPlug(1, r0);
1800 } else if (var != NULL && !var->is_this() && var->is_global()) { 1811 } else if (var != NULL && !var->is_this() && var->is_global()) {
1801 // Push global object as receiver for the call IC. 1812 // Push global object as receiver for the call IC.
1802 __ ldr(r0, CodeGenerator::GlobalObject()); 1813 __ ldr(r0, CodeGenerator::GlobalObject());
1803 __ push(r0); 1814 __ push(r0);
1804 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 1815 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
1805 } else if (var != NULL && var->AsSlot() != NULL && 1816 } else if (var != NULL && var->AsSlot() != NULL &&
1806 var->AsSlot()->type() == Slot::LOOKUP) { 1817 var->AsSlot()->type() == Slot::LOOKUP) {
1807 // Call to a lookup slot (dynamically introduced variable). 1818 // Call to a lookup slot (dynamically introduced variable).
1808 Label slow, done; 1819 Label slow, done;
1809 1820
1810 // Generate code for loading from variables potentially shadowed 1821 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1811 // by eval-introduced variables. 1822 // Generate code for loading from variables potentially shadowed
1812 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 1823 // by eval-introduced variables.
1813 NOT_INSIDE_TYPEOF, 1824 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
1814 &slow, 1825 NOT_INSIDE_TYPEOF,
1815 &done); 1826 &slow,
1827 &done);
1828 }
1816 1829
1817 __ bind(&slow); 1830 __ bind(&slow);
1818 // Call the runtime to find the function to call (returned in r0) 1831 // Call the runtime to find the function to call (returned in r0)
1819 // and the object holding it (returned in edx). 1832 // and the object holding it (returned in edx).
1820 __ push(context_register()); 1833 __ push(context_register());
1821 __ mov(r2, Operand(var->name())); 1834 __ mov(r2, Operand(var->name()));
1822 __ push(r2); 1835 __ push(r2);
1823 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1836 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1824 __ Push(r0, r1); // Function, receiver. 1837 __ Push(r0, r1); // Function, receiver.
1825 1838
(...skipping 13 matching lines...) Expand all
1839 __ bind(&call); 1852 __ bind(&call);
1840 } 1853 }
1841 1854
1842 EmitCallWithStub(expr); 1855 EmitCallWithStub(expr);
1843 } else if (fun->AsProperty() != NULL) { 1856 } else if (fun->AsProperty() != NULL) {
1844 // Call to an object property. 1857 // Call to an object property.
1845 Property* prop = fun->AsProperty(); 1858 Property* prop = fun->AsProperty();
1846 Literal* key = prop->key()->AsLiteral(); 1859 Literal* key = prop->key()->AsLiteral();
1847 if (key != NULL && key->handle()->IsSymbol()) { 1860 if (key != NULL && key->handle()->IsSymbol()) {
1848 // Call to a named property, use call IC. 1861 // Call to a named property, use call IC.
1849 VisitForStackValue(prop->obj()); 1862 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1863 VisitForStackValue(prop->obj());
1864 }
1850 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 1865 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
1851 } else { 1866 } else {
1852 // Call to a keyed property. 1867 // Call to a keyed property.
1853 // For a synthetic property use keyed load IC followed by function call, 1868 // For a synthetic property use keyed load IC followed by function call,
1854 // for a regular property use keyed CallIC. 1869 // for a regular property use keyed CallIC.
1855 VisitForStackValue(prop->obj()); 1870 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1871 VisitForStackValue(prop->obj());
1872 }
1856 if (prop->is_synthetic()) { 1873 if (prop->is_synthetic()) {
1857 VisitForAccumulatorValue(prop->key()); 1874 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1875 VisitForAccumulatorValue(prop->key());
1876 }
1858 // Record source code position for IC call. 1877 // Record source code position for IC call.
1859 SetSourcePosition(prop->position()); 1878 SetSourcePosition(prop->position(), FORCED_POSITION);
1860 __ pop(r1); // We do not need to keep the receiver. 1879 __ pop(r1); // We do not need to keep the receiver.
1861 1880
1862 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1881 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1863 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1882 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1864 __ ldr(r1, CodeGenerator::GlobalObject()); 1883 __ ldr(r1, CodeGenerator::GlobalObject());
1865 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 1884 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
1866 __ Push(r0, r1); // Function, receiver. 1885 __ Push(r0, r1); // Function, receiver.
1867 EmitCallWithStub(expr); 1886 EmitCallWithStub(expr);
1868 } else { 1887 } else {
1869 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 1888 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
1870 } 1889 }
1871 } 1890 }
1872 } else { 1891 } else {
1873 // Call to some other expression. If the expression is an anonymous 1892 // Call to some other expression. If the expression is an anonymous
1874 // function literal not called in a loop, mark it as one that should 1893 // function literal not called in a loop, mark it as one that should
1875 // also use the fast code generator. 1894 // also use the fast code generator.
1876 FunctionLiteral* lit = fun->AsFunctionLiteral(); 1895 FunctionLiteral* lit = fun->AsFunctionLiteral();
1877 if (lit != NULL && 1896 if (lit != NULL &&
1878 lit->name()->Equals(Heap::empty_string()) && 1897 lit->name()->Equals(Heap::empty_string()) &&
1879 loop_depth() == 0) { 1898 loop_depth() == 0) {
1880 lit->set_try_full_codegen(true); 1899 lit->set_try_full_codegen(true);
1881 } 1900 }
1882 VisitForStackValue(fun); 1901
1902 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1903 VisitForStackValue(fun);
1904 }
1883 // Load global receiver object. 1905 // Load global receiver object.
1884 __ ldr(r1, CodeGenerator::GlobalObject()); 1906 __ ldr(r1, CodeGenerator::GlobalObject());
1885 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 1907 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
1886 __ push(r1); 1908 __ push(r1);
1887 // Emit function call. 1909 // Emit function call.
1888 EmitCallWithStub(expr); 1910 EmitCallWithStub(expr);
1889 } 1911 }
1890 } 1912 }
1891 1913
1892 1914
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after
3401 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3423 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3402 __ add(pc, r1, Operand(masm_->CodeObject())); 3424 __ add(pc, r1, Operand(masm_->CodeObject()));
3403 } 3425 }
3404 3426
3405 3427
3406 #undef __ 3428 #undef __
3407 3429
3408 } } // namespace v8::internal 3430 } } // namespace v8::internal
3409 3431
3410 #endif // V8_TARGET_ARCH_ARM 3432 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698