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 |