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 |