| 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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 // Possibly allocate a local context. | 235 // Possibly allocate a local context. |
| 236 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 236 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 237 if (heap_slots > 0) { | 237 if (heap_slots > 0) { |
| 238 // Argument to NewContext is the function, which is still in r1. | 238 // Argument to NewContext is the function, which is still in r1. |
| 239 Comment cmnt(masm_, "[ Allocate context"); | 239 Comment cmnt(masm_, "[ Allocate context"); |
| 240 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 240 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
| 241 __ push(r1); | 241 __ push(r1); |
| 242 __ Push(info->scope()->GetScopeInfo()); | 242 __ Push(info->scope()->GetScopeInfo()); |
| 243 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 243 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
| 244 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 244 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 245 FastNewContextStub stub(heap_slots); | 245 FastNewContextStub stub(isolate(), heap_slots); |
| 246 __ CallStub(&stub); | 246 __ CallStub(&stub); |
| 247 } else { | 247 } else { |
| 248 __ push(r1); | 248 __ push(r1); |
| 249 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 249 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
| 250 } | 250 } |
| 251 function_in_register = false; | 251 function_in_register = false; |
| 252 // Context is returned in r0. It replaces the context passed to us. | 252 // Context is returned in r0. It replaces the context passed to us. |
| 253 // It's saved in the stack and kept live in cp. | 253 // It's saved in the stack and kept live in cp. |
| 254 __ mov(cp, r0); | 254 __ mov(cp, r0); |
| 255 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 255 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 // The stub will rewrite receiever and parameter count if the previous | 296 // The stub will rewrite receiever and parameter count if the previous |
| 297 // stack frame was an arguments adapter frame. | 297 // stack frame was an arguments adapter frame. |
| 298 ArgumentsAccessStub::Type type; | 298 ArgumentsAccessStub::Type type; |
| 299 if (strict_mode() == STRICT) { | 299 if (strict_mode() == STRICT) { |
| 300 type = ArgumentsAccessStub::NEW_STRICT; | 300 type = ArgumentsAccessStub::NEW_STRICT; |
| 301 } else if (function()->has_duplicate_parameters()) { | 301 } else if (function()->has_duplicate_parameters()) { |
| 302 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 302 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
| 303 } else { | 303 } else { |
| 304 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 304 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
| 305 } | 305 } |
| 306 ArgumentsAccessStub stub(type); | 306 ArgumentsAccessStub stub(isolate(), type); |
| 307 __ CallStub(&stub); | 307 __ CallStub(&stub); |
| 308 | 308 |
| 309 SetVar(arguments, r0, r1, r2); | 309 SetVar(arguments, r0, r1, r2); |
| 310 } | 310 } |
| 311 | 311 |
| 312 if (FLAG_trace) { | 312 if (FLAG_trace) { |
| 313 __ CallRuntime(Runtime::kTraceEnter, 0); | 313 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 314 } | 314 } |
| 315 | 315 |
| 316 // Visit the declarations and body unless there is an illegal | 316 // Visit the declarations and body unless there is an illegal |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 // space for nested functions that don't need literals cloning. If | 1350 // space for nested functions that don't need literals cloning. If |
| 1351 // we're running with the --always-opt or the --prepare-always-opt | 1351 // we're running with the --always-opt or the --prepare-always-opt |
| 1352 // flag, we need to use the runtime function so that the new function | 1352 // flag, we need to use the runtime function so that the new function |
| 1353 // we are creating here gets a chance to have its code optimized and | 1353 // we are creating here gets a chance to have its code optimized and |
| 1354 // doesn't just get a copy of the existing unoptimized code. | 1354 // doesn't just get a copy of the existing unoptimized code. |
| 1355 if (!FLAG_always_opt && | 1355 if (!FLAG_always_opt && |
| 1356 !FLAG_prepare_always_opt && | 1356 !FLAG_prepare_always_opt && |
| 1357 !pretenure && | 1357 !pretenure && |
| 1358 scope()->is_function_scope() && | 1358 scope()->is_function_scope() && |
| 1359 info->num_literals() == 0) { | 1359 info->num_literals() == 0) { |
| 1360 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1360 FastNewClosureStub stub(isolate(), |
| 1361 info->strict_mode(), |
| 1362 info->is_generator()); |
| 1361 __ mov(r2, Operand(info)); | 1363 __ mov(r2, Operand(info)); |
| 1362 __ CallStub(&stub); | 1364 __ CallStub(&stub); |
| 1363 } else { | 1365 } else { |
| 1364 __ mov(r0, Operand(info)); | 1366 __ mov(r0, Operand(info)); |
| 1365 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1367 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
| 1366 : Heap::kFalseValueRootIndex); | 1368 : Heap::kFalseValueRootIndex); |
| 1367 __ Push(cp, r0, r1); | 1369 __ Push(cp, r0, r1); |
| 1368 __ CallRuntime(Runtime::kHiddenNewClosure, 3); | 1370 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
| 1369 } | 1371 } |
| 1370 context()->Plug(r0); | 1372 context()->Plug(r0); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 ? ObjectLiteral::kHasFunction | 1678 ? ObjectLiteral::kHasFunction |
| 1677 : ObjectLiteral::kNoFlags; | 1679 : ObjectLiteral::kNoFlags; |
| 1678 __ mov(r0, Operand(Smi::FromInt(flags))); | 1680 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1679 int properties_count = constant_properties->length() / 2; | 1681 int properties_count = constant_properties->length() / 2; |
| 1680 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || | 1682 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || |
| 1681 flags != ObjectLiteral::kFastElements || | 1683 flags != ObjectLiteral::kFastElements || |
| 1682 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1684 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1683 __ Push(r3, r2, r1, r0); | 1685 __ Push(r3, r2, r1, r0); |
| 1684 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); | 1686 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
| 1685 } else { | 1687 } else { |
| 1686 FastCloneShallowObjectStub stub(properties_count); | 1688 FastCloneShallowObjectStub stub(isolate(), properties_count); |
| 1687 __ CallStub(&stub); | 1689 __ CallStub(&stub); |
| 1688 } | 1690 } |
| 1689 | 1691 |
| 1690 // If result_saved is true the result is on top of the stack. If | 1692 // If result_saved is true the result is on top of the stack. If |
| 1691 // result_saved is false the result is in r0. | 1693 // result_saved is false the result is in r0. |
| 1692 bool result_saved = false; | 1694 bool result_saved = false; |
| 1693 | 1695 |
| 1694 // Mark all computed expressions that are bound to a key that | 1696 // Mark all computed expressions that are bound to a key that |
| 1695 // is shadowed by a later occurrence of the same key. For the | 1697 // is shadowed by a later occurrence of the same key. For the |
| 1696 // marked expressions, no store code is emitted. | 1698 // marked expressions, no store code is emitted. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1815 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; | 1817 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; |
| 1816 } | 1818 } |
| 1817 | 1819 |
| 1818 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1820 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1819 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1821 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
| 1820 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1822 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1821 __ mov(r1, Operand(constant_elements)); | 1823 __ mov(r1, Operand(constant_elements)); |
| 1822 if (has_fast_elements && constant_elements_values->map() == | 1824 if (has_fast_elements && constant_elements_values->map() == |
| 1823 isolate()->heap()->fixed_cow_array_map()) { | 1825 isolate()->heap()->fixed_cow_array_map()) { |
| 1824 FastCloneShallowArrayStub stub( | 1826 FastCloneShallowArrayStub stub( |
| 1827 isolate(), |
| 1825 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1828 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1826 allocation_site_mode, | 1829 allocation_site_mode, |
| 1827 length); | 1830 length); |
| 1828 __ CallStub(&stub); | 1831 __ CallStub(&stub); |
| 1829 __ IncrementCounter( | 1832 __ IncrementCounter( |
| 1830 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); | 1833 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); |
| 1831 } else if (expr->depth() > 1 || Serializer::enabled() || | 1834 } else if (expr->depth() > 1 || Serializer::enabled() || |
| 1832 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1835 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1833 __ mov(r0, Operand(Smi::FromInt(flags))); | 1836 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1834 __ Push(r3, r2, r1, r0); | 1837 __ Push(r3, r2, r1, r0); |
| 1835 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); | 1838 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
| 1836 } else { | 1839 } else { |
| 1837 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1840 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1838 FLAG_smi_only_arrays); | 1841 FLAG_smi_only_arrays); |
| 1839 FastCloneShallowArrayStub::Mode mode = | 1842 FastCloneShallowArrayStub::Mode mode = |
| 1840 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1843 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
| 1841 | 1844 |
| 1842 if (has_fast_elements) { | 1845 if (has_fast_elements) { |
| 1843 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1846 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
| 1844 } | 1847 } |
| 1845 | 1848 |
| 1846 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 1849 FastCloneShallowArrayStub stub(isolate(), mode, allocation_site_mode, |
| 1850 length); |
| 1847 __ CallStub(&stub); | 1851 __ CallStub(&stub); |
| 1848 } | 1852 } |
| 1849 | 1853 |
| 1850 bool result_saved = false; // Is the result saved to the stack? | 1854 bool result_saved = false; // Is the result saved to the stack? |
| 1851 | 1855 |
| 1852 // Emit code to evaluate all the non-constant subexpressions and to store | 1856 // Emit code to evaluate all the non-constant subexpressions and to store |
| 1853 // them into the newly cloned array. | 1857 // them into the newly cloned array. |
| 1854 for (int i = 0; i < length; i++) { | 1858 for (int i = 0; i < length; i++) { |
| 1855 Expression* subexpr = subexprs->at(i); | 1859 Expression* subexpr = subexprs->at(i); |
| 1856 // If the subexpression is a literal or a simple materialized literal it | 1860 // If the subexpression is a literal or a simple materialized literal it |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1868 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 1872 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
| 1869 __ ldr(r6, MemOperand(sp, kPointerSize)); // Copy of array literal. | 1873 __ ldr(r6, MemOperand(sp, kPointerSize)); // Copy of array literal. |
| 1870 __ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset)); | 1874 __ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset)); |
| 1871 __ str(result_register(), FieldMemOperand(r1, offset)); | 1875 __ str(result_register(), FieldMemOperand(r1, offset)); |
| 1872 // Update the write barrier for the array store. | 1876 // Update the write barrier for the array store. |
| 1873 __ RecordWriteField(r1, offset, result_register(), r2, | 1877 __ RecordWriteField(r1, offset, result_register(), r2, |
| 1874 kLRHasBeenSaved, kDontSaveFPRegs, | 1878 kLRHasBeenSaved, kDontSaveFPRegs, |
| 1875 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); | 1879 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); |
| 1876 } else { | 1880 } else { |
| 1877 __ mov(r3, Operand(Smi::FromInt(i))); | 1881 __ mov(r3, Operand(Smi::FromInt(i))); |
| 1878 StoreArrayLiteralElementStub stub; | 1882 StoreArrayLiteralElementStub stub(isolate()); |
| 1879 __ CallStub(&stub); | 1883 __ CallStub(&stub); |
| 1880 } | 1884 } |
| 1881 | 1885 |
| 1882 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); | 1886 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); |
| 1883 } | 1887 } |
| 1884 | 1888 |
| 1885 if (result_saved) { | 1889 if (result_saved) { |
| 1886 __ pop(); // literal index | 1890 __ pop(); // literal index |
| 1887 context()->PlugTOS(); | 1891 context()->PlugTOS(); |
| 1888 } else { | 1892 } else { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2113 __ Push(r2, r3, r0); // "next", iter, received | 2117 __ Push(r2, r3, r0); // "next", iter, received |
| 2114 | 2118 |
| 2115 // result = receiver[f](arg); | 2119 // result = receiver[f](arg); |
| 2116 __ bind(&l_call); | 2120 __ bind(&l_call); |
| 2117 __ ldr(r1, MemOperand(sp, kPointerSize)); | 2121 __ ldr(r1, MemOperand(sp, kPointerSize)); |
| 2118 __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); | 2122 __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); |
| 2119 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2123 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2120 CallIC(ic, TypeFeedbackId::None()); | 2124 CallIC(ic, TypeFeedbackId::None()); |
| 2121 __ mov(r1, r0); | 2125 __ mov(r1, r0); |
| 2122 __ str(r1, MemOperand(sp, 2 * kPointerSize)); | 2126 __ str(r1, MemOperand(sp, 2 * kPointerSize)); |
| 2123 CallFunctionStub stub(1, CALL_AS_METHOD); | 2127 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2124 __ CallStub(&stub); | 2128 __ CallStub(&stub); |
| 2125 | 2129 |
| 2126 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2130 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2127 __ Drop(1); // The function is still on the stack; drop it. | 2131 __ Drop(1); // The function is still on the stack; drop it. |
| 2128 | 2132 |
| 2129 // if (!result.done) goto l_try; | 2133 // if (!result.done) goto l_try; |
| 2130 __ bind(&l_loop); | 2134 __ bind(&l_loop); |
| 2131 __ push(r0); // save result | 2135 __ push(r0); // save result |
| 2132 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" | 2136 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" |
| 2133 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 | 2137 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2342 Register right = r0; | 2346 Register right = r0; |
| 2343 __ pop(left); | 2347 __ pop(left); |
| 2344 | 2348 |
| 2345 // Perform combined smi check on both operands. | 2349 // Perform combined smi check on both operands. |
| 2346 __ orr(scratch1, left, Operand(right)); | 2350 __ orr(scratch1, left, Operand(right)); |
| 2347 STATIC_ASSERT(kSmiTag == 0); | 2351 STATIC_ASSERT(kSmiTag == 0); |
| 2348 JumpPatchSite patch_site(masm_); | 2352 JumpPatchSite patch_site(masm_); |
| 2349 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2353 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 2350 | 2354 |
| 2351 __ bind(&stub_call); | 2355 __ bind(&stub_call); |
| 2352 BinaryOpICStub stub(op, mode); | 2356 BinaryOpICStub stub(isolate(), op, mode); |
| 2353 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2357 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
| 2354 patch_site.EmitPatchInfo(); | 2358 patch_site.EmitPatchInfo(); |
| 2355 __ jmp(&done); | 2359 __ jmp(&done); |
| 2356 | 2360 |
| 2357 __ bind(&smi_case); | 2361 __ bind(&smi_case); |
| 2358 // Smi case. This code works the same way as the smi-smi case in the type | 2362 // Smi case. This code works the same way as the smi-smi case in the type |
| 2359 // recording binary operation stub, see | 2363 // recording binary operation stub, see |
| 2360 switch (op) { | 2364 switch (op) { |
| 2361 case Token::SAR: | 2365 case Token::SAR: |
| 2362 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2366 __ GetLeastBitsFromSmi(scratch1, right, 5); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2418 | 2422 |
| 2419 __ bind(&done); | 2423 __ bind(&done); |
| 2420 context()->Plug(r0); | 2424 context()->Plug(r0); |
| 2421 } | 2425 } |
| 2422 | 2426 |
| 2423 | 2427 |
| 2424 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2428 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2425 Token::Value op, | 2429 Token::Value op, |
| 2426 OverwriteMode mode) { | 2430 OverwriteMode mode) { |
| 2427 __ pop(r1); | 2431 __ pop(r1); |
| 2428 BinaryOpICStub stub(op, mode); | 2432 BinaryOpICStub stub(isolate(), op, mode); |
| 2429 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2433 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2430 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2434 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
| 2431 patch_site.EmitPatchInfo(); | 2435 patch_site.EmitPatchInfo(); |
| 2432 context()->Plug(r0); | 2436 context()->Plug(r0); |
| 2433 } | 2437 } |
| 2434 | 2438 |
| 2435 | 2439 |
| 2436 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2440 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2437 ASSERT(expr->IsValidReferenceExpression()); | 2441 ASSERT(expr->IsValidReferenceExpression()); |
| 2438 | 2442 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2665 | 2669 |
| 2666 // Load the arguments. | 2670 // Load the arguments. |
| 2667 { PreservePositionScope scope(masm()->positions_recorder()); | 2671 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2668 for (int i = 0; i < arg_count; i++) { | 2672 for (int i = 0; i < arg_count; i++) { |
| 2669 VisitForStackValue(args->at(i)); | 2673 VisitForStackValue(args->at(i)); |
| 2670 } | 2674 } |
| 2671 } | 2675 } |
| 2672 | 2676 |
| 2673 // Record source position for debugger. | 2677 // Record source position for debugger. |
| 2674 SetSourcePosition(expr->position()); | 2678 SetSourcePosition(expr->position()); |
| 2675 CallFunctionStub stub(arg_count, flags); | 2679 CallFunctionStub stub(isolate(), arg_count, flags); |
| 2676 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2680 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2677 __ CallStub(&stub); | 2681 __ CallStub(&stub); |
| 2678 | 2682 |
| 2679 RecordJSReturnSite(expr); | 2683 RecordJSReturnSite(expr); |
| 2680 | 2684 |
| 2681 // Restore context register. | 2685 // Restore context register. |
| 2682 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2686 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2683 | 2687 |
| 2684 context()->DropAndPlug(1, r0); | 2688 context()->DropAndPlug(1, r0); |
| 2685 } | 2689 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2707 __ str(r0, MemOperand(sp, kPointerSize)); | 2711 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2708 | 2712 |
| 2709 { PreservePositionScope scope(masm()->positions_recorder()); | 2713 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2710 for (int i = 0; i < arg_count; i++) { | 2714 for (int i = 0; i < arg_count; i++) { |
| 2711 VisitForStackValue(args->at(i)); | 2715 VisitForStackValue(args->at(i)); |
| 2712 } | 2716 } |
| 2713 } | 2717 } |
| 2714 | 2718 |
| 2715 // Record source position for debugger. | 2719 // Record source position for debugger. |
| 2716 SetSourcePosition(expr->position()); | 2720 SetSourcePosition(expr->position()); |
| 2717 CallFunctionStub stub(arg_count, CALL_AS_METHOD); | 2721 CallFunctionStub stub(isolate(), arg_count, CALL_AS_METHOD); |
| 2718 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2722 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2719 __ CallStub(&stub); | 2723 __ CallStub(&stub); |
| 2720 | 2724 |
| 2721 RecordJSReturnSite(expr); | 2725 RecordJSReturnSite(expr); |
| 2722 // Restore context register. | 2726 // Restore context register. |
| 2723 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2727 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2724 | 2728 |
| 2725 context()->DropAndPlug(1, r0); | 2729 context()->DropAndPlug(1, r0); |
| 2726 } | 2730 } |
| 2727 | 2731 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2738 // Record source position for debugger. | 2742 // Record source position for debugger. |
| 2739 SetSourcePosition(expr->position()); | 2743 SetSourcePosition(expr->position()); |
| 2740 | 2744 |
| 2741 Handle<Object> uninitialized = | 2745 Handle<Object> uninitialized = |
| 2742 TypeFeedbackInfo::UninitializedSentinel(isolate()); | 2746 TypeFeedbackInfo::UninitializedSentinel(isolate()); |
| 2743 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); | 2747 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); |
| 2744 __ Move(r2, FeedbackVector()); | 2748 __ Move(r2, FeedbackVector()); |
| 2745 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); | 2749 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); |
| 2746 | 2750 |
| 2747 // Record call targets in unoptimized code. | 2751 // Record call targets in unoptimized code. |
| 2748 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); | 2752 CallFunctionStub stub(isolate(), arg_count, RECORD_CALL_TARGET); |
| 2749 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2753 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2750 __ CallStub(&stub); | 2754 __ CallStub(&stub); |
| 2751 RecordJSReturnSite(expr); | 2755 RecordJSReturnSite(expr); |
| 2752 // Restore context register. | 2756 // Restore context register. |
| 2753 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2757 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2754 context()->DropAndPlug(1, r0); | 2758 context()->DropAndPlug(1, r0); |
| 2755 } | 2759 } |
| 2756 | 2760 |
| 2757 | 2761 |
| 2758 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2762 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2815 EmitResolvePossiblyDirectEval(arg_count); | 2819 EmitResolvePossiblyDirectEval(arg_count); |
| 2816 | 2820 |
| 2817 // The runtime call returns a pair of values in r0 (function) and | 2821 // The runtime call returns a pair of values in r0 (function) and |
| 2818 // r1 (receiver). Touch up the stack with the right values. | 2822 // r1 (receiver). Touch up the stack with the right values. |
| 2819 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2823 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2820 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | 2824 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2821 } | 2825 } |
| 2822 | 2826 |
| 2823 // Record source position for debugger. | 2827 // Record source position for debugger. |
| 2824 SetSourcePosition(expr->position()); | 2828 SetSourcePosition(expr->position()); |
| 2825 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2829 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 2826 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2830 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2827 __ CallStub(&stub); | 2831 __ CallStub(&stub); |
| 2828 RecordJSReturnSite(expr); | 2832 RecordJSReturnSite(expr); |
| 2829 // Restore context register. | 2833 // Restore context register. |
| 2830 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2834 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2831 context()->DropAndPlug(1, r0); | 2835 context()->DropAndPlug(1, r0); |
| 2832 } else if (call_type == Call::GLOBAL_CALL) { | 2836 } else if (call_type == Call::GLOBAL_CALL) { |
| 2833 EmitCallWithIC(expr); | 2837 EmitCallWithIC(expr); |
| 2834 | 2838 |
| 2835 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2839 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2933 if (FLAG_pretenuring_call_new) { | 2937 if (FLAG_pretenuring_call_new) { |
| 2934 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), | 2938 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), |
| 2935 isolate()->factory()->NewAllocationSite()); | 2939 isolate()->factory()->NewAllocationSite()); |
| 2936 ASSERT(expr->AllocationSiteFeedbackSlot() == | 2940 ASSERT(expr->AllocationSiteFeedbackSlot() == |
| 2937 expr->CallNewFeedbackSlot() + 1); | 2941 expr->CallNewFeedbackSlot() + 1); |
| 2938 } | 2942 } |
| 2939 | 2943 |
| 2940 __ Move(r2, FeedbackVector()); | 2944 __ Move(r2, FeedbackVector()); |
| 2941 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); | 2945 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); |
| 2942 | 2946 |
| 2943 CallConstructStub stub(RECORD_CALL_TARGET); | 2947 CallConstructStub stub(isolate(), RECORD_CALL_TARGET); |
| 2944 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 2948 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |
| 2945 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2949 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2946 context()->Plug(r0); | 2950 context()->Plug(r0); |
| 2947 } | 2951 } |
| 2948 | 2952 |
| 2949 | 2953 |
| 2950 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2954 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 2951 ZoneList<Expression*>* args = expr->arguments(); | 2955 ZoneList<Expression*>* args = expr->arguments(); |
| 2952 ASSERT(args->length() == 1); | 2956 ASSERT(args->length() == 1); |
| 2953 | 2957 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3304 | 3308 |
| 3305 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { | 3309 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
| 3306 ZoneList<Expression*>* args = expr->arguments(); | 3310 ZoneList<Expression*>* args = expr->arguments(); |
| 3307 ASSERT(args->length() == 1); | 3311 ASSERT(args->length() == 1); |
| 3308 | 3312 |
| 3309 // ArgumentsAccessStub expects the key in edx and the formal | 3313 // ArgumentsAccessStub expects the key in edx and the formal |
| 3310 // parameter count in r0. | 3314 // parameter count in r0. |
| 3311 VisitForAccumulatorValue(args->at(0)); | 3315 VisitForAccumulatorValue(args->at(0)); |
| 3312 __ mov(r1, r0); | 3316 __ mov(r1, r0); |
| 3313 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 3317 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| 3314 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 3318 ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); |
| 3315 __ CallStub(&stub); | 3319 __ CallStub(&stub); |
| 3316 context()->Plug(r0); | 3320 context()->Plug(r0); |
| 3317 } | 3321 } |
| 3318 | 3322 |
| 3319 | 3323 |
| 3320 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { | 3324 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
| 3321 ASSERT(expr->arguments()->length() == 0); | 3325 ASSERT(expr->arguments()->length() == 0); |
| 3322 | 3326 |
| 3323 // Get the number of formal parameters. | 3327 // Get the number of formal parameters. |
| 3324 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 3328 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3414 } | 3418 } |
| 3415 | 3419 |
| 3416 // Finally, we're expected to leave a value on the top of the stack. | 3420 // Finally, we're expected to leave a value on the top of the stack. |
| 3417 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3421 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 3418 context()->Plug(r0); | 3422 context()->Plug(r0); |
| 3419 } | 3423 } |
| 3420 | 3424 |
| 3421 | 3425 |
| 3422 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3426 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3423 // Load the arguments on the stack and call the stub. | 3427 // Load the arguments on the stack and call the stub. |
| 3424 SubStringStub stub; | 3428 SubStringStub stub(isolate()); |
| 3425 ZoneList<Expression*>* args = expr->arguments(); | 3429 ZoneList<Expression*>* args = expr->arguments(); |
| 3426 ASSERT(args->length() == 3); | 3430 ASSERT(args->length() == 3); |
| 3427 VisitForStackValue(args->at(0)); | 3431 VisitForStackValue(args->at(0)); |
| 3428 VisitForStackValue(args->at(1)); | 3432 VisitForStackValue(args->at(1)); |
| 3429 VisitForStackValue(args->at(2)); | 3433 VisitForStackValue(args->at(2)); |
| 3430 __ CallStub(&stub); | 3434 __ CallStub(&stub); |
| 3431 context()->Plug(r0); | 3435 context()->Plug(r0); |
| 3432 } | 3436 } |
| 3433 | 3437 |
| 3434 | 3438 |
| 3435 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | 3439 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3436 // Load the arguments on the stack and call the stub. | 3440 // Load the arguments on the stack and call the stub. |
| 3437 RegExpExecStub stub; | 3441 RegExpExecStub stub(isolate()); |
| 3438 ZoneList<Expression*>* args = expr->arguments(); | 3442 ZoneList<Expression*>* args = expr->arguments(); |
| 3439 ASSERT(args->length() == 4); | 3443 ASSERT(args->length() == 4); |
| 3440 VisitForStackValue(args->at(0)); | 3444 VisitForStackValue(args->at(0)); |
| 3441 VisitForStackValue(args->at(1)); | 3445 VisitForStackValue(args->at(1)); |
| 3442 VisitForStackValue(args->at(2)); | 3446 VisitForStackValue(args->at(2)); |
| 3443 VisitForStackValue(args->at(3)); | 3447 VisitForStackValue(args->at(3)); |
| 3444 __ CallStub(&stub); | 3448 __ CallStub(&stub); |
| 3445 context()->Plug(r0); | 3449 context()->Plug(r0); |
| 3446 } | 3450 } |
| 3447 | 3451 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3577 } | 3581 } |
| 3578 | 3582 |
| 3579 | 3583 |
| 3580 | 3584 |
| 3581 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { | 3585 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 3582 // Load the arguments on the stack and call the runtime function. | 3586 // Load the arguments on the stack and call the runtime function. |
| 3583 ZoneList<Expression*>* args = expr->arguments(); | 3587 ZoneList<Expression*>* args = expr->arguments(); |
| 3584 ASSERT(args->length() == 2); | 3588 ASSERT(args->length() == 2); |
| 3585 VisitForStackValue(args->at(0)); | 3589 VisitForStackValue(args->at(0)); |
| 3586 VisitForStackValue(args->at(1)); | 3590 VisitForStackValue(args->at(1)); |
| 3587 MathPowStub stub(MathPowStub::ON_STACK); | 3591 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 3588 __ CallStub(&stub); | 3592 __ CallStub(&stub); |
| 3589 context()->Plug(r0); | 3593 context()->Plug(r0); |
| 3590 } | 3594 } |
| 3591 | 3595 |
| 3592 | 3596 |
| 3593 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3597 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3594 ZoneList<Expression*>* args = expr->arguments(); | 3598 ZoneList<Expression*>* args = expr->arguments(); |
| 3595 ASSERT(args->length() == 2); | 3599 ASSERT(args->length() == 2); |
| 3596 VisitForStackValue(args->at(0)); // Load the object. | 3600 VisitForStackValue(args->at(0)); // Load the object. |
| 3597 VisitForAccumulatorValue(args->at(1)); // Load the value. | 3601 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3617 context()->Plug(r0); | 3621 context()->Plug(r0); |
| 3618 } | 3622 } |
| 3619 | 3623 |
| 3620 | 3624 |
| 3621 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { | 3625 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 3622 ZoneList<Expression*>* args = expr->arguments(); | 3626 ZoneList<Expression*>* args = expr->arguments(); |
| 3623 ASSERT_EQ(args->length(), 1); | 3627 ASSERT_EQ(args->length(), 1); |
| 3624 // Load the argument into r0 and call the stub. | 3628 // Load the argument into r0 and call the stub. |
| 3625 VisitForAccumulatorValue(args->at(0)); | 3629 VisitForAccumulatorValue(args->at(0)); |
| 3626 | 3630 |
| 3627 NumberToStringStub stub; | 3631 NumberToStringStub stub(isolate()); |
| 3628 __ CallStub(&stub); | 3632 __ CallStub(&stub); |
| 3629 context()->Plug(r0); | 3633 context()->Plug(r0); |
| 3630 } | 3634 } |
| 3631 | 3635 |
| 3632 | 3636 |
| 3633 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 3637 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 3634 ZoneList<Expression*>* args = expr->arguments(); | 3638 ZoneList<Expression*>* args = expr->arguments(); |
| 3635 ASSERT(args->length() == 1); | 3639 ASSERT(args->length() == 1); |
| 3636 VisitForAccumulatorValue(args->at(0)); | 3640 VisitForAccumulatorValue(args->at(0)); |
| 3637 | 3641 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3740 } | 3744 } |
| 3741 | 3745 |
| 3742 | 3746 |
| 3743 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { | 3747 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
| 3744 ZoneList<Expression*>* args = expr->arguments(); | 3748 ZoneList<Expression*>* args = expr->arguments(); |
| 3745 ASSERT_EQ(2, args->length()); | 3749 ASSERT_EQ(2, args->length()); |
| 3746 VisitForStackValue(args->at(0)); | 3750 VisitForStackValue(args->at(0)); |
| 3747 VisitForAccumulatorValue(args->at(1)); | 3751 VisitForAccumulatorValue(args->at(1)); |
| 3748 | 3752 |
| 3749 __ pop(r1); | 3753 __ pop(r1); |
| 3750 StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED); | 3754 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 3751 __ CallStub(&stub); | 3755 __ CallStub(&stub); |
| 3752 context()->Plug(r0); | 3756 context()->Plug(r0); |
| 3753 } | 3757 } |
| 3754 | 3758 |
| 3755 | 3759 |
| 3756 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { | 3760 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 3757 ZoneList<Expression*>* args = expr->arguments(); | 3761 ZoneList<Expression*>* args = expr->arguments(); |
| 3758 ASSERT_EQ(2, args->length()); | 3762 ASSERT_EQ(2, args->length()); |
| 3759 VisitForStackValue(args->at(0)); | 3763 VisitForStackValue(args->at(0)); |
| 3760 VisitForStackValue(args->at(1)); | 3764 VisitForStackValue(args->at(1)); |
| 3761 | 3765 |
| 3762 StringCompareStub stub; | 3766 StringCompareStub stub(isolate()); |
| 3763 __ CallStub(&stub); | 3767 __ CallStub(&stub); |
| 3764 context()->Plug(r0); | 3768 context()->Plug(r0); |
| 3765 } | 3769 } |
| 3766 | 3770 |
| 3767 | 3771 |
| 3768 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 3772 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3769 ZoneList<Expression*>* args = expr->arguments(); | 3773 ZoneList<Expression*>* args = expr->arguments(); |
| 3770 ASSERT(args->length() >= 2); | 3774 ASSERT(args->length() >= 2); |
| 3771 | 3775 |
| 3772 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3776 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3791 __ bind(&runtime); | 3795 __ bind(&runtime); |
| 3792 __ push(r0); | 3796 __ push(r0); |
| 3793 __ CallRuntime(Runtime::kCall, args->length()); | 3797 __ CallRuntime(Runtime::kCall, args->length()); |
| 3794 __ bind(&done); | 3798 __ bind(&done); |
| 3795 | 3799 |
| 3796 context()->Plug(r0); | 3800 context()->Plug(r0); |
| 3797 } | 3801 } |
| 3798 | 3802 |
| 3799 | 3803 |
| 3800 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { | 3804 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
| 3801 RegExpConstructResultStub stub; | 3805 RegExpConstructResultStub stub(isolate()); |
| 3802 ZoneList<Expression*>* args = expr->arguments(); | 3806 ZoneList<Expression*>* args = expr->arguments(); |
| 3803 ASSERT(args->length() == 3); | 3807 ASSERT(args->length() == 3); |
| 3804 VisitForStackValue(args->at(0)); | 3808 VisitForStackValue(args->at(0)); |
| 3805 VisitForStackValue(args->at(1)); | 3809 VisitForStackValue(args->at(1)); |
| 3806 VisitForAccumulatorValue(args->at(2)); | 3810 VisitForAccumulatorValue(args->at(2)); |
| 3807 __ pop(r1); | 3811 __ pop(r1); |
| 3808 __ pop(r2); | 3812 __ pop(r2); |
| 3809 __ CallStub(&stub); | 3813 __ CallStub(&stub); |
| 3810 context()->Plug(r0); | 3814 context()->Plug(r0); |
| 3811 } | 3815 } |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4157 __ str(r0, MemOperand(sp, kPointerSize)); | 4161 __ str(r0, MemOperand(sp, kPointerSize)); |
| 4158 | 4162 |
| 4159 // Push the arguments ("left-to-right"). | 4163 // Push the arguments ("left-to-right"). |
| 4160 int arg_count = args->length(); | 4164 int arg_count = args->length(); |
| 4161 for (int i = 0; i < arg_count; i++) { | 4165 for (int i = 0; i < arg_count; i++) { |
| 4162 VisitForStackValue(args->at(i)); | 4166 VisitForStackValue(args->at(i)); |
| 4163 } | 4167 } |
| 4164 | 4168 |
| 4165 // Record source position of the IC call. | 4169 // Record source position of the IC call. |
| 4166 SetSourcePosition(expr->position()); | 4170 SetSourcePosition(expr->position()); |
| 4167 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 4171 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4168 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 4172 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 4169 __ CallStub(&stub); | 4173 __ CallStub(&stub); |
| 4170 | 4174 |
| 4171 // Restore context register. | 4175 // Restore context register. |
| 4172 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4176 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4173 | 4177 |
| 4174 context()->DropAndPlug(1, r0); | 4178 context()->DropAndPlug(1, r0); |
| 4175 } else { | 4179 } else { |
| 4176 // Push the arguments ("left-to-right"). | 4180 // Push the arguments ("left-to-right"). |
| 4177 for (int i = 0; i < arg_count; i++) { | 4181 for (int i = 0; i < arg_count; i++) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4375 } | 4379 } |
| 4376 } | 4380 } |
| 4377 | 4381 |
| 4378 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); | 4382 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); |
| 4379 __ b(vc, &done); | 4383 __ b(vc, &done); |
| 4380 // Call stub. Undo operation first. | 4384 // Call stub. Undo operation first. |
| 4381 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); | 4385 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); |
| 4382 __ jmp(&stub_call); | 4386 __ jmp(&stub_call); |
| 4383 __ bind(&slow); | 4387 __ bind(&slow); |
| 4384 } | 4388 } |
| 4385 ToNumberStub convert_stub; | 4389 ToNumberStub convert_stub(isolate()); |
| 4386 __ CallStub(&convert_stub); | 4390 __ CallStub(&convert_stub); |
| 4387 | 4391 |
| 4388 // Save result for postfix expressions. | 4392 // Save result for postfix expressions. |
| 4389 if (expr->is_postfix()) { | 4393 if (expr->is_postfix()) { |
| 4390 if (!context()->IsEffect()) { | 4394 if (!context()->IsEffect()) { |
| 4391 // Save the result on the stack. If we have a named or keyed property | 4395 // Save the result on the stack. If we have a named or keyed property |
| 4392 // we store the result under the receiver that is currently on top | 4396 // we store the result under the receiver that is currently on top |
| 4393 // of the stack. | 4397 // of the stack. |
| 4394 switch (assign_type) { | 4398 switch (assign_type) { |
| 4395 case VARIABLE: | 4399 case VARIABLE: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4406 } | 4410 } |
| 4407 | 4411 |
| 4408 | 4412 |
| 4409 __ bind(&stub_call); | 4413 __ bind(&stub_call); |
| 4410 __ mov(r1, r0); | 4414 __ mov(r1, r0); |
| 4411 __ mov(r0, Operand(Smi::FromInt(count_value))); | 4415 __ mov(r0, Operand(Smi::FromInt(count_value))); |
| 4412 | 4416 |
| 4413 // Record position before stub call. | 4417 // Record position before stub call. |
| 4414 SetSourcePosition(expr->position()); | 4418 SetSourcePosition(expr->position()); |
| 4415 | 4419 |
| 4416 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); | 4420 BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE); |
| 4417 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); | 4421 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); |
| 4418 patch_site.EmitPatchInfo(); | 4422 patch_site.EmitPatchInfo(); |
| 4419 __ bind(&done); | 4423 __ bind(&done); |
| 4420 | 4424 |
| 4421 // Store the value returned in r0. | 4425 // Store the value returned in r0. |
| 4422 switch (assign_type) { | 4426 switch (assign_type) { |
| 4423 case VARIABLE: | 4427 case VARIABLE: |
| 4424 if (expr->is_postfix()) { | 4428 if (expr->is_postfix()) { |
| 4425 { EffectContext context(this); | 4429 { EffectContext context(this); |
| 4426 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4430 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4616 VisitForStackValue(expr->right()); | 4620 VisitForStackValue(expr->right()); |
| 4617 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4621 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 4618 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 4622 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 4619 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 4623 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 4620 __ cmp(r0, ip); | 4624 __ cmp(r0, ip); |
| 4621 Split(eq, if_true, if_false, fall_through); | 4625 Split(eq, if_true, if_false, fall_through); |
| 4622 break; | 4626 break; |
| 4623 | 4627 |
| 4624 case Token::INSTANCEOF: { | 4628 case Token::INSTANCEOF: { |
| 4625 VisitForStackValue(expr->right()); | 4629 VisitForStackValue(expr->right()); |
| 4626 InstanceofStub stub(InstanceofStub::kNoFlags); | 4630 InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); |
| 4627 __ CallStub(&stub); | 4631 __ CallStub(&stub); |
| 4628 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4632 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4629 // The stub returns 0 for true. | 4633 // The stub returns 0 for true. |
| 4630 __ tst(r0, r0); | 4634 __ tst(r0, r0); |
| 4631 Split(eq, if_true, if_false, fall_through); | 4635 Split(eq, if_true, if_false, fall_through); |
| 4632 break; | 4636 break; |
| 4633 } | 4637 } |
| 4634 | 4638 |
| 4635 default: { | 4639 default: { |
| 4636 VisitForAccumulatorValue(expr->right()); | 4640 VisitForAccumulatorValue(expr->right()); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4932 | 4936 |
| 4933 ASSERT(interrupt_address == | 4937 ASSERT(interrupt_address == |
| 4934 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4938 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4935 return OSR_AFTER_STACK_CHECK; | 4939 return OSR_AFTER_STACK_CHECK; |
| 4936 } | 4940 } |
| 4937 | 4941 |
| 4938 | 4942 |
| 4939 } } // namespace v8::internal | 4943 } } // namespace v8::internal |
| 4940 | 4944 |
| 4941 #endif // V8_TARGET_ARCH_ARM | 4945 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |