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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 // Possibly allocate a local context. | 223 // Possibly allocate a local context. |
224 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 224 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
225 if (heap_slots > 0) { | 225 if (heap_slots > 0) { |
226 Comment cmnt(masm_, "[ Allocate context"); | 226 Comment cmnt(masm_, "[ Allocate context"); |
227 // Argument to NewContext is the function, which is still in rdi. | 227 // Argument to NewContext is the function, which is still in rdi. |
228 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 228 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
229 __ Push(rdi); | 229 __ Push(rdi); |
230 __ Push(info->scope()->GetScopeInfo()); | 230 __ Push(info->scope()->GetScopeInfo()); |
231 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 231 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
232 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 232 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
233 FastNewContextStub stub(heap_slots); | 233 FastNewContextStub stub(isolate(), heap_slots); |
234 __ CallStub(&stub); | 234 __ CallStub(&stub); |
235 } else { | 235 } else { |
236 __ Push(rdi); | 236 __ Push(rdi); |
237 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 237 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
238 } | 238 } |
239 function_in_register = false; | 239 function_in_register = false; |
240 // Context is returned in rax. It replaces the context passed to us. | 240 // Context is returned in rax. It replaces the context passed to us. |
241 // It's saved in the stack and kept live in rsi. | 241 // It's saved in the stack and kept live in rsi. |
242 __ movp(rsi, rax); | 242 __ movp(rsi, rax); |
243 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); | 243 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); |
(...skipping 40 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, rax, rbx, rdx); | 297 SetVar(arguments, rax, rbx, rdx); |
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 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 // space for nested functions that don't need literals cloning. If | 1330 // space for nested functions that don't need literals cloning. If |
1331 // we're running with the --always-opt or the --prepare-always-opt | 1331 // we're running with the --always-opt or the --prepare-always-opt |
1332 // flag, we need to use the runtime function so that the new function | 1332 // flag, we need to use the runtime function so that the new function |
1333 // we are creating here gets a chance to have its code optimized and | 1333 // we are creating here gets a chance to have its code optimized and |
1334 // doesn't just get a copy of the existing unoptimized code. | 1334 // doesn't just get a copy of the existing unoptimized code. |
1335 if (!FLAG_always_opt && | 1335 if (!FLAG_always_opt && |
1336 !FLAG_prepare_always_opt && | 1336 !FLAG_prepare_always_opt && |
1337 !pretenure && | 1337 !pretenure && |
1338 scope()->is_function_scope() && | 1338 scope()->is_function_scope() && |
1339 info->num_literals() == 0) { | 1339 info->num_literals() == 0) { |
1340 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1340 FastNewClosureStub stub(isolate(), |
| 1341 info->strict_mode(), |
| 1342 info->is_generator()); |
1341 __ Move(rbx, info); | 1343 __ Move(rbx, info); |
1342 __ CallStub(&stub); | 1344 __ CallStub(&stub); |
1343 } else { | 1345 } else { |
1344 __ Push(rsi); | 1346 __ Push(rsi); |
1345 __ Push(info); | 1347 __ Push(info); |
1346 __ Push(pretenure | 1348 __ Push(pretenure |
1347 ? isolate()->factory()->true_value() | 1349 ? isolate()->factory()->true_value() |
1348 : isolate()->factory()->false_value()); | 1350 : isolate()->factory()->false_value()); |
1349 __ CallRuntime(Runtime::kHiddenNewClosure, 3); | 1351 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
1350 } | 1352 } |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 __ Push(Smi::FromInt(expr->literal_index())); | 1666 __ Push(Smi::FromInt(expr->literal_index())); |
1665 __ Push(constant_properties); | 1667 __ Push(constant_properties); |
1666 __ Push(Smi::FromInt(flags)); | 1668 __ Push(Smi::FromInt(flags)); |
1667 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); | 1669 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
1668 } else { | 1670 } else { |
1669 __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1671 __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1670 __ movp(rax, FieldOperand(rdi, JSFunction::kLiteralsOffset)); | 1672 __ movp(rax, FieldOperand(rdi, JSFunction::kLiteralsOffset)); |
1671 __ Move(rbx, Smi::FromInt(expr->literal_index())); | 1673 __ Move(rbx, Smi::FromInt(expr->literal_index())); |
1672 __ Move(rcx, constant_properties); | 1674 __ Move(rcx, constant_properties); |
1673 __ Move(rdx, Smi::FromInt(flags)); | 1675 __ Move(rdx, Smi::FromInt(flags)); |
1674 FastCloneShallowObjectStub stub(properties_count); | 1676 FastCloneShallowObjectStub stub(isolate(), properties_count); |
1675 __ CallStub(&stub); | 1677 __ CallStub(&stub); |
1676 } | 1678 } |
1677 | 1679 |
1678 // If result_saved is true the result is on top of the stack. If | 1680 // If result_saved is true the result is on top of the stack. If |
1679 // result_saved is false the result is in rax. | 1681 // result_saved is false the result is in rax. |
1680 bool result_saved = false; | 1682 bool result_saved = false; |
1681 | 1683 |
1682 // Mark all computed expressions that are bound to a key that | 1684 // Mark all computed expressions that are bound to a key that |
1683 // is shadowed by a later occurrence of the same key. For the | 1685 // is shadowed by a later occurrence of the same key. For the |
1684 // marked expressions, no store code is emitted. | 1686 // marked expressions, no store code is emitted. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 if (has_constant_fast_elements && | 1801 if (has_constant_fast_elements && |
1800 constant_elements_values->map() == heap->fixed_cow_array_map()) { | 1802 constant_elements_values->map() == heap->fixed_cow_array_map()) { |
1801 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot | 1803 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot |
1802 // change, so it's possible to specialize the stub in advance. | 1804 // change, so it's possible to specialize the stub in advance. |
1803 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); | 1805 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); |
1804 __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1806 __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1805 __ movp(rax, FieldOperand(rbx, JSFunction::kLiteralsOffset)); | 1807 __ movp(rax, FieldOperand(rbx, JSFunction::kLiteralsOffset)); |
1806 __ Move(rbx, Smi::FromInt(expr->literal_index())); | 1808 __ Move(rbx, Smi::FromInt(expr->literal_index())); |
1807 __ Move(rcx, constant_elements); | 1809 __ Move(rcx, constant_elements); |
1808 FastCloneShallowArrayStub stub( | 1810 FastCloneShallowArrayStub stub( |
| 1811 isolate(), |
1809 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1812 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
1810 allocation_site_mode, | 1813 allocation_site_mode, |
1811 length); | 1814 length); |
1812 __ CallStub(&stub); | 1815 __ CallStub(&stub); |
1813 } else if (expr->depth() > 1 || Serializer::enabled() || | 1816 } else if (expr->depth() > 1 || Serializer::enabled() || |
1814 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1817 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
1815 __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1818 __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1816 __ Push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); | 1819 __ Push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); |
1817 __ Push(Smi::FromInt(expr->literal_index())); | 1820 __ Push(Smi::FromInt(expr->literal_index())); |
1818 __ Push(constant_elements); | 1821 __ Push(constant_elements); |
1819 __ Push(Smi::FromInt(flags)); | 1822 __ Push(Smi::FromInt(flags)); |
1820 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); | 1823 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
1821 } else { | 1824 } else { |
1822 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1825 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
1823 FLAG_smi_only_arrays); | 1826 FLAG_smi_only_arrays); |
1824 FastCloneShallowArrayStub::Mode mode = | 1827 FastCloneShallowArrayStub::Mode mode = |
1825 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1828 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
1826 | 1829 |
1827 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot | 1830 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot |
1828 // change, so it's possible to specialize the stub in advance. | 1831 // change, so it's possible to specialize the stub in advance. |
1829 if (has_constant_fast_elements) { | 1832 if (has_constant_fast_elements) { |
1830 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1833 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
1831 } | 1834 } |
1832 | 1835 |
1833 __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1836 __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1834 __ movp(rax, FieldOperand(rbx, JSFunction::kLiteralsOffset)); | 1837 __ movp(rax, FieldOperand(rbx, JSFunction::kLiteralsOffset)); |
1835 __ Move(rbx, Smi::FromInt(expr->literal_index())); | 1838 __ Move(rbx, Smi::FromInt(expr->literal_index())); |
1836 __ Move(rcx, constant_elements); | 1839 __ Move(rcx, constant_elements); |
1837 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 1840 FastCloneShallowArrayStub stub(isolate(), |
| 1841 mode, |
| 1842 allocation_site_mode, length); |
1838 __ CallStub(&stub); | 1843 __ CallStub(&stub); |
1839 } | 1844 } |
1840 | 1845 |
1841 bool result_saved = false; // Is the result saved to the stack? | 1846 bool result_saved = false; // Is the result saved to the stack? |
1842 | 1847 |
1843 // Emit code to evaluate all the non-constant subexpressions and to store | 1848 // Emit code to evaluate all the non-constant subexpressions and to store |
1844 // them into the newly cloned array. | 1849 // them into the newly cloned array. |
1845 for (int i = 0; i < length; i++) { | 1850 for (int i = 0; i < length; i++) { |
1846 Expression* subexpr = subexprs->at(i); | 1851 Expression* subexpr = subexprs->at(i); |
1847 // If the subexpression is a literal or a simple materialized literal it | 1852 // If the subexpression is a literal or a simple materialized literal it |
(...skipping 16 matching lines...) Expand all Loading... |
1864 // Store the subexpression value in the array's elements. | 1869 // Store the subexpression value in the array's elements. |
1865 __ movp(FieldOperand(rbx, offset), result_register()); | 1870 __ movp(FieldOperand(rbx, offset), result_register()); |
1866 // Update the write barrier for the array store. | 1871 // Update the write barrier for the array store. |
1867 __ RecordWriteField(rbx, offset, result_register(), rcx, | 1872 __ RecordWriteField(rbx, offset, result_register(), rcx, |
1868 kDontSaveFPRegs, | 1873 kDontSaveFPRegs, |
1869 EMIT_REMEMBERED_SET, | 1874 EMIT_REMEMBERED_SET, |
1870 INLINE_SMI_CHECK); | 1875 INLINE_SMI_CHECK); |
1871 } else { | 1876 } else { |
1872 // Store the subexpression value in the array's elements. | 1877 // Store the subexpression value in the array's elements. |
1873 __ Move(rcx, Smi::FromInt(i)); | 1878 __ Move(rcx, Smi::FromInt(i)); |
1874 StoreArrayLiteralElementStub stub; | 1879 StoreArrayLiteralElementStub stub(isolate()); |
1875 __ CallStub(&stub); | 1880 __ CallStub(&stub); |
1876 } | 1881 } |
1877 | 1882 |
1878 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); | 1883 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); |
1879 } | 1884 } |
1880 | 1885 |
1881 if (result_saved) { | 1886 if (result_saved) { |
1882 __ addp(rsp, Immediate(kPointerSize)); // literal index | 1887 __ addp(rsp, Immediate(kPointerSize)); // literal index |
1883 context()->PlugTOS(); | 1888 context()->PlugTOS(); |
1884 } else { | 1889 } else { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2114 __ Push(rax); // received | 2119 __ Push(rax); // received |
2115 | 2120 |
2116 // result = receiver[f](arg); | 2121 // result = receiver[f](arg); |
2117 __ bind(&l_call); | 2122 __ bind(&l_call); |
2118 __ movp(rdx, Operand(rsp, kPointerSize)); | 2123 __ movp(rdx, Operand(rsp, kPointerSize)); |
2119 __ movp(rax, Operand(rsp, 2 * kPointerSize)); | 2124 __ movp(rax, Operand(rsp, 2 * kPointerSize)); |
2120 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2125 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2121 CallIC(ic, TypeFeedbackId::None()); | 2126 CallIC(ic, TypeFeedbackId::None()); |
2122 __ movp(rdi, rax); | 2127 __ movp(rdi, rax); |
2123 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2128 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
2124 CallFunctionStub stub(1, CALL_AS_METHOD); | 2129 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2125 __ CallStub(&stub); | 2130 __ CallStub(&stub); |
2126 | 2131 |
2127 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2132 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2128 __ Drop(1); // The function is still on the stack; drop it. | 2133 __ Drop(1); // The function is still on the stack; drop it. |
2129 | 2134 |
2130 // if (!result.done) goto l_try; | 2135 // if (!result.done) goto l_try; |
2131 __ bind(&l_loop); | 2136 __ bind(&l_loop); |
2132 __ Push(rax); // save result | 2137 __ Push(rax); // save result |
2133 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" | 2138 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" |
2134 CallLoadIC(NOT_CONTEXTUAL); // result.done in rax | 2139 CallLoadIC(NOT_CONTEXTUAL); // result.done in rax |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2322 // rcx to make the shifts easier. | 2327 // rcx to make the shifts easier. |
2323 Label done, stub_call, smi_case; | 2328 Label done, stub_call, smi_case; |
2324 __ Pop(rdx); | 2329 __ Pop(rdx); |
2325 __ movp(rcx, rax); | 2330 __ movp(rcx, rax); |
2326 __ orp(rax, rdx); | 2331 __ orp(rax, rdx); |
2327 JumpPatchSite patch_site(masm_); | 2332 JumpPatchSite patch_site(masm_); |
2328 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 2333 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
2329 | 2334 |
2330 __ bind(&stub_call); | 2335 __ bind(&stub_call); |
2331 __ movp(rax, rcx); | 2336 __ movp(rax, rcx); |
2332 BinaryOpICStub stub(op, mode); | 2337 BinaryOpICStub stub(isolate(), op, mode); |
2333 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2338 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
2334 patch_site.EmitPatchInfo(); | 2339 patch_site.EmitPatchInfo(); |
2335 __ jmp(&done, Label::kNear); | 2340 __ jmp(&done, Label::kNear); |
2336 | 2341 |
2337 __ bind(&smi_case); | 2342 __ bind(&smi_case); |
2338 switch (op) { | 2343 switch (op) { |
2339 case Token::SAR: | 2344 case Token::SAR: |
2340 __ SmiShiftArithmeticRight(rax, rdx, rcx); | 2345 __ SmiShiftArithmeticRight(rax, rdx, rcx); |
2341 break; | 2346 break; |
2342 case Token::SHL: | 2347 case Token::SHL: |
(...skipping 27 matching lines...) Expand all Loading... |
2370 | 2375 |
2371 __ bind(&done); | 2376 __ bind(&done); |
2372 context()->Plug(rax); | 2377 context()->Plug(rax); |
2373 } | 2378 } |
2374 | 2379 |
2375 | 2380 |
2376 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2381 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2377 Token::Value op, | 2382 Token::Value op, |
2378 OverwriteMode mode) { | 2383 OverwriteMode mode) { |
2379 __ Pop(rdx); | 2384 __ Pop(rdx); |
2380 BinaryOpICStub stub(op, mode); | 2385 BinaryOpICStub stub(isolate(), op, mode); |
2381 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2386 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2382 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2387 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
2383 patch_site.EmitPatchInfo(); | 2388 patch_site.EmitPatchInfo(); |
2384 context()->Plug(rax); | 2389 context()->Plug(rax); |
2385 } | 2390 } |
2386 | 2391 |
2387 | 2392 |
2388 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2393 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2389 ASSERT(expr->IsValidReferenceExpression()); | 2394 ASSERT(expr->IsValidReferenceExpression()); |
2390 | 2395 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2610 | 2615 |
2611 // Load the arguments. | 2616 // Load the arguments. |
2612 { PreservePositionScope scope(masm()->positions_recorder()); | 2617 { PreservePositionScope scope(masm()->positions_recorder()); |
2613 for (int i = 0; i < arg_count; i++) { | 2618 for (int i = 0; i < arg_count; i++) { |
2614 VisitForStackValue(args->at(i)); | 2619 VisitForStackValue(args->at(i)); |
2615 } | 2620 } |
2616 } | 2621 } |
2617 | 2622 |
2618 // Record source position for debugger. | 2623 // Record source position for debugger. |
2619 SetSourcePosition(expr->position()); | 2624 SetSourcePosition(expr->position()); |
2620 CallFunctionStub stub(arg_count, flags); | 2625 CallFunctionStub stub(isolate(), arg_count, flags); |
2621 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2626 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2622 __ CallStub(&stub); | 2627 __ CallStub(&stub); |
2623 | 2628 |
2624 RecordJSReturnSite(expr); | 2629 RecordJSReturnSite(expr); |
2625 | 2630 |
2626 // Restore context register. | 2631 // Restore context register. |
2627 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2632 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2628 | 2633 |
2629 context()->DropAndPlug(1, rax); | 2634 context()->DropAndPlug(1, rax); |
2630 } | 2635 } |
(...skipping 21 matching lines...) Expand all Loading... |
2652 | 2657 |
2653 // Load the arguments. | 2658 // Load the arguments. |
2654 { PreservePositionScope scope(masm()->positions_recorder()); | 2659 { PreservePositionScope scope(masm()->positions_recorder()); |
2655 for (int i = 0; i < arg_count; i++) { | 2660 for (int i = 0; i < arg_count; i++) { |
2656 VisitForStackValue(args->at(i)); | 2661 VisitForStackValue(args->at(i)); |
2657 } | 2662 } |
2658 } | 2663 } |
2659 | 2664 |
2660 // Record source position for debugger. | 2665 // Record source position for debugger. |
2661 SetSourcePosition(expr->position()); | 2666 SetSourcePosition(expr->position()); |
2662 CallFunctionStub stub(arg_count, CALL_AS_METHOD); | 2667 CallFunctionStub stub(isolate(), arg_count, CALL_AS_METHOD); |
2663 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2668 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2664 __ CallStub(&stub); | 2669 __ CallStub(&stub); |
2665 | 2670 |
2666 RecordJSReturnSite(expr); | 2671 RecordJSReturnSite(expr); |
2667 // Restore context register. | 2672 // Restore context register. |
2668 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2673 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2669 | 2674 |
2670 context()->DropAndPlug(1, rax); | 2675 context()->DropAndPlug(1, rax); |
2671 } | 2676 } |
2672 | 2677 |
(...skipping 10 matching lines...) Expand all Loading... |
2683 // Record source position for debugger. | 2688 // Record source position for debugger. |
2684 SetSourcePosition(expr->position()); | 2689 SetSourcePosition(expr->position()); |
2685 | 2690 |
2686 Handle<Object> uninitialized = | 2691 Handle<Object> uninitialized = |
2687 TypeFeedbackInfo::UninitializedSentinel(isolate()); | 2692 TypeFeedbackInfo::UninitializedSentinel(isolate()); |
2688 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); | 2693 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); |
2689 __ Move(rbx, FeedbackVector()); | 2694 __ Move(rbx, FeedbackVector()); |
2690 __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot())); | 2695 __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot())); |
2691 | 2696 |
2692 // Record call targets in unoptimized code. | 2697 // Record call targets in unoptimized code. |
2693 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); | 2698 CallFunctionStub stub(isolate(), arg_count, RECORD_CALL_TARGET); |
2694 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2699 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2695 __ CallStub(&stub); | 2700 __ CallStub(&stub); |
2696 RecordJSReturnSite(expr); | 2701 RecordJSReturnSite(expr); |
2697 // Restore context register. | 2702 // Restore context register. |
2698 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2703 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2699 // Discard the function left on TOS. | 2704 // Discard the function left on TOS. |
2700 context()->DropAndPlug(1, rax); | 2705 context()->DropAndPlug(1, rax); |
2701 } | 2706 } |
2702 | 2707 |
2703 | 2708 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2755 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); | 2760 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); |
2756 EmitResolvePossiblyDirectEval(arg_count); | 2761 EmitResolvePossiblyDirectEval(arg_count); |
2757 | 2762 |
2758 // The runtime call returns a pair of values in rax (function) and | 2763 // The runtime call returns a pair of values in rax (function) and |
2759 // rdx (receiver). Touch up the stack with the right values. | 2764 // rdx (receiver). Touch up the stack with the right values. |
2760 __ movp(Operand(rsp, (arg_count + 0) * kPointerSize), rdx); | 2765 __ movp(Operand(rsp, (arg_count + 0) * kPointerSize), rdx); |
2761 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); | 2766 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); |
2762 } | 2767 } |
2763 // Record source position for debugger. | 2768 // Record source position for debugger. |
2764 SetSourcePosition(expr->position()); | 2769 SetSourcePosition(expr->position()); |
2765 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2770 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
2766 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2771 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2767 __ CallStub(&stub); | 2772 __ CallStub(&stub); |
2768 RecordJSReturnSite(expr); | 2773 RecordJSReturnSite(expr); |
2769 // Restore context register. | 2774 // Restore context register. |
2770 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2775 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2771 context()->DropAndPlug(1, rax); | 2776 context()->DropAndPlug(1, rax); |
2772 } else if (call_type == Call::GLOBAL_CALL) { | 2777 } else if (call_type == Call::GLOBAL_CALL) { |
2773 EmitCallWithIC(expr); | 2778 EmitCallWithIC(expr); |
2774 | 2779 |
2775 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2780 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2869 if (FLAG_pretenuring_call_new) { | 2874 if (FLAG_pretenuring_call_new) { |
2870 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), | 2875 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), |
2871 isolate()->factory()->NewAllocationSite()); | 2876 isolate()->factory()->NewAllocationSite()); |
2872 ASSERT(expr->AllocationSiteFeedbackSlot() == | 2877 ASSERT(expr->AllocationSiteFeedbackSlot() == |
2873 expr->CallNewFeedbackSlot() + 1); | 2878 expr->CallNewFeedbackSlot() + 1); |
2874 } | 2879 } |
2875 | 2880 |
2876 __ Move(rbx, FeedbackVector()); | 2881 __ Move(rbx, FeedbackVector()); |
2877 __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot())); | 2882 __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot())); |
2878 | 2883 |
2879 CallConstructStub stub(RECORD_CALL_TARGET); | 2884 CallConstructStub stub(isolate(), RECORD_CALL_TARGET); |
2880 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 2885 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |
2881 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2886 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2882 context()->Plug(rax); | 2887 context()->Plug(rax); |
2883 } | 2888 } |
2884 | 2889 |
2885 | 2890 |
2886 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2891 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2887 ZoneList<Expression*>* args = expr->arguments(); | 2892 ZoneList<Expression*>* args = expr->arguments(); |
2888 ASSERT(args->length() == 1); | 2893 ASSERT(args->length() == 1); |
2889 | 2894 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3241 | 3246 |
3242 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { | 3247 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
3243 ZoneList<Expression*>* args = expr->arguments(); | 3248 ZoneList<Expression*>* args = expr->arguments(); |
3244 ASSERT(args->length() == 1); | 3249 ASSERT(args->length() == 1); |
3245 | 3250 |
3246 // ArgumentsAccessStub expects the key in rdx and the formal | 3251 // ArgumentsAccessStub expects the key in rdx and the formal |
3247 // parameter count in rax. | 3252 // parameter count in rax. |
3248 VisitForAccumulatorValue(args->at(0)); | 3253 VisitForAccumulatorValue(args->at(0)); |
3249 __ movp(rdx, rax); | 3254 __ movp(rdx, rax); |
3250 __ Move(rax, Smi::FromInt(info_->scope()->num_parameters())); | 3255 __ Move(rax, Smi::FromInt(info_->scope()->num_parameters())); |
3251 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 3256 ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); |
3252 __ CallStub(&stub); | 3257 __ CallStub(&stub); |
3253 context()->Plug(rax); | 3258 context()->Plug(rax); |
3254 } | 3259 } |
3255 | 3260 |
3256 | 3261 |
3257 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { | 3262 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
3258 ASSERT(expr->arguments()->length() == 0); | 3263 ASSERT(expr->arguments()->length() == 0); |
3259 | 3264 |
3260 Label exit; | 3265 Label exit; |
3261 // Get the number of formal parameters. | 3266 // Get the number of formal parameters. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3354 __ CallRuntime(Runtime::kHiddenLog, 2); | 3359 __ CallRuntime(Runtime::kHiddenLog, 2); |
3355 } | 3360 } |
3356 // Finally, we're expected to leave a value on the top of the stack. | 3361 // Finally, we're expected to leave a value on the top of the stack. |
3357 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 3362 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
3358 context()->Plug(rax); | 3363 context()->Plug(rax); |
3359 } | 3364 } |
3360 | 3365 |
3361 | 3366 |
3362 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3367 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
3363 // Load the arguments on the stack and call the stub. | 3368 // Load the arguments on the stack and call the stub. |
3364 SubStringStub stub; | 3369 SubStringStub stub(isolate()); |
3365 ZoneList<Expression*>* args = expr->arguments(); | 3370 ZoneList<Expression*>* args = expr->arguments(); |
3366 ASSERT(args->length() == 3); | 3371 ASSERT(args->length() == 3); |
3367 VisitForStackValue(args->at(0)); | 3372 VisitForStackValue(args->at(0)); |
3368 VisitForStackValue(args->at(1)); | 3373 VisitForStackValue(args->at(1)); |
3369 VisitForStackValue(args->at(2)); | 3374 VisitForStackValue(args->at(2)); |
3370 __ CallStub(&stub); | 3375 __ CallStub(&stub); |
3371 context()->Plug(rax); | 3376 context()->Plug(rax); |
3372 } | 3377 } |
3373 | 3378 |
3374 | 3379 |
3375 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | 3380 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
3376 // Load the arguments on the stack and call the stub. | 3381 // Load the arguments on the stack and call the stub. |
3377 RegExpExecStub stub; | 3382 RegExpExecStub stub(isolate()); |
3378 ZoneList<Expression*>* args = expr->arguments(); | 3383 ZoneList<Expression*>* args = expr->arguments(); |
3379 ASSERT(args->length() == 4); | 3384 ASSERT(args->length() == 4); |
3380 VisitForStackValue(args->at(0)); | 3385 VisitForStackValue(args->at(0)); |
3381 VisitForStackValue(args->at(1)); | 3386 VisitForStackValue(args->at(1)); |
3382 VisitForStackValue(args->at(2)); | 3387 VisitForStackValue(args->at(2)); |
3383 VisitForStackValue(args->at(3)); | 3388 VisitForStackValue(args->at(3)); |
3384 __ CallStub(&stub); | 3389 __ CallStub(&stub); |
3385 context()->Plug(rax); | 3390 context()->Plug(rax); |
3386 } | 3391 } |
3387 | 3392 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3517 context()->Plug(rax); | 3522 context()->Plug(rax); |
3518 } | 3523 } |
3519 | 3524 |
3520 | 3525 |
3521 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { | 3526 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
3522 // Load the arguments on the stack and call the runtime function. | 3527 // Load the arguments on the stack and call the runtime function. |
3523 ZoneList<Expression*>* args = expr->arguments(); | 3528 ZoneList<Expression*>* args = expr->arguments(); |
3524 ASSERT(args->length() == 2); | 3529 ASSERT(args->length() == 2); |
3525 VisitForStackValue(args->at(0)); | 3530 VisitForStackValue(args->at(0)); |
3526 VisitForStackValue(args->at(1)); | 3531 VisitForStackValue(args->at(1)); |
3527 MathPowStub stub(MathPowStub::ON_STACK); | 3532 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
3528 __ CallStub(&stub); | 3533 __ CallStub(&stub); |
3529 context()->Plug(rax); | 3534 context()->Plug(rax); |
3530 } | 3535 } |
3531 | 3536 |
3532 | 3537 |
3533 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3538 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
3534 ZoneList<Expression*>* args = expr->arguments(); | 3539 ZoneList<Expression*>* args = expr->arguments(); |
3535 ASSERT(args->length() == 2); | 3540 ASSERT(args->length() == 2); |
3536 | 3541 |
3537 VisitForStackValue(args->at(0)); // Load the object. | 3542 VisitForStackValue(args->at(0)); // Load the object. |
(...skipping 20 matching lines...) Expand all Loading... |
3558 } | 3563 } |
3559 | 3564 |
3560 | 3565 |
3561 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { | 3566 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
3562 ZoneList<Expression*>* args = expr->arguments(); | 3567 ZoneList<Expression*>* args = expr->arguments(); |
3563 ASSERT_EQ(args->length(), 1); | 3568 ASSERT_EQ(args->length(), 1); |
3564 | 3569 |
3565 // Load the argument into rax and call the stub. | 3570 // Load the argument into rax and call the stub. |
3566 VisitForAccumulatorValue(args->at(0)); | 3571 VisitForAccumulatorValue(args->at(0)); |
3567 | 3572 |
3568 NumberToStringStub stub; | 3573 NumberToStringStub stub(isolate()); |
3569 __ CallStub(&stub); | 3574 __ CallStub(&stub); |
3570 context()->Plug(rax); | 3575 context()->Plug(rax); |
3571 } | 3576 } |
3572 | 3577 |
3573 | 3578 |
3574 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 3579 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
3575 ZoneList<Expression*>* args = expr->arguments(); | 3580 ZoneList<Expression*>* args = expr->arguments(); |
3576 ASSERT(args->length() == 1); | 3581 ASSERT(args->length() == 1); |
3577 | 3582 |
3578 VisitForAccumulatorValue(args->at(0)); | 3583 VisitForAccumulatorValue(args->at(0)); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3684 } | 3689 } |
3685 | 3690 |
3686 | 3691 |
3687 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { | 3692 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
3688 ZoneList<Expression*>* args = expr->arguments(); | 3693 ZoneList<Expression*>* args = expr->arguments(); |
3689 ASSERT_EQ(2, args->length()); | 3694 ASSERT_EQ(2, args->length()); |
3690 VisitForStackValue(args->at(0)); | 3695 VisitForStackValue(args->at(0)); |
3691 VisitForAccumulatorValue(args->at(1)); | 3696 VisitForAccumulatorValue(args->at(1)); |
3692 | 3697 |
3693 __ Pop(rdx); | 3698 __ Pop(rdx); |
3694 StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED); | 3699 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
3695 __ CallStub(&stub); | 3700 __ CallStub(&stub); |
3696 context()->Plug(rax); | 3701 context()->Plug(rax); |
3697 } | 3702 } |
3698 | 3703 |
3699 | 3704 |
3700 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { | 3705 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
3701 ZoneList<Expression*>* args = expr->arguments(); | 3706 ZoneList<Expression*>* args = expr->arguments(); |
3702 ASSERT_EQ(2, args->length()); | 3707 ASSERT_EQ(2, args->length()); |
3703 | 3708 |
3704 VisitForStackValue(args->at(0)); | 3709 VisitForStackValue(args->at(0)); |
3705 VisitForStackValue(args->at(1)); | 3710 VisitForStackValue(args->at(1)); |
3706 | 3711 |
3707 StringCompareStub stub; | 3712 StringCompareStub stub(isolate()); |
3708 __ CallStub(&stub); | 3713 __ CallStub(&stub); |
3709 context()->Plug(rax); | 3714 context()->Plug(rax); |
3710 } | 3715 } |
3711 | 3716 |
3712 | 3717 |
3713 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 3718 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
3714 ZoneList<Expression*>* args = expr->arguments(); | 3719 ZoneList<Expression*>* args = expr->arguments(); |
3715 ASSERT(args->length() >= 2); | 3720 ASSERT(args->length() >= 2); |
3716 | 3721 |
3717 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3722 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
(...skipping 18 matching lines...) Expand all Loading... |
3736 __ bind(&runtime); | 3741 __ bind(&runtime); |
3737 __ Push(rax); | 3742 __ Push(rax); |
3738 __ CallRuntime(Runtime::kCall, args->length()); | 3743 __ CallRuntime(Runtime::kCall, args->length()); |
3739 __ bind(&done); | 3744 __ bind(&done); |
3740 | 3745 |
3741 context()->Plug(rax); | 3746 context()->Plug(rax); |
3742 } | 3747 } |
3743 | 3748 |
3744 | 3749 |
3745 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { | 3750 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
3746 RegExpConstructResultStub stub; | 3751 RegExpConstructResultStub stub(isolate()); |
3747 ZoneList<Expression*>* args = expr->arguments(); | 3752 ZoneList<Expression*>* args = expr->arguments(); |
3748 ASSERT(args->length() == 3); | 3753 ASSERT(args->length() == 3); |
3749 VisitForStackValue(args->at(0)); | 3754 VisitForStackValue(args->at(0)); |
3750 VisitForStackValue(args->at(1)); | 3755 VisitForStackValue(args->at(1)); |
3751 VisitForAccumulatorValue(args->at(2)); | 3756 VisitForAccumulatorValue(args->at(2)); |
3752 __ Pop(rbx); | 3757 __ Pop(rbx); |
3753 __ Pop(rcx); | 3758 __ Pop(rcx); |
3754 __ CallStub(&stub); | 3759 __ CallStub(&stub); |
3755 context()->Plug(rax); | 3760 context()->Plug(rax); |
3756 } | 3761 } |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4162 __ Push(Operand(rsp, 0)); | 4167 __ Push(Operand(rsp, 0)); |
4163 __ movp(Operand(rsp, kPointerSize), rax); | 4168 __ movp(Operand(rsp, kPointerSize), rax); |
4164 | 4169 |
4165 // Push the arguments ("left-to-right"). | 4170 // Push the arguments ("left-to-right"). |
4166 for (int i = 0; i < arg_count; i++) { | 4171 for (int i = 0; i < arg_count; i++) { |
4167 VisitForStackValue(args->at(i)); | 4172 VisitForStackValue(args->at(i)); |
4168 } | 4173 } |
4169 | 4174 |
4170 // Record source position of the IC call. | 4175 // Record source position of the IC call. |
4171 SetSourcePosition(expr->position()); | 4176 SetSourcePosition(expr->position()); |
4172 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 4177 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
4173 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 4178 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
4174 __ CallStub(&stub); | 4179 __ CallStub(&stub); |
4175 | 4180 |
4176 // Restore context register. | 4181 // Restore context register. |
4177 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4182 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
4178 context()->DropAndPlug(1, rax); | 4183 context()->DropAndPlug(1, rax); |
4179 | 4184 |
4180 } else { | 4185 } else { |
4181 // Push the arguments ("left-to-right"). | 4186 // Push the arguments ("left-to-right"). |
4182 for (int i = 0; i < arg_count; i++) { | 4187 for (int i = 0; i < arg_count; i++) { |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4385 mode.Add(BAILOUT_ON_NO_OVERFLOW); | 4390 mode.Add(BAILOUT_ON_NO_OVERFLOW); |
4386 if (expr->op() == Token::INC) { | 4391 if (expr->op() == Token::INC) { |
4387 __ SmiAddConstant(rax, rax, Smi::FromInt(1), mode, &done, Label::kNear); | 4392 __ SmiAddConstant(rax, rax, Smi::FromInt(1), mode, &done, Label::kNear); |
4388 } else { | 4393 } else { |
4389 __ SmiSubConstant(rax, rax, Smi::FromInt(1), mode, &done, Label::kNear); | 4394 __ SmiSubConstant(rax, rax, Smi::FromInt(1), mode, &done, Label::kNear); |
4390 } | 4395 } |
4391 __ jmp(&stub_call, Label::kNear); | 4396 __ jmp(&stub_call, Label::kNear); |
4392 __ bind(&slow); | 4397 __ bind(&slow); |
4393 } | 4398 } |
4394 | 4399 |
4395 ToNumberStub convert_stub; | 4400 ToNumberStub convert_stub(isolate()); |
4396 __ CallStub(&convert_stub); | 4401 __ CallStub(&convert_stub); |
4397 | 4402 |
4398 // Save result for postfix expressions. | 4403 // Save result for postfix expressions. |
4399 if (expr->is_postfix()) { | 4404 if (expr->is_postfix()) { |
4400 if (!context()->IsEffect()) { | 4405 if (!context()->IsEffect()) { |
4401 // Save the result on the stack. If we have a named or keyed property | 4406 // Save the result on the stack. If we have a named or keyed property |
4402 // we store the result under the receiver that is currently on top | 4407 // we store the result under the receiver that is currently on top |
4403 // of the stack. | 4408 // of the stack. |
4404 switch (assign_type) { | 4409 switch (assign_type) { |
4405 case VARIABLE: | 4410 case VARIABLE: |
4406 __ Push(rax); | 4411 __ Push(rax); |
4407 break; | 4412 break; |
4408 case NAMED_PROPERTY: | 4413 case NAMED_PROPERTY: |
4409 __ movp(Operand(rsp, kPointerSize), rax); | 4414 __ movp(Operand(rsp, kPointerSize), rax); |
4410 break; | 4415 break; |
4411 case KEYED_PROPERTY: | 4416 case KEYED_PROPERTY: |
4412 __ movp(Operand(rsp, 2 * kPointerSize), rax); | 4417 __ movp(Operand(rsp, 2 * kPointerSize), rax); |
4413 break; | 4418 break; |
4414 } | 4419 } |
4415 } | 4420 } |
4416 } | 4421 } |
4417 | 4422 |
4418 // Record position before stub call. | 4423 // Record position before stub call. |
4419 SetSourcePosition(expr->position()); | 4424 SetSourcePosition(expr->position()); |
4420 | 4425 |
4421 // Call stub for +1/-1. | 4426 // Call stub for +1/-1. |
4422 __ bind(&stub_call); | 4427 __ bind(&stub_call); |
4423 __ movp(rdx, rax); | 4428 __ movp(rdx, rax); |
4424 __ Move(rax, Smi::FromInt(1)); | 4429 __ Move(rax, Smi::FromInt(1)); |
4425 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); | 4430 BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); |
4426 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); | 4431 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); |
4427 patch_site.EmitPatchInfo(); | 4432 patch_site.EmitPatchInfo(); |
4428 __ bind(&done); | 4433 __ bind(&done); |
4429 | 4434 |
4430 // Store the value returned in rax. | 4435 // Store the value returned in rax. |
4431 switch (assign_type) { | 4436 switch (assign_type) { |
4432 case VARIABLE: | 4437 case VARIABLE: |
4433 if (expr->is_postfix()) { | 4438 if (expr->is_postfix()) { |
4434 // Perform the assignment as if via '='. | 4439 // Perform the assignment as if via '='. |
4435 { EffectContext context(this); | 4440 { EffectContext context(this); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4625 case Token::IN: | 4630 case Token::IN: |
4626 VisitForStackValue(expr->right()); | 4631 VisitForStackValue(expr->right()); |
4627 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4632 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
4628 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 4633 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
4629 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 4634 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
4630 Split(equal, if_true, if_false, fall_through); | 4635 Split(equal, if_true, if_false, fall_through); |
4631 break; | 4636 break; |
4632 | 4637 |
4633 case Token::INSTANCEOF: { | 4638 case Token::INSTANCEOF: { |
4634 VisitForStackValue(expr->right()); | 4639 VisitForStackValue(expr->right()); |
4635 InstanceofStub stub(InstanceofStub::kNoFlags); | 4640 InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); |
4636 __ CallStub(&stub); | 4641 __ CallStub(&stub); |
4637 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4642 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4638 __ testp(rax, rax); | 4643 __ testp(rax, rax); |
4639 // The stub returns 0 for true. | 4644 // The stub returns 0 for true. |
4640 Split(zero, if_true, if_false, fall_through); | 4645 Split(zero, if_true, if_false, fall_through); |
4641 break; | 4646 break; |
4642 } | 4647 } |
4643 | 4648 |
4644 default: { | 4649 default: { |
4645 VisitForAccumulatorValue(expr->right()); | 4650 VisitForAccumulatorValue(expr->right()); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4924 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4929 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4925 Assembler::target_address_at(call_target_address, | 4930 Assembler::target_address_at(call_target_address, |
4926 unoptimized_code)); | 4931 unoptimized_code)); |
4927 return OSR_AFTER_STACK_CHECK; | 4932 return OSR_AFTER_STACK_CHECK; |
4928 } | 4933 } |
4929 | 4934 |
4930 | 4935 |
4931 } } // namespace v8::internal | 4936 } } // namespace v8::internal |
4932 | 4937 |
4933 #endif // V8_TARGET_ARCH_X64 | 4938 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |