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

Side by Side Diff: src/x64/full-codegen-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 context()->Plug(rax); 1710 context()->Plug(rax);
1711 } 1711 }
1712 1712
1713 1713
1714 void FullCodeGenerator::EmitCallWithIC(Call* expr, 1714 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1715 Handle<Object> name, 1715 Handle<Object> name,
1716 RelocInfo::Mode mode) { 1716 RelocInfo::Mode mode) {
1717 // Code common for calls using the IC. 1717 // Code common for calls using the IC.
1718 ZoneList<Expression*>* args = expr->arguments(); 1718 ZoneList<Expression*>* args = expr->arguments();
1719 int arg_count = args->length(); 1719 int arg_count = args->length();
1720 for (int i = 0; i < arg_count; i++) { 1720 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1721 VisitForStackValue(args->at(i)); 1721 for (int i = 0; i < arg_count; i++) {
1722 VisitForStackValue(args->at(i));
1723 }
1724 __ Move(rcx, name);
1722 } 1725 }
1723 __ Move(rcx, name);
1724 // Record source position for debugger. 1726 // Record source position for debugger.
1725 SetSourcePosition(expr->position()); 1727 SetSourcePosition(expr->position(), FORCED_POSITION);
1726 // Call the IC initialization code. 1728 // Call the IC initialization code.
1727 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1729 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1728 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1730 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1729 in_loop); 1731 in_loop);
1730 EmitCallIC(ic, mode); 1732 EmitCallIC(ic, mode);
1731 // Restore context register. 1733 // Restore context register.
1732 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1734 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1733 context()->Plug(rax); 1735 context()->Plug(rax);
1734 } 1736 }
1735 1737
1736 1738
1737 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 1739 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
1738 Expression* key, 1740 Expression* key,
1739 RelocInfo::Mode mode) { 1741 RelocInfo::Mode mode) {
1740 // Code common for calls using the IC. 1742 // Code common for calls using the IC.
1741 ZoneList<Expression*>* args = expr->arguments(); 1743 ZoneList<Expression*>* args = expr->arguments();
1742 int arg_count = args->length(); 1744 int arg_count = args->length();
1743 for (int i = 0; i < arg_count; i++) { 1745 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1744 VisitForStackValue(args->at(i)); 1746 for (int i = 0; i < arg_count; i++) {
1747 VisitForStackValue(args->at(i));
1748 }
1749 VisitForAccumulatorValue(key);
1750 __ movq(rcx, rax);
1745 } 1751 }
1746 VisitForAccumulatorValue(key);
1747 __ movq(rcx, rax);
1748 // Record source position for debugger. 1752 // Record source position for debugger.
1749 SetSourcePosition(expr->position()); 1753 SetSourcePosition(expr->position(), FORCED_POSITION);
1750 // Call the IC initialization code. 1754 // Call the IC initialization code.
1751 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1755 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1752 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, 1756 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
1753 in_loop); 1757 in_loop);
1754 EmitCallIC(ic, mode); 1758 EmitCallIC(ic, mode);
1755 // Restore context register. 1759 // Restore context register.
1756 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1760 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1757 context()->Plug(rax); 1761 context()->Plug(rax);
1758 } 1762 }
1759 1763
1760 1764
1761 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 1765 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1762 // Code common for calls using the call stub. 1766 // Code common for calls using the call stub.
1763 ZoneList<Expression*>* args = expr->arguments(); 1767 ZoneList<Expression*>* args = expr->arguments();
1764 int arg_count = args->length(); 1768 int arg_count = args->length();
1765 for (int i = 0; i < arg_count; i++) { 1769 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1766 VisitForStackValue(args->at(i)); 1770 for (int i = 0; i < arg_count; i++) {
1771 VisitForStackValue(args->at(i));
1772 }
1767 } 1773 }
1768 // Record source position for debugger. 1774 // Record source position for debugger.
1769 SetSourcePosition(expr->position()); 1775 SetSourcePosition(expr->position(), FORCED_POSITION);
1770 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1776 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1771 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 1777 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1772 __ CallStub(&stub); 1778 __ CallStub(&stub);
1773 // Restore context register. 1779 // Restore context register.
1774 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1780 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1775 // Discard the function left on TOS. 1781 // Discard the function left on TOS.
1776 context()->DropAndPlug(1, rax); 1782 context()->DropAndPlug(1, rax);
1777 } 1783 }
1778 1784
1779 1785
1780 void FullCodeGenerator::VisitCall(Call* expr) { 1786 void FullCodeGenerator::VisitCall(Call* expr) {
1781 Comment cmnt(masm_, "[ Call"); 1787 Comment cmnt(masm_, "[ Call");
1782 Expression* fun = expr->expression(); 1788 Expression* fun = expr->expression();
1783 Variable* var = fun->AsVariableProxy()->AsVariable(); 1789 Variable* var = fun->AsVariableProxy()->AsVariable();
1784 1790
1785 if (var != NULL && var->is_possibly_eval()) { 1791 if (var != NULL && var->is_possibly_eval()) {
1786 // In a call to eval, we first call %ResolvePossiblyDirectEval to 1792 // In a call to eval, we first call %ResolvePossiblyDirectEval to
1787 // resolve the function we need to call and the receiver of the 1793 // resolve the function we need to call and the receiver of the
1788 // call. The we call the resolved function using the given 1794 // call. The we call the resolved function using the given
1789 // arguments. 1795 // arguments.
1790 VisitForStackValue(fun);
1791 __ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot.
1792
1793 // Push the arguments.
1794 ZoneList<Expression*>* args = expr->arguments(); 1796 ZoneList<Expression*>* args = expr->arguments();
1795 int arg_count = args->length(); 1797 int arg_count = args->length();
1796 for (int i = 0; i < arg_count; i++) { 1798 { PreserveStatementPositionScope pos_scope(masm()->positions_recorder());
1797 VisitForStackValue(args->at(i)); 1799
1800 VisitForStackValue(fun);
1801 __ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot.
1802
1803 // Push the arguments.
1804 for (int i = 0; i < arg_count; i++) {
1805 VisitForStackValue(args->at(i));
1806 }
1807
1808 // Push copy of the function - found below the arguments.
1809 __ push(Operand(rsp, (arg_count + 1) * kPointerSize));
1810
1811 // Push copy of the first argument or undefined if it doesn't exist.
1812 if (arg_count > 0) {
1813 __ push(Operand(rsp, arg_count * kPointerSize));
1814 } else {
1815 __ PushRoot(Heap::kUndefinedValueRootIndex);
1816 }
1817
1818 // Push the receiver of the enclosing function and do runtime call.
1819 __ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize));
1820 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
1821
1822 // The runtime call returns a pair of values in rax (function) and
1823 // rdx (receiver). Touch up the stack with the right values.
1824 __ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx);
1825 __ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
1798 } 1826 }
1799
1800 // Push copy of the function - found below the arguments.
1801 __ push(Operand(rsp, (arg_count + 1) * kPointerSize));
1802
1803 // Push copy of the first argument or undefined if it doesn't exist.
1804 if (arg_count > 0) {
1805 __ push(Operand(rsp, arg_count * kPointerSize));
1806 } else {
1807 __ PushRoot(Heap::kUndefinedValueRootIndex);
1808 }
1809
1810 // Push the receiver of the enclosing function and do runtime call.
1811 __ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize));
1812 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
1813
1814 // The runtime call returns a pair of values in rax (function) and
1815 // rdx (receiver). Touch up the stack with the right values.
1816 __ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx);
1817 __ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
1818
1819 // Record source position for debugger. 1827 // Record source position for debugger.
1820 SetSourcePosition(expr->position()); 1828 SetSourcePosition(expr->position(), FORCED_POSITION);
1821 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1829 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1822 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 1830 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1823 __ CallStub(&stub); 1831 __ CallStub(&stub);
1824 // Restore context register. 1832 // Restore context register.
1825 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1833 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1826 context()->DropAndPlug(1, rax); 1834 context()->DropAndPlug(1, rax);
1827 } else if (var != NULL && !var->is_this() && var->is_global()) { 1835 } else if (var != NULL && !var->is_this() && var->is_global()) {
1828 // Call to a global variable. 1836 // Call to a global variable.
1829 // Push global object as receiver for the call IC lookup. 1837 // Push global object as receiver for the call IC lookup.
1830 __ push(CodeGenerator::GlobalObject()); 1838 __ push(CodeGenerator::GlobalObject());
1831 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 1839 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
1832 } else if (var != NULL && var->AsSlot() != NULL && 1840 } else if (var != NULL && var->AsSlot() != NULL &&
1833 var->AsSlot()->type() == Slot::LOOKUP) { 1841 var->AsSlot()->type() == Slot::LOOKUP) {
1834 // Call to a lookup slot (dynamically introduced variable). 1842 // Call to a lookup slot (dynamically introduced variable).
1835 Label slow, done; 1843 Label slow, done;
1836 1844
1837 // Generate code for loading from variables potentially shadowed 1845 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1838 // by eval-introduced variables. 1846 // Generate code for loading from variables potentially shadowed
1839 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 1847 // by eval-introduced variables.
1840 NOT_INSIDE_TYPEOF, 1848 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
1841 &slow, 1849 NOT_INSIDE_TYPEOF,
1842 &done); 1850 &slow,
1851 &done);
1843 1852
1844 __ bind(&slow); 1853 __ bind(&slow);
1845 // Call the runtime to find the function to call (returned in rax) 1854 // Call the runtime to find the function to call (returned in rax)
1846 // and the object holding it (returned in rdx). 1855 // and the object holding it (returned in rdx).
1847 __ push(context_register()); 1856 __ push(context_register());
1848 __ Push(var->name()); 1857 __ Push(var->name());
1849 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1858 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1850 __ push(rax); // Function. 1859 __ push(rax); // Function.
1851 __ push(rdx); // Receiver. 1860 __ push(rdx); // Receiver.
1852 1861
1853 // If fast case code has been generated, emit code to push the 1862 // If fast case code has been generated, emit code to push the
1854 // function and receiver and have the slow path jump around this 1863 // function and receiver and have the slow path jump around this
1855 // code. 1864 // code.
1856 if (done.is_linked()) { 1865 if (done.is_linked()) {
1857 NearLabel call; 1866 NearLabel call;
1858 __ jmp(&call); 1867 __ jmp(&call);
1859 __ bind(&done); 1868 __ bind(&done);
1860 // Push function. 1869 // Push function.
1861 __ push(rax); 1870 __ push(rax);
1862 // Push global receiver. 1871 // Push global receiver.
1863 __ movq(rbx, CodeGenerator::GlobalObject()); 1872 __ movq(rbx, CodeGenerator::GlobalObject());
1864 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); 1873 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
1865 __ bind(&call); 1874 __ bind(&call);
1875 }
1866 } 1876 }
1867 1877
1868 EmitCallWithStub(expr); 1878 EmitCallWithStub(expr);
1869 1879
1870 } else if (fun->AsProperty() != NULL) { 1880 } else if (fun->AsProperty() != NULL) {
1871 // Call to an object property. 1881 // Call to an object property.
1872 Property* prop = fun->AsProperty(); 1882 Property* prop = fun->AsProperty();
1873 Literal* key = prop->key()->AsLiteral(); 1883 Literal* key = prop->key()->AsLiteral();
1874 if (key != NULL && key->handle()->IsSymbol()) { 1884 if (key != NULL && key->handle()->IsSymbol()) {
1875 // Call to a named property, use call IC. 1885 // Call to a named property, use call IC.
1876 VisitForStackValue(prop->obj()); 1886 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1887 VisitForStackValue(prop->obj());
1888 }
1877 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 1889 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
1878 } else { 1890 } else {
1879 // Call to a keyed property. 1891 // Call to a keyed property.
1880 // For a synthetic property use keyed load IC followed by function call, 1892 // For a synthetic property use keyed load IC followed by function call,
1881 // for a regular property use KeyedCallIC. 1893 // for a regular property use KeyedCallIC.
1882 VisitForStackValue(prop->obj()); 1894 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1895 VisitForStackValue(prop->obj());
1896 }
1883 if (prop->is_synthetic()) { 1897 if (prop->is_synthetic()) {
1884 VisitForAccumulatorValue(prop->key()); 1898 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1885 __ movq(rdx, Operand(rsp, 0)); 1899 VisitForAccumulatorValue(prop->key());
1900 __ movq(rdx, Operand(rsp, 0));
1901 }
1886 // Record source code position for IC call. 1902 // Record source code position for IC call.
1887 SetSourcePosition(prop->position()); 1903 SetSourcePosition(prop->position(), FORCED_POSITION);
1888 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1904 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1889 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1905 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1890 // Pop receiver. 1906 // Pop receiver.
1891 __ pop(rbx); 1907 __ pop(rbx);
1892 // Push result (function). 1908 // Push result (function).
1893 __ push(rax); 1909 __ push(rax);
1894 // Push receiver object on stack. 1910 // Push receiver object on stack.
1895 __ movq(rcx, CodeGenerator::GlobalObject()); 1911 __ movq(rcx, CodeGenerator::GlobalObject());
1896 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 1912 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
1897 EmitCallWithStub(expr); 1913 EmitCallWithStub(expr);
1898 } else { 1914 } else {
1899 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 1915 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
1900 } 1916 }
1901 } 1917 }
1902 } else { 1918 } else {
1903 // Call to some other expression. If the expression is an anonymous 1919 // Call to some other expression. If the expression is an anonymous
1904 // function literal not called in a loop, mark it as one that should 1920 // function literal not called in a loop, mark it as one that should
1905 // also use the fast code generator. 1921 // also use the fast code generator.
1906 FunctionLiteral* lit = fun->AsFunctionLiteral(); 1922 FunctionLiteral* lit = fun->AsFunctionLiteral();
1907 if (lit != NULL && 1923 if (lit != NULL &&
1908 lit->name()->Equals(Heap::empty_string()) && 1924 lit->name()->Equals(Heap::empty_string()) &&
1909 loop_depth() == 0) { 1925 loop_depth() == 0) {
1910 lit->set_try_full_codegen(true); 1926 lit->set_try_full_codegen(true);
1911 } 1927 }
1912 VisitForStackValue(fun); 1928 { PreserveStatementPositionScope scope(masm()->positions_recorder());
1929 VisitForStackValue(fun);
1930 }
1913 // Load global receiver object. 1931 // Load global receiver object.
1914 __ movq(rbx, CodeGenerator::GlobalObject()); 1932 __ movq(rbx, CodeGenerator::GlobalObject());
1915 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); 1933 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
1916 // Emit function call. 1934 // Emit function call.
1917 EmitCallWithStub(expr); 1935 EmitCallWithStub(expr);
1918 } 1936 }
1919 } 1937 }
1920 1938
1921 1939
1922 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 1940 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after
3436 __ ret(0); 3454 __ ret(0);
3437 } 3455 }
3438 3456
3439 3457
3440 #undef __ 3458 #undef __
3441 3459
3442 3460
3443 } } // namespace v8::internal 3461 } } // namespace v8::internal
3444 3462
3445 #endif // V8_TARGET_ARCH_X64 3463 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698