| 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 |