| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 // Possibly allocate a local context. | 222 // Possibly allocate a local context. |
| 223 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 223 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 224 if (heap_slots > 0) { | 224 if (heap_slots > 0) { |
| 225 Comment cmnt(masm_, "[ Allocate context"); | 225 Comment cmnt(masm_, "[ Allocate context"); |
| 226 // Argument to NewContext is the function, which is still in edi. | 226 // Argument to NewContext is the function, which is still in edi. |
| 227 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 227 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
| 228 __ push(edi); | 228 __ push(edi); |
| 229 __ Push(info->scope()->GetScopeInfo()); | 229 __ Push(info->scope()->GetScopeInfo()); |
| 230 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 230 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
| 231 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 231 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 232 FastNewContextStub stub(heap_slots); | 232 FastNewContextStub stub(isolate(), heap_slots); |
| 233 __ CallStub(&stub); | 233 __ CallStub(&stub); |
| 234 } else { | 234 } else { |
| 235 __ push(edi); | 235 __ push(edi); |
| 236 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 236 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
| 237 } | 237 } |
| 238 function_in_register = false; | 238 function_in_register = false; |
| 239 // Context is returned in eax. It replaces the context passed to us. | 239 // Context is returned in eax. It replaces the context passed to us. |
| 240 // It's saved in the stack and kept live in esi. | 240 // It's saved in the stack and kept live in esi. |
| 241 __ mov(esi, eax); | 241 __ mov(esi, eax); |
| 242 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); | 242 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // The stub will rewrite receiver and parameter count if the previous | 284 // The stub will rewrite receiver and parameter count if the previous |
| 285 // stack frame was an arguments adapter frame. | 285 // stack frame was an arguments adapter frame. |
| 286 ArgumentsAccessStub::Type type; | 286 ArgumentsAccessStub::Type type; |
| 287 if (strict_mode() == STRICT) { | 287 if (strict_mode() == STRICT) { |
| 288 type = ArgumentsAccessStub::NEW_STRICT; | 288 type = ArgumentsAccessStub::NEW_STRICT; |
| 289 } else if (function()->has_duplicate_parameters()) { | 289 } else if (function()->has_duplicate_parameters()) { |
| 290 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 290 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
| 291 } else { | 291 } else { |
| 292 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 292 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
| 293 } | 293 } |
| 294 ArgumentsAccessStub stub(type); | 294 ArgumentsAccessStub stub(isolate(), type); |
| 295 __ CallStub(&stub); | 295 __ CallStub(&stub); |
| 296 | 296 |
| 297 SetVar(arguments, eax, ebx, edx); | 297 SetVar(arguments, eax, ebx, edx); |
| 298 } | 298 } |
| 299 | 299 |
| 300 if (FLAG_trace) { | 300 if (FLAG_trace) { |
| 301 __ CallRuntime(Runtime::kTraceEnter, 0); | 301 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 302 } | 302 } |
| 303 | 303 |
| 304 // Visit the declarations and body unless there is an illegal | 304 // Visit the declarations and body unless there is an illegal |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 // space for nested functions that don't need literals cloning. If | 1293 // space for nested functions that don't need literals cloning. If |
| 1294 // we're running with the --always-opt or the --prepare-always-opt | 1294 // we're running with the --always-opt or the --prepare-always-opt |
| 1295 // flag, we need to use the runtime function so that the new function | 1295 // flag, we need to use the runtime function so that the new function |
| 1296 // we are creating here gets a chance to have its code optimized and | 1296 // we are creating here gets a chance to have its code optimized and |
| 1297 // doesn't just get a copy of the existing unoptimized code. | 1297 // doesn't just get a copy of the existing unoptimized code. |
| 1298 if (!FLAG_always_opt && | 1298 if (!FLAG_always_opt && |
| 1299 !FLAG_prepare_always_opt && | 1299 !FLAG_prepare_always_opt && |
| 1300 !pretenure && | 1300 !pretenure && |
| 1301 scope()->is_function_scope() && | 1301 scope()->is_function_scope() && |
| 1302 info->num_literals() == 0) { | 1302 info->num_literals() == 0) { |
| 1303 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1303 FastNewClosureStub stub(isolate(), |
| 1304 info->strict_mode(), |
| 1305 info->is_generator()); |
| 1304 __ mov(ebx, Immediate(info)); | 1306 __ mov(ebx, Immediate(info)); |
| 1305 __ CallStub(&stub); | 1307 __ CallStub(&stub); |
| 1306 } else { | 1308 } else { |
| 1307 __ push(esi); | 1309 __ push(esi); |
| 1308 __ push(Immediate(info)); | 1310 __ push(Immediate(info)); |
| 1309 __ push(Immediate(pretenure | 1311 __ push(Immediate(pretenure |
| 1310 ? isolate()->factory()->true_value() | 1312 ? isolate()->factory()->true_value() |
| 1311 : isolate()->factory()->false_value())); | 1313 : isolate()->factory()->false_value())); |
| 1312 __ CallRuntime(Runtime::kHiddenNewClosure, 3); | 1314 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
| 1313 } | 1315 } |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1629 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
| 1628 __ push(Immediate(constant_properties)); | 1630 __ push(Immediate(constant_properties)); |
| 1629 __ push(Immediate(Smi::FromInt(flags))); | 1631 __ push(Immediate(Smi::FromInt(flags))); |
| 1630 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); | 1632 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
| 1631 } else { | 1633 } else { |
| 1632 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1634 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1633 __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 1635 __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
| 1634 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1636 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
| 1635 __ mov(ecx, Immediate(constant_properties)); | 1637 __ mov(ecx, Immediate(constant_properties)); |
| 1636 __ mov(edx, Immediate(Smi::FromInt(flags))); | 1638 __ mov(edx, Immediate(Smi::FromInt(flags))); |
| 1637 FastCloneShallowObjectStub stub(properties_count); | 1639 FastCloneShallowObjectStub stub(isolate(), properties_count); |
| 1638 __ CallStub(&stub); | 1640 __ CallStub(&stub); |
| 1639 } | 1641 } |
| 1640 | 1642 |
| 1641 // If result_saved is true the result is on top of the stack. If | 1643 // If result_saved is true the result is on top of the stack. If |
| 1642 // result_saved is false the result is in eax. | 1644 // result_saved is false the result is in eax. |
| 1643 bool result_saved = false; | 1645 bool result_saved = false; |
| 1644 | 1646 |
| 1645 // Mark all computed expressions that are bound to a key that | 1647 // Mark all computed expressions that are bound to a key that |
| 1646 // is shadowed by a later occurrence of the same key. For the | 1648 // is shadowed by a later occurrence of the same key. For the |
| 1647 // marked expressions, no store code is emitted. | 1649 // marked expressions, no store code is emitted. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 if (has_constant_fast_elements && | 1764 if (has_constant_fast_elements && |
| 1763 constant_elements_values->map() == heap->fixed_cow_array_map()) { | 1765 constant_elements_values->map() == heap->fixed_cow_array_map()) { |
| 1764 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot | 1766 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot |
| 1765 // change, so it's possible to specialize the stub in advance. | 1767 // change, so it's possible to specialize the stub in advance. |
| 1766 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); | 1768 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); |
| 1767 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1769 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1768 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1770 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
| 1769 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1771 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
| 1770 __ mov(ecx, Immediate(constant_elements)); | 1772 __ mov(ecx, Immediate(constant_elements)); |
| 1771 FastCloneShallowArrayStub stub( | 1773 FastCloneShallowArrayStub stub( |
| 1774 isolate(), |
| 1772 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1775 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1773 allocation_site_mode, | 1776 allocation_site_mode, |
| 1774 length); | 1777 length); |
| 1775 __ CallStub(&stub); | 1778 __ CallStub(&stub); |
| 1776 } else if (expr->depth() > 1 || Serializer::enabled() || | 1779 } else if (expr->depth() > 1 || Serializer::enabled() || |
| 1777 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1780 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1778 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1781 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1779 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1782 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
| 1780 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1783 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
| 1781 __ push(Immediate(constant_elements)); | 1784 __ push(Immediate(constant_elements)); |
| 1782 __ push(Immediate(Smi::FromInt(flags))); | 1785 __ push(Immediate(Smi::FromInt(flags))); |
| 1783 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); | 1786 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
| 1784 } else { | 1787 } else { |
| 1785 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1788 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1786 FLAG_smi_only_arrays); | 1789 FLAG_smi_only_arrays); |
| 1787 FastCloneShallowArrayStub::Mode mode = | 1790 FastCloneShallowArrayStub::Mode mode = |
| 1788 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1791 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
| 1789 | 1792 |
| 1790 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot | 1793 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot |
| 1791 // change, so it's possible to specialize the stub in advance. | 1794 // change, so it's possible to specialize the stub in advance. |
| 1792 if (has_constant_fast_elements) { | 1795 if (has_constant_fast_elements) { |
| 1793 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1796 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
| 1794 } | 1797 } |
| 1795 | 1798 |
| 1796 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1799 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1797 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1800 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
| 1798 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1801 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
| 1799 __ mov(ecx, Immediate(constant_elements)); | 1802 __ mov(ecx, Immediate(constant_elements)); |
| 1800 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 1803 FastCloneShallowArrayStub stub(isolate(), |
| 1804 mode, |
| 1805 allocation_site_mode, |
| 1806 length); |
| 1801 __ CallStub(&stub); | 1807 __ CallStub(&stub); |
| 1802 } | 1808 } |
| 1803 | 1809 |
| 1804 bool result_saved = false; // Is the result saved to the stack? | 1810 bool result_saved = false; // Is the result saved to the stack? |
| 1805 | 1811 |
| 1806 // Emit code to evaluate all the non-constant subexpressions and to store | 1812 // Emit code to evaluate all the non-constant subexpressions and to store |
| 1807 // them into the newly cloned array. | 1813 // them into the newly cloned array. |
| 1808 for (int i = 0; i < length; i++) { | 1814 for (int i = 0; i < length; i++) { |
| 1809 Expression* subexpr = subexprs->at(i); | 1815 Expression* subexpr = subexprs->at(i); |
| 1810 // If the subexpression is a literal or a simple materialized literal it | 1816 // If the subexpression is a literal or a simple materialized literal it |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1827 // Store the subexpression value in the array's elements. | 1833 // Store the subexpression value in the array's elements. |
| 1828 __ mov(FieldOperand(ebx, offset), result_register()); | 1834 __ mov(FieldOperand(ebx, offset), result_register()); |
| 1829 // Update the write barrier for the array store. | 1835 // Update the write barrier for the array store. |
| 1830 __ RecordWriteField(ebx, offset, result_register(), ecx, | 1836 __ RecordWriteField(ebx, offset, result_register(), ecx, |
| 1831 kDontSaveFPRegs, | 1837 kDontSaveFPRegs, |
| 1832 EMIT_REMEMBERED_SET, | 1838 EMIT_REMEMBERED_SET, |
| 1833 INLINE_SMI_CHECK); | 1839 INLINE_SMI_CHECK); |
| 1834 } else { | 1840 } else { |
| 1835 // Store the subexpression value in the array's elements. | 1841 // Store the subexpression value in the array's elements. |
| 1836 __ mov(ecx, Immediate(Smi::FromInt(i))); | 1842 __ mov(ecx, Immediate(Smi::FromInt(i))); |
| 1837 StoreArrayLiteralElementStub stub; | 1843 StoreArrayLiteralElementStub stub(isolate()); |
| 1838 __ CallStub(&stub); | 1844 __ CallStub(&stub); |
| 1839 } | 1845 } |
| 1840 | 1846 |
| 1841 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); | 1847 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); |
| 1842 } | 1848 } |
| 1843 | 1849 |
| 1844 if (result_saved) { | 1850 if (result_saved) { |
| 1845 __ add(esp, Immediate(kPointerSize)); // literal index | 1851 __ add(esp, Immediate(kPointerSize)); // literal index |
| 1846 context()->PlugTOS(); | 1852 context()->PlugTOS(); |
| 1847 } else { | 1853 } else { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2076 __ push(Operand(esp, 2 * kPointerSize)); // iter | 2082 __ push(Operand(esp, 2 * kPointerSize)); // iter |
| 2077 __ push(eax); // received | 2083 __ push(eax); // received |
| 2078 | 2084 |
| 2079 // result = receiver[f](arg); | 2085 // result = receiver[f](arg); |
| 2080 __ bind(&l_call); | 2086 __ bind(&l_call); |
| 2081 __ mov(edx, Operand(esp, kPointerSize)); | 2087 __ mov(edx, Operand(esp, kPointerSize)); |
| 2082 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2088 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2083 CallIC(ic, TypeFeedbackId::None()); | 2089 CallIC(ic, TypeFeedbackId::None()); |
| 2084 __ mov(edi, eax); | 2090 __ mov(edi, eax); |
| 2085 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2091 __ mov(Operand(esp, 2 * kPointerSize), edi); |
| 2086 CallFunctionStub stub(1, CALL_AS_METHOD); | 2092 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2087 __ CallStub(&stub); | 2093 __ CallStub(&stub); |
| 2088 | 2094 |
| 2089 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2095 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2090 __ Drop(1); // The function is still on the stack; drop it. | 2096 __ Drop(1); // The function is still on the stack; drop it. |
| 2091 | 2097 |
| 2092 // if (!result.done) goto l_try; | 2098 // if (!result.done) goto l_try; |
| 2093 __ bind(&l_loop); | 2099 __ bind(&l_loop); |
| 2094 __ push(eax); // save result | 2100 __ push(eax); // save result |
| 2095 __ mov(edx, eax); // result | 2101 __ mov(edx, eax); // result |
| 2096 __ mov(ecx, isolate()->factory()->done_string()); // "done" | 2102 __ mov(ecx, isolate()->factory()->done_string()); // "done" |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2283 // stack. Right operand is in eax. | 2289 // stack. Right operand is in eax. |
| 2284 Label smi_case, done, stub_call; | 2290 Label smi_case, done, stub_call; |
| 2285 __ pop(edx); | 2291 __ pop(edx); |
| 2286 __ mov(ecx, eax); | 2292 __ mov(ecx, eax); |
| 2287 __ or_(eax, edx); | 2293 __ or_(eax, edx); |
| 2288 JumpPatchSite patch_site(masm_); | 2294 JumpPatchSite patch_site(masm_); |
| 2289 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 2295 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
| 2290 | 2296 |
| 2291 __ bind(&stub_call); | 2297 __ bind(&stub_call); |
| 2292 __ mov(eax, ecx); | 2298 __ mov(eax, ecx); |
| 2293 BinaryOpICStub stub(op, mode); | 2299 BinaryOpICStub stub(isolate(), op, mode); |
| 2294 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2300 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
| 2295 patch_site.EmitPatchInfo(); | 2301 patch_site.EmitPatchInfo(); |
| 2296 __ jmp(&done, Label::kNear); | 2302 __ jmp(&done, Label::kNear); |
| 2297 | 2303 |
| 2298 // Smi case. | 2304 // Smi case. |
| 2299 __ bind(&smi_case); | 2305 __ bind(&smi_case); |
| 2300 __ mov(eax, edx); // Copy left operand in case of a stub call. | 2306 __ mov(eax, edx); // Copy left operand in case of a stub call. |
| 2301 | 2307 |
| 2302 switch (op) { | 2308 switch (op) { |
| 2303 case Token::SAR: | 2309 case Token::SAR: |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 | 2372 |
| 2367 __ bind(&done); | 2373 __ bind(&done); |
| 2368 context()->Plug(eax); | 2374 context()->Plug(eax); |
| 2369 } | 2375 } |
| 2370 | 2376 |
| 2371 | 2377 |
| 2372 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2378 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2373 Token::Value op, | 2379 Token::Value op, |
| 2374 OverwriteMode mode) { | 2380 OverwriteMode mode) { |
| 2375 __ pop(edx); | 2381 __ pop(edx); |
| 2376 BinaryOpICStub stub(op, mode); | 2382 BinaryOpICStub stub(isolate(), op, mode); |
| 2377 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2383 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2378 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2384 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
| 2379 patch_site.EmitPatchInfo(); | 2385 patch_site.EmitPatchInfo(); |
| 2380 context()->Plug(eax); | 2386 context()->Plug(eax); |
| 2381 } | 2387 } |
| 2382 | 2388 |
| 2383 | 2389 |
| 2384 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2390 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2385 ASSERT(expr->IsValidReferenceExpression()); | 2391 ASSERT(expr->IsValidReferenceExpression()); |
| 2386 | 2392 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2615 | 2621 |
| 2616 // Load the arguments. | 2622 // Load the arguments. |
| 2617 { PreservePositionScope scope(masm()->positions_recorder()); | 2623 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2618 for (int i = 0; i < arg_count; i++) { | 2624 for (int i = 0; i < arg_count; i++) { |
| 2619 VisitForStackValue(args->at(i)); | 2625 VisitForStackValue(args->at(i)); |
| 2620 } | 2626 } |
| 2621 } | 2627 } |
| 2622 | 2628 |
| 2623 // Record source position of the IC call. | 2629 // Record source position of the IC call. |
| 2624 SetSourcePosition(expr->position()); | 2630 SetSourcePosition(expr->position()); |
| 2625 CallFunctionStub stub(arg_count, flags); | 2631 CallFunctionStub stub(isolate(), arg_count, flags); |
| 2626 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2632 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2627 __ CallStub(&stub); | 2633 __ CallStub(&stub); |
| 2628 RecordJSReturnSite(expr); | 2634 RecordJSReturnSite(expr); |
| 2629 | 2635 |
| 2630 // Restore context register. | 2636 // Restore context register. |
| 2631 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2637 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2632 | 2638 |
| 2633 context()->DropAndPlug(1, eax); | 2639 context()->DropAndPlug(1, eax); |
| 2634 } | 2640 } |
| 2635 | 2641 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2658 | 2664 |
| 2659 // Load the arguments. | 2665 // Load the arguments. |
| 2660 { PreservePositionScope scope(masm()->positions_recorder()); | 2666 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2661 for (int i = 0; i < arg_count; i++) { | 2667 for (int i = 0; i < arg_count; i++) { |
| 2662 VisitForStackValue(args->at(i)); | 2668 VisitForStackValue(args->at(i)); |
| 2663 } | 2669 } |
| 2664 } | 2670 } |
| 2665 | 2671 |
| 2666 // Record source position of the IC call. | 2672 // Record source position of the IC call. |
| 2667 SetSourcePosition(expr->position()); | 2673 SetSourcePosition(expr->position()); |
| 2668 CallFunctionStub stub(arg_count, CALL_AS_METHOD); | 2674 CallFunctionStub stub(isolate(), arg_count, CALL_AS_METHOD); |
| 2669 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2675 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2670 __ CallStub(&stub); | 2676 __ CallStub(&stub); |
| 2671 RecordJSReturnSite(expr); | 2677 RecordJSReturnSite(expr); |
| 2672 | 2678 |
| 2673 // Restore context register. | 2679 // Restore context register. |
| 2674 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2680 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2675 | 2681 |
| 2676 context()->DropAndPlug(1, eax); | 2682 context()->DropAndPlug(1, eax); |
| 2677 } | 2683 } |
| 2678 | 2684 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2689 // Record source position for debugger. | 2695 // Record source position for debugger. |
| 2690 SetSourcePosition(expr->position()); | 2696 SetSourcePosition(expr->position()); |
| 2691 | 2697 |
| 2692 Handle<Object> uninitialized = | 2698 Handle<Object> uninitialized = |
| 2693 TypeFeedbackInfo::UninitializedSentinel(isolate()); | 2699 TypeFeedbackInfo::UninitializedSentinel(isolate()); |
| 2694 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); | 2700 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); |
| 2695 __ LoadHeapObject(ebx, FeedbackVector()); | 2701 __ LoadHeapObject(ebx, FeedbackVector()); |
| 2696 __ mov(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot()))); | 2702 __ mov(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot()))); |
| 2697 | 2703 |
| 2698 // Record call targets in unoptimized code. | 2704 // Record call targets in unoptimized code. |
| 2699 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); | 2705 CallFunctionStub stub(isolate(), arg_count, RECORD_CALL_TARGET); |
| 2700 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2706 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2701 __ CallStub(&stub); | 2707 __ CallStub(&stub); |
| 2702 | 2708 |
| 2703 RecordJSReturnSite(expr); | 2709 RecordJSReturnSite(expr); |
| 2704 // Restore context register. | 2710 // Restore context register. |
| 2705 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2711 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2706 context()->DropAndPlug(1, eax); | 2712 context()->DropAndPlug(1, eax); |
| 2707 } | 2713 } |
| 2708 | 2714 |
| 2709 | 2715 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2759 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); | 2765 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2760 EmitResolvePossiblyDirectEval(arg_count); | 2766 EmitResolvePossiblyDirectEval(arg_count); |
| 2761 | 2767 |
| 2762 // The runtime call returns a pair of values in eax (function) and | 2768 // The runtime call returns a pair of values in eax (function) and |
| 2763 // edx (receiver). Touch up the stack with the right values. | 2769 // edx (receiver). Touch up the stack with the right values. |
| 2764 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); | 2770 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); |
| 2765 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); | 2771 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); |
| 2766 } | 2772 } |
| 2767 // Record source position for debugger. | 2773 // Record source position for debugger. |
| 2768 SetSourcePosition(expr->position()); | 2774 SetSourcePosition(expr->position()); |
| 2769 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2775 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 2770 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2776 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2771 __ CallStub(&stub); | 2777 __ CallStub(&stub); |
| 2772 RecordJSReturnSite(expr); | 2778 RecordJSReturnSite(expr); |
| 2773 // Restore context register. | 2779 // Restore context register. |
| 2774 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2780 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2775 context()->DropAndPlug(1, eax); | 2781 context()->DropAndPlug(1, eax); |
| 2776 | 2782 |
| 2777 } else if (call_type == Call::GLOBAL_CALL) { | 2783 } else if (call_type == Call::GLOBAL_CALL) { |
| 2778 EmitCallWithIC(expr); | 2784 EmitCallWithIC(expr); |
| 2779 | 2785 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2875 if (FLAG_pretenuring_call_new) { | 2881 if (FLAG_pretenuring_call_new) { |
| 2876 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), | 2882 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), |
| 2877 isolate()->factory()->NewAllocationSite()); | 2883 isolate()->factory()->NewAllocationSite()); |
| 2878 ASSERT(expr->AllocationSiteFeedbackSlot() == | 2884 ASSERT(expr->AllocationSiteFeedbackSlot() == |
| 2879 expr->CallNewFeedbackSlot() + 1); | 2885 expr->CallNewFeedbackSlot() + 1); |
| 2880 } | 2886 } |
| 2881 | 2887 |
| 2882 __ LoadHeapObject(ebx, FeedbackVector()); | 2888 __ LoadHeapObject(ebx, FeedbackVector()); |
| 2883 __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot()))); | 2889 __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot()))); |
| 2884 | 2890 |
| 2885 CallConstructStub stub(RECORD_CALL_TARGET); | 2891 CallConstructStub stub(isolate(), RECORD_CALL_TARGET); |
| 2886 __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 2892 __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |
| 2887 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2893 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2888 context()->Plug(eax); | 2894 context()->Plug(eax); |
| 2889 } | 2895 } |
| 2890 | 2896 |
| 2891 | 2897 |
| 2892 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2898 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 2893 ZoneList<Expression*>* args = expr->arguments(); | 2899 ZoneList<Expression*>* args = expr->arguments(); |
| 2894 ASSERT(args->length() == 1); | 2900 ASSERT(args->length() == 1); |
| 2895 | 2901 |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3252 | 3258 |
| 3253 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { | 3259 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
| 3254 ZoneList<Expression*>* args = expr->arguments(); | 3260 ZoneList<Expression*>* args = expr->arguments(); |
| 3255 ASSERT(args->length() == 1); | 3261 ASSERT(args->length() == 1); |
| 3256 | 3262 |
| 3257 // ArgumentsAccessStub expects the key in edx and the formal | 3263 // ArgumentsAccessStub expects the key in edx and the formal |
| 3258 // parameter count in eax. | 3264 // parameter count in eax. |
| 3259 VisitForAccumulatorValue(args->at(0)); | 3265 VisitForAccumulatorValue(args->at(0)); |
| 3260 __ mov(edx, eax); | 3266 __ mov(edx, eax); |
| 3261 __ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); | 3267 __ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); |
| 3262 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 3268 ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); |
| 3263 __ CallStub(&stub); | 3269 __ CallStub(&stub); |
| 3264 context()->Plug(eax); | 3270 context()->Plug(eax); |
| 3265 } | 3271 } |
| 3266 | 3272 |
| 3267 | 3273 |
| 3268 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { | 3274 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
| 3269 ASSERT(expr->arguments()->length() == 0); | 3275 ASSERT(expr->arguments()->length() == 0); |
| 3270 | 3276 |
| 3271 Label exit; | 3277 Label exit; |
| 3272 // Get the number of formal parameters. | 3278 // Get the number of formal parameters. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3365 __ CallRuntime(Runtime::kHiddenLog, 2); | 3371 __ CallRuntime(Runtime::kHiddenLog, 2); |
| 3366 } | 3372 } |
| 3367 // Finally, we're expected to leave a value on the top of the stack. | 3373 // Finally, we're expected to leave a value on the top of the stack. |
| 3368 __ mov(eax, isolate()->factory()->undefined_value()); | 3374 __ mov(eax, isolate()->factory()->undefined_value()); |
| 3369 context()->Plug(eax); | 3375 context()->Plug(eax); |
| 3370 } | 3376 } |
| 3371 | 3377 |
| 3372 | 3378 |
| 3373 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3379 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3374 // Load the arguments on the stack and call the stub. | 3380 // Load the arguments on the stack and call the stub. |
| 3375 SubStringStub stub; | 3381 SubStringStub stub(isolate()); |
| 3376 ZoneList<Expression*>* args = expr->arguments(); | 3382 ZoneList<Expression*>* args = expr->arguments(); |
| 3377 ASSERT(args->length() == 3); | 3383 ASSERT(args->length() == 3); |
| 3378 VisitForStackValue(args->at(0)); | 3384 VisitForStackValue(args->at(0)); |
| 3379 VisitForStackValue(args->at(1)); | 3385 VisitForStackValue(args->at(1)); |
| 3380 VisitForStackValue(args->at(2)); | 3386 VisitForStackValue(args->at(2)); |
| 3381 __ CallStub(&stub); | 3387 __ CallStub(&stub); |
| 3382 context()->Plug(eax); | 3388 context()->Plug(eax); |
| 3383 } | 3389 } |
| 3384 | 3390 |
| 3385 | 3391 |
| 3386 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | 3392 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3387 // Load the arguments on the stack and call the stub. | 3393 // Load the arguments on the stack and call the stub. |
| 3388 RegExpExecStub stub; | 3394 RegExpExecStub stub(isolate()); |
| 3389 ZoneList<Expression*>* args = expr->arguments(); | 3395 ZoneList<Expression*>* args = expr->arguments(); |
| 3390 ASSERT(args->length() == 4); | 3396 ASSERT(args->length() == 4); |
| 3391 VisitForStackValue(args->at(0)); | 3397 VisitForStackValue(args->at(0)); |
| 3392 VisitForStackValue(args->at(1)); | 3398 VisitForStackValue(args->at(1)); |
| 3393 VisitForStackValue(args->at(2)); | 3399 VisitForStackValue(args->at(2)); |
| 3394 VisitForStackValue(args->at(3)); | 3400 VisitForStackValue(args->at(3)); |
| 3395 __ CallStub(&stub); | 3401 __ CallStub(&stub); |
| 3396 context()->Plug(eax); | 3402 context()->Plug(eax); |
| 3397 } | 3403 } |
| 3398 | 3404 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3531 | 3537 |
| 3532 | 3538 |
| 3533 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { | 3539 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 3534 // Load the arguments on the stack and call the runtime function. | 3540 // Load the arguments on the stack and call the runtime function. |
| 3535 ZoneList<Expression*>* args = expr->arguments(); | 3541 ZoneList<Expression*>* args = expr->arguments(); |
| 3536 ASSERT(args->length() == 2); | 3542 ASSERT(args->length() == 2); |
| 3537 VisitForStackValue(args->at(0)); | 3543 VisitForStackValue(args->at(0)); |
| 3538 VisitForStackValue(args->at(1)); | 3544 VisitForStackValue(args->at(1)); |
| 3539 | 3545 |
| 3540 if (CpuFeatures::IsSupported(SSE2)) { | 3546 if (CpuFeatures::IsSupported(SSE2)) { |
| 3541 MathPowStub stub(MathPowStub::ON_STACK); | 3547 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 3542 __ CallStub(&stub); | 3548 __ CallStub(&stub); |
| 3543 } else { | 3549 } else { |
| 3544 __ CallRuntime(Runtime::kHiddenMathPowSlow, 2); | 3550 __ CallRuntime(Runtime::kHiddenMathPowSlow, 2); |
| 3545 } | 3551 } |
| 3546 context()->Plug(eax); | 3552 context()->Plug(eax); |
| 3547 } | 3553 } |
| 3548 | 3554 |
| 3549 | 3555 |
| 3550 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3556 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3551 ZoneList<Expression*>* args = expr->arguments(); | 3557 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3576 } | 3582 } |
| 3577 | 3583 |
| 3578 | 3584 |
| 3579 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { | 3585 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 3580 ZoneList<Expression*>* args = expr->arguments(); | 3586 ZoneList<Expression*>* args = expr->arguments(); |
| 3581 ASSERT_EQ(args->length(), 1); | 3587 ASSERT_EQ(args->length(), 1); |
| 3582 | 3588 |
| 3583 // Load the argument into eax and call the stub. | 3589 // Load the argument into eax and call the stub. |
| 3584 VisitForAccumulatorValue(args->at(0)); | 3590 VisitForAccumulatorValue(args->at(0)); |
| 3585 | 3591 |
| 3586 NumberToStringStub stub; | 3592 NumberToStringStub stub(isolate()); |
| 3587 __ CallStub(&stub); | 3593 __ CallStub(&stub); |
| 3588 context()->Plug(eax); | 3594 context()->Plug(eax); |
| 3589 } | 3595 } |
| 3590 | 3596 |
| 3591 | 3597 |
| 3592 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 3598 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 3593 ZoneList<Expression*>* args = expr->arguments(); | 3599 ZoneList<Expression*>* args = expr->arguments(); |
| 3594 ASSERT(args->length() == 1); | 3600 ASSERT(args->length() == 1); |
| 3595 | 3601 |
| 3596 VisitForAccumulatorValue(args->at(0)); | 3602 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3702 } | 3708 } |
| 3703 | 3709 |
| 3704 | 3710 |
| 3705 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { | 3711 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
| 3706 ZoneList<Expression*>* args = expr->arguments(); | 3712 ZoneList<Expression*>* args = expr->arguments(); |
| 3707 ASSERT_EQ(2, args->length()); | 3713 ASSERT_EQ(2, args->length()); |
| 3708 VisitForStackValue(args->at(0)); | 3714 VisitForStackValue(args->at(0)); |
| 3709 VisitForAccumulatorValue(args->at(1)); | 3715 VisitForAccumulatorValue(args->at(1)); |
| 3710 | 3716 |
| 3711 __ pop(edx); | 3717 __ pop(edx); |
| 3712 StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED); | 3718 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 3713 __ CallStub(&stub); | 3719 __ CallStub(&stub); |
| 3714 context()->Plug(eax); | 3720 context()->Plug(eax); |
| 3715 } | 3721 } |
| 3716 | 3722 |
| 3717 | 3723 |
| 3718 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { | 3724 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 3719 ZoneList<Expression*>* args = expr->arguments(); | 3725 ZoneList<Expression*>* args = expr->arguments(); |
| 3720 ASSERT_EQ(2, args->length()); | 3726 ASSERT_EQ(2, args->length()); |
| 3721 | 3727 |
| 3722 VisitForStackValue(args->at(0)); | 3728 VisitForStackValue(args->at(0)); |
| 3723 VisitForStackValue(args->at(1)); | 3729 VisitForStackValue(args->at(1)); |
| 3724 | 3730 |
| 3725 StringCompareStub stub; | 3731 StringCompareStub stub(isolate()); |
| 3726 __ CallStub(&stub); | 3732 __ CallStub(&stub); |
| 3727 context()->Plug(eax); | 3733 context()->Plug(eax); |
| 3728 } | 3734 } |
| 3729 | 3735 |
| 3730 | 3736 |
| 3731 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 3737 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3732 ZoneList<Expression*>* args = expr->arguments(); | 3738 ZoneList<Expression*>* args = expr->arguments(); |
| 3733 ASSERT(args->length() >= 2); | 3739 ASSERT(args->length() >= 2); |
| 3734 | 3740 |
| 3735 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3741 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3755 __ push(eax); | 3761 __ push(eax); |
| 3756 __ CallRuntime(Runtime::kCall, args->length()); | 3762 __ CallRuntime(Runtime::kCall, args->length()); |
| 3757 __ bind(&done); | 3763 __ bind(&done); |
| 3758 | 3764 |
| 3759 context()->Plug(eax); | 3765 context()->Plug(eax); |
| 3760 } | 3766 } |
| 3761 | 3767 |
| 3762 | 3768 |
| 3763 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { | 3769 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
| 3764 // Load the arguments on the stack and call the stub. | 3770 // Load the arguments on the stack and call the stub. |
| 3765 RegExpConstructResultStub stub; | 3771 RegExpConstructResultStub stub(isolate()); |
| 3766 ZoneList<Expression*>* args = expr->arguments(); | 3772 ZoneList<Expression*>* args = expr->arguments(); |
| 3767 ASSERT(args->length() == 3); | 3773 ASSERT(args->length() == 3); |
| 3768 VisitForStackValue(args->at(0)); | 3774 VisitForStackValue(args->at(0)); |
| 3769 VisitForStackValue(args->at(1)); | 3775 VisitForStackValue(args->at(1)); |
| 3770 VisitForAccumulatorValue(args->at(2)); | 3776 VisitForAccumulatorValue(args->at(2)); |
| 3771 __ pop(ebx); | 3777 __ pop(ebx); |
| 3772 __ pop(ecx); | 3778 __ pop(ecx); |
| 3773 __ CallStub(&stub); | 3779 __ CallStub(&stub); |
| 3774 context()->Plug(eax); | 3780 context()->Plug(eax); |
| 3775 } | 3781 } |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4153 | 4159 |
| 4154 // Code common for calls using the IC. | 4160 // Code common for calls using the IC. |
| 4155 ZoneList<Expression*>* args = expr->arguments(); | 4161 ZoneList<Expression*>* args = expr->arguments(); |
| 4156 int arg_count = args->length(); | 4162 int arg_count = args->length(); |
| 4157 for (int i = 0; i < arg_count; i++) { | 4163 for (int i = 0; i < arg_count; i++) { |
| 4158 VisitForStackValue(args->at(i)); | 4164 VisitForStackValue(args->at(i)); |
| 4159 } | 4165 } |
| 4160 | 4166 |
| 4161 // Record source position of the IC call. | 4167 // Record source position of the IC call. |
| 4162 SetSourcePosition(expr->position()); | 4168 SetSourcePosition(expr->position()); |
| 4163 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 4169 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4164 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 4170 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 4165 __ CallStub(&stub); | 4171 __ CallStub(&stub); |
| 4166 // Restore context register. | 4172 // Restore context register. |
| 4167 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4173 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 4168 context()->DropAndPlug(1, eax); | 4174 context()->DropAndPlug(1, eax); |
| 4169 | 4175 |
| 4170 } else { | 4176 } else { |
| 4171 // Push the arguments ("left-to-right"). | 4177 // Push the arguments ("left-to-right"). |
| 4172 int arg_count = args->length(); | 4178 int arg_count = args->length(); |
| 4173 for (int i = 0; i < arg_count; i++) { | 4179 for (int i = 0; i < arg_count; i++) { |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4382 __ j(no_overflow, &done, Label::kNear); | 4388 __ j(no_overflow, &done, Label::kNear); |
| 4383 // Call stub. Undo operation first. | 4389 // Call stub. Undo operation first. |
| 4384 if (expr->op() == Token::INC) { | 4390 if (expr->op() == Token::INC) { |
| 4385 __ sub(eax, Immediate(Smi::FromInt(1))); | 4391 __ sub(eax, Immediate(Smi::FromInt(1))); |
| 4386 } else { | 4392 } else { |
| 4387 __ add(eax, Immediate(Smi::FromInt(1))); | 4393 __ add(eax, Immediate(Smi::FromInt(1))); |
| 4388 } | 4394 } |
| 4389 __ jmp(&stub_call, Label::kNear); | 4395 __ jmp(&stub_call, Label::kNear); |
| 4390 __ bind(&slow); | 4396 __ bind(&slow); |
| 4391 } | 4397 } |
| 4392 ToNumberStub convert_stub; | 4398 ToNumberStub convert_stub(isolate()); |
| 4393 __ CallStub(&convert_stub); | 4399 __ CallStub(&convert_stub); |
| 4394 | 4400 |
| 4395 // Save result for postfix expressions. | 4401 // Save result for postfix expressions. |
| 4396 if (expr->is_postfix()) { | 4402 if (expr->is_postfix()) { |
| 4397 if (!context()->IsEffect()) { | 4403 if (!context()->IsEffect()) { |
| 4398 // Save the result on the stack. If we have a named or keyed property | 4404 // Save the result on the stack. If we have a named or keyed property |
| 4399 // we store the result under the receiver that is currently on top | 4405 // we store the result under the receiver that is currently on top |
| 4400 // of the stack. | 4406 // of the stack. |
| 4401 switch (assign_type) { | 4407 switch (assign_type) { |
| 4402 case VARIABLE: | 4408 case VARIABLE: |
| 4403 __ push(eax); | 4409 __ push(eax); |
| 4404 break; | 4410 break; |
| 4405 case NAMED_PROPERTY: | 4411 case NAMED_PROPERTY: |
| 4406 __ mov(Operand(esp, kPointerSize), eax); | 4412 __ mov(Operand(esp, kPointerSize), eax); |
| 4407 break; | 4413 break; |
| 4408 case KEYED_PROPERTY: | 4414 case KEYED_PROPERTY: |
| 4409 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4415 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 4410 break; | 4416 break; |
| 4411 } | 4417 } |
| 4412 } | 4418 } |
| 4413 } | 4419 } |
| 4414 | 4420 |
| 4415 // Record position before stub call. | 4421 // Record position before stub call. |
| 4416 SetSourcePosition(expr->position()); | 4422 SetSourcePosition(expr->position()); |
| 4417 | 4423 |
| 4418 // Call stub for +1/-1. | 4424 // Call stub for +1/-1. |
| 4419 __ bind(&stub_call); | 4425 __ bind(&stub_call); |
| 4420 __ mov(edx, eax); | 4426 __ mov(edx, eax); |
| 4421 __ mov(eax, Immediate(Smi::FromInt(1))); | 4427 __ mov(eax, Immediate(Smi::FromInt(1))); |
| 4422 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); | 4428 BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); |
| 4423 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); | 4429 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); |
| 4424 patch_site.EmitPatchInfo(); | 4430 patch_site.EmitPatchInfo(); |
| 4425 __ bind(&done); | 4431 __ bind(&done); |
| 4426 | 4432 |
| 4427 // Store the value returned in eax. | 4433 // Store the value returned in eax. |
| 4428 switch (assign_type) { | 4434 switch (assign_type) { |
| 4429 case VARIABLE: | 4435 case VARIABLE: |
| 4430 if (expr->is_postfix()) { | 4436 if (expr->is_postfix()) { |
| 4431 // Perform the assignment as if via '='. | 4437 // Perform the assignment as if via '='. |
| 4432 { EffectContext context(this); | 4438 { EffectContext context(this); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4623 case Token::IN: | 4629 case Token::IN: |
| 4624 VisitForStackValue(expr->right()); | 4630 VisitForStackValue(expr->right()); |
| 4625 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4631 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 4626 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 4632 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 4627 __ cmp(eax, isolate()->factory()->true_value()); | 4633 __ cmp(eax, isolate()->factory()->true_value()); |
| 4628 Split(equal, if_true, if_false, fall_through); | 4634 Split(equal, if_true, if_false, fall_through); |
| 4629 break; | 4635 break; |
| 4630 | 4636 |
| 4631 case Token::INSTANCEOF: { | 4637 case Token::INSTANCEOF: { |
| 4632 VisitForStackValue(expr->right()); | 4638 VisitForStackValue(expr->right()); |
| 4633 InstanceofStub stub(InstanceofStub::kNoFlags); | 4639 InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); |
| 4634 __ CallStub(&stub); | 4640 __ CallStub(&stub); |
| 4635 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4641 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4636 __ test(eax, eax); | 4642 __ test(eax, eax); |
| 4637 // The stub returns 0 for true. | 4643 // The stub returns 0 for true. |
| 4638 Split(zero, if_true, if_false, fall_through); | 4644 Split(zero, if_true, if_false, fall_through); |
| 4639 break; | 4645 break; |
| 4640 } | 4646 } |
| 4641 | 4647 |
| 4642 default: { | 4648 default: { |
| 4643 VisitForAccumulatorValue(expr->right()); | 4649 VisitForAccumulatorValue(expr->right()); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4919 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4925 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4920 Assembler::target_address_at(call_target_address, | 4926 Assembler::target_address_at(call_target_address, |
| 4921 unoptimized_code)); | 4927 unoptimized_code)); |
| 4922 return OSR_AFTER_STACK_CHECK; | 4928 return OSR_AFTER_STACK_CHECK; |
| 4923 } | 4929 } |
| 4924 | 4930 |
| 4925 | 4931 |
| 4926 } } // namespace v8::internal | 4932 } } // namespace v8::internal |
| 4927 | 4933 |
| 4928 #endif // V8_TARGET_ARCH_IA32 | 4934 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |