| OLD | NEW |
| 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 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1719 SetSourcePosition(expr->position()); | 1719 SetSourcePosition(expr->position()); |
| 1720 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1720 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1721 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); | 1721 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); |
| 1722 __ call(ic, mode); | 1722 __ call(ic, mode); |
| 1723 // Restore context register. | 1723 // Restore context register. |
| 1724 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 1724 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 1725 Apply(context_, eax); | 1725 Apply(context_, eax); |
| 1726 } | 1726 } |
| 1727 | 1727 |
| 1728 | 1728 |
| 1729 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 1730 Expression* key, |
| 1731 RelocInfo::Mode mode) { |
| 1732 // Code common for calls using the IC. |
| 1733 ZoneList<Expression*>* args = expr->arguments(); |
| 1734 int arg_count = args->length(); |
| 1735 for (int i = 0; i < arg_count; i++) { |
| 1736 VisitForValue(args->at(i), kStack); |
| 1737 } |
| 1738 VisitForValue(key, kAccumulator); |
| 1739 __ mov(ecx, eax); |
| 1740 // Record source position of the IC call. |
| 1741 SetSourcePosition(expr->position()); |
| 1742 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1743 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize( |
| 1744 arg_count, in_loop); |
| 1745 __ call(ic, mode); |
| 1746 // Restore context register. |
| 1747 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 1748 Apply(context_, eax); |
| 1749 } |
| 1750 |
| 1751 |
| 1729 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1752 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
| 1730 // Code common for calls using the call stub. | 1753 // Code common for calls using the call stub. |
| 1731 ZoneList<Expression*>* args = expr->arguments(); | 1754 ZoneList<Expression*>* args = expr->arguments(); |
| 1732 int arg_count = args->length(); | 1755 int arg_count = args->length(); |
| 1733 for (int i = 0; i < arg_count; i++) { | 1756 for (int i = 0; i < arg_count; i++) { |
| 1734 VisitForValue(args->at(i), kStack); | 1757 VisitForValue(args->at(i), kStack); |
| 1735 } | 1758 } |
| 1736 // Record source position for debugger. | 1759 // Record source position for debugger. |
| 1737 SetSourcePosition(expr->position()); | 1760 SetSourcePosition(expr->position()); |
| 1738 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1761 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1808 EmitCallWithStub(expr); | 1831 EmitCallWithStub(expr); |
| 1809 } else if (fun->AsProperty() != NULL) { | 1832 } else if (fun->AsProperty() != NULL) { |
| 1810 // Call to an object property. | 1833 // Call to an object property. |
| 1811 Property* prop = fun->AsProperty(); | 1834 Property* prop = fun->AsProperty(); |
| 1812 Literal* key = prop->key()->AsLiteral(); | 1835 Literal* key = prop->key()->AsLiteral(); |
| 1813 if (key != NULL && key->handle()->IsSymbol()) { | 1836 if (key != NULL && key->handle()->IsSymbol()) { |
| 1814 // Call to a named property, use call IC. | 1837 // Call to a named property, use call IC. |
| 1815 VisitForValue(prop->obj(), kStack); | 1838 VisitForValue(prop->obj(), kStack); |
| 1816 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 1839 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
| 1817 } else { | 1840 } else { |
| 1818 // Call to a keyed property, use keyed load IC followed by function | 1841 // Call to a keyed property. |
| 1819 // call. | 1842 // For a synthetic property use keyed load IC followed by function call, |
| 1843 // for a regular property use keyed CallIC. |
| 1820 VisitForValue(prop->obj(), kStack); | 1844 VisitForValue(prop->obj(), kStack); |
| 1821 VisitForValue(prop->key(), kAccumulator); | |
| 1822 // Record source code position for IC call. | |
| 1823 SetSourcePosition(prop->position()); | |
| 1824 if (prop->is_synthetic()) { | 1845 if (prop->is_synthetic()) { |
| 1846 VisitForValue(prop->key(), kAccumulator); |
| 1847 // Record source code position for IC call. |
| 1848 SetSourcePosition(prop->position()); |
| 1825 __ pop(edx); // We do not need to keep the receiver. | 1849 __ pop(edx); // We do not need to keep the receiver. |
| 1826 } else { | |
| 1827 __ mov(edx, Operand(esp, 0)); // Keep receiver, to call function on. | |
| 1828 } | |
| 1829 | 1850 |
| 1830 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1851 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 1831 __ call(ic, RelocInfo::CODE_TARGET); | 1852 __ call(ic, RelocInfo::CODE_TARGET); |
| 1832 // By emitting a nop we make sure that we do not have a "test eax,..." | 1853 // By emitting a nop we make sure that we do not have a "test eax,..." |
| 1833 // instruction after the call it is treated specially by the LoadIC code. | 1854 // instruction after the call as it is treated specially |
| 1834 __ nop(); | 1855 // by the LoadIC code. |
| 1835 if (prop->is_synthetic()) { | 1856 __ nop(); |
| 1836 // Push result (function). | 1857 // Push result (function). |
| 1837 __ push(eax); | 1858 __ push(eax); |
| 1838 // Push Global receiver. | 1859 // Push Global receiver. |
| 1839 __ mov(ecx, CodeGenerator::GlobalObject()); | 1860 __ mov(ecx, CodeGenerator::GlobalObject()); |
| 1840 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); | 1861 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); |
| 1862 EmitCallWithStub(expr); |
| 1841 } else { | 1863 } else { |
| 1842 // Pop receiver. | 1864 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
| 1843 __ pop(ebx); | |
| 1844 // Push result (function). | |
| 1845 __ push(eax); | |
| 1846 __ push(ebx); | |
| 1847 } | 1865 } |
| 1848 EmitCallWithStub(expr); | |
| 1849 } | 1866 } |
| 1850 } else { | 1867 } else { |
| 1851 // Call to some other expression. If the expression is an anonymous | 1868 // Call to some other expression. If the expression is an anonymous |
| 1852 // function literal not called in a loop, mark it as one that should | 1869 // function literal not called in a loop, mark it as one that should |
| 1853 // also use the full code generator. | 1870 // also use the full code generator. |
| 1854 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1871 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
| 1855 if (lit != NULL && | 1872 if (lit != NULL && |
| 1856 lit->name()->Equals(Heap::empty_string()) && | 1873 lit->name()->Equals(Heap::empty_string()) && |
| 1857 loop_depth() == 0) { | 1874 loop_depth() == 0) { |
| 1858 lit->set_try_full_codegen(true); | 1875 lit->set_try_full_codegen(true); |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3234 // And return. | 3251 // And return. |
| 3235 __ ret(0); | 3252 __ ret(0); |
| 3236 } | 3253 } |
| 3237 | 3254 |
| 3238 | 3255 |
| 3239 #undef __ | 3256 #undef __ |
| 3240 | 3257 |
| 3241 } } // namespace v8::internal | 3258 } } // namespace v8::internal |
| 3242 | 3259 |
| 3243 #endif // V8_TARGET_ARCH_IA32 | 3260 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |