| 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 // Possibly allocate a local context. | 242 // Possibly allocate a local context. |
| 243 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 243 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 244 if (heap_slots > 0) { | 244 if (heap_slots > 0) { |
| 245 Comment cmnt(masm_, "[ Allocate context"); | 245 Comment cmnt(masm_, "[ Allocate context"); |
| 246 // Argument to NewContext is the function, which is still in a1. | 246 // Argument to NewContext is the function, which is still in a1. |
| 247 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 247 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
| 248 __ push(a1); | 248 __ push(a1); |
| 249 __ Push(info->scope()->GetScopeInfo()); | 249 __ Push(info->scope()->GetScopeInfo()); |
| 250 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 250 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
| 251 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 251 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 252 FastNewContextStub stub(heap_slots); | 252 FastNewContextStub stub(isolate(), heap_slots); |
| 253 __ CallStub(&stub); | 253 __ CallStub(&stub); |
| 254 } else { | 254 } else { |
| 255 __ push(a1); | 255 __ push(a1); |
| 256 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 256 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
| 257 } | 257 } |
| 258 function_in_register = false; | 258 function_in_register = false; |
| 259 // Context is returned in v0. It replaces the context passed to us. | 259 // Context is returned in v0. It replaces the context passed to us. |
| 260 // It's saved in the stack and kept live in cp. | 260 // It's saved in the stack and kept live in cp. |
| 261 __ mov(cp, v0); | 261 __ mov(cp, v0); |
| 262 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 262 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 // The stub will rewrite receiever and parameter count if the previous | 303 // The stub will rewrite receiever and parameter count if the previous |
| 304 // stack frame was an arguments adapter frame. | 304 // stack frame was an arguments adapter frame. |
| 305 ArgumentsAccessStub::Type type; | 305 ArgumentsAccessStub::Type type; |
| 306 if (strict_mode() == STRICT) { | 306 if (strict_mode() == STRICT) { |
| 307 type = ArgumentsAccessStub::NEW_STRICT; | 307 type = ArgumentsAccessStub::NEW_STRICT; |
| 308 } else if (function()->has_duplicate_parameters()) { | 308 } else if (function()->has_duplicate_parameters()) { |
| 309 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 309 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
| 310 } else { | 310 } else { |
| 311 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 311 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
| 312 } | 312 } |
| 313 ArgumentsAccessStub stub(type); | 313 ArgumentsAccessStub stub(isolate(), type); |
| 314 __ CallStub(&stub); | 314 __ CallStub(&stub); |
| 315 | 315 |
| 316 SetVar(arguments, v0, a1, a2); | 316 SetVar(arguments, v0, a1, a2); |
| 317 } | 317 } |
| 318 | 318 |
| 319 if (FLAG_trace) { | 319 if (FLAG_trace) { |
| 320 __ CallRuntime(Runtime::kTraceEnter, 0); | 320 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 321 } | 321 } |
| 322 | 322 |
| 323 // Visit the declarations and body unless there is an illegal | 323 // Visit the declarations and body unless there is an illegal |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 // space for nested functions that don't need literals cloning. If | 1361 // space for nested functions that don't need literals cloning. If |
| 1362 // we're running with the --always-opt or the --prepare-always-opt | 1362 // we're running with the --always-opt or the --prepare-always-opt |
| 1363 // flag, we need to use the runtime function so that the new function | 1363 // flag, we need to use the runtime function so that the new function |
| 1364 // we are creating here gets a chance to have its code optimized and | 1364 // we are creating here gets a chance to have its code optimized and |
| 1365 // doesn't just get a copy of the existing unoptimized code. | 1365 // doesn't just get a copy of the existing unoptimized code. |
| 1366 if (!FLAG_always_opt && | 1366 if (!FLAG_always_opt && |
| 1367 !FLAG_prepare_always_opt && | 1367 !FLAG_prepare_always_opt && |
| 1368 !pretenure && | 1368 !pretenure && |
| 1369 scope()->is_function_scope() && | 1369 scope()->is_function_scope() && |
| 1370 info->num_literals() == 0) { | 1370 info->num_literals() == 0) { |
| 1371 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1371 FastNewClosureStub stub(isolate(), |
| 1372 info->strict_mode(), |
| 1373 info->is_generator()); |
| 1372 __ li(a2, Operand(info)); | 1374 __ li(a2, Operand(info)); |
| 1373 __ CallStub(&stub); | 1375 __ CallStub(&stub); |
| 1374 } else { | 1376 } else { |
| 1375 __ li(a0, Operand(info)); | 1377 __ li(a0, Operand(info)); |
| 1376 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex | 1378 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex |
| 1377 : Heap::kFalseValueRootIndex); | 1379 : Heap::kFalseValueRootIndex); |
| 1378 __ Push(cp, a0, a1); | 1380 __ Push(cp, a0, a1); |
| 1379 __ CallRuntime(Runtime::kHiddenNewClosure, 3); | 1381 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
| 1380 } | 1382 } |
| 1381 context()->Plug(v0); | 1383 context()->Plug(v0); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 ? ObjectLiteral::kHasFunction | 1688 ? ObjectLiteral::kHasFunction |
| 1687 : ObjectLiteral::kNoFlags; | 1689 : ObjectLiteral::kNoFlags; |
| 1688 __ li(a0, Operand(Smi::FromInt(flags))); | 1690 __ li(a0, Operand(Smi::FromInt(flags))); |
| 1689 int properties_count = constant_properties->length() / 2; | 1691 int properties_count = constant_properties->length() / 2; |
| 1690 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || | 1692 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || |
| 1691 flags != ObjectLiteral::kFastElements || | 1693 flags != ObjectLiteral::kFastElements || |
| 1692 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1694 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1693 __ Push(a3, a2, a1, a0); | 1695 __ Push(a3, a2, a1, a0); |
| 1694 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); | 1696 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
| 1695 } else { | 1697 } else { |
| 1696 FastCloneShallowObjectStub stub(properties_count); | 1698 FastCloneShallowObjectStub stub(isolate(), properties_count); |
| 1697 __ CallStub(&stub); | 1699 __ CallStub(&stub); |
| 1698 } | 1700 } |
| 1699 | 1701 |
| 1700 // If result_saved is true the result is on top of the stack. If | 1702 // If result_saved is true the result is on top of the stack. If |
| 1701 // result_saved is false the result is in v0. | 1703 // result_saved is false the result is in v0. |
| 1702 bool result_saved = false; | 1704 bool result_saved = false; |
| 1703 | 1705 |
| 1704 // Mark all computed expressions that are bound to a key that | 1706 // Mark all computed expressions that are bound to a key that |
| 1705 // is shadowed by a later occurrence of the same key. For the | 1707 // is shadowed by a later occurrence of the same key. For the |
| 1706 // marked expressions, no store code is emitted. | 1708 // marked expressions, no store code is emitted. |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 } | 1830 } |
| 1829 | 1831 |
| 1830 __ mov(a0, result_register()); | 1832 __ mov(a0, result_register()); |
| 1831 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1833 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1832 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1834 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1833 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1835 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1834 __ li(a1, Operand(constant_elements)); | 1836 __ li(a1, Operand(constant_elements)); |
| 1835 if (has_fast_elements && constant_elements_values->map() == | 1837 if (has_fast_elements && constant_elements_values->map() == |
| 1836 isolate()->heap()->fixed_cow_array_map()) { | 1838 isolate()->heap()->fixed_cow_array_map()) { |
| 1837 FastCloneShallowArrayStub stub( | 1839 FastCloneShallowArrayStub stub( |
| 1840 isolate(), |
| 1838 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1841 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1839 allocation_site_mode, | 1842 allocation_site_mode, |
| 1840 length); | 1843 length); |
| 1841 __ CallStub(&stub); | 1844 __ CallStub(&stub); |
| 1842 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), | 1845 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), |
| 1843 1, a1, a2); | 1846 1, a1, a2); |
| 1844 } else if (expr->depth() > 1 || Serializer::enabled() || | 1847 } else if (expr->depth() > 1 || Serializer::enabled() || |
| 1845 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1848 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1846 __ li(a0, Operand(Smi::FromInt(flags))); | 1849 __ li(a0, Operand(Smi::FromInt(flags))); |
| 1847 __ Push(a3, a2, a1, a0); | 1850 __ Push(a3, a2, a1, a0); |
| 1848 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); | 1851 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
| 1849 } else { | 1852 } else { |
| 1850 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1853 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1851 FLAG_smi_only_arrays); | 1854 FLAG_smi_only_arrays); |
| 1852 FastCloneShallowArrayStub::Mode mode = | 1855 FastCloneShallowArrayStub::Mode mode = |
| 1853 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1856 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
| 1854 | 1857 |
| 1855 if (has_fast_elements) { | 1858 if (has_fast_elements) { |
| 1856 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1859 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
| 1857 } | 1860 } |
| 1858 | 1861 |
| 1859 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 1862 FastCloneShallowArrayStub stub(isolate(), mode, allocation_site_mode, |
| 1863 length); |
| 1860 __ CallStub(&stub); | 1864 __ CallStub(&stub); |
| 1861 } | 1865 } |
| 1862 | 1866 |
| 1863 bool result_saved = false; // Is the result saved to the stack? | 1867 bool result_saved = false; // Is the result saved to the stack? |
| 1864 | 1868 |
| 1865 // Emit code to evaluate all the non-constant subexpressions and to store | 1869 // Emit code to evaluate all the non-constant subexpressions and to store |
| 1866 // them into the newly cloned array. | 1870 // them into the newly cloned array. |
| 1867 for (int i = 0; i < length; i++) { | 1871 for (int i = 0; i < length; i++) { |
| 1868 Expression* subexpr = subexprs->at(i); | 1872 Expression* subexpr = subexprs->at(i); |
| 1869 // If the subexpression is a literal or a simple materialized literal it | 1873 // If the subexpression is a literal or a simple materialized literal it |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1883 __ lw(t2, MemOperand(sp, kPointerSize)); // Copy of array literal. | 1887 __ lw(t2, MemOperand(sp, kPointerSize)); // Copy of array literal. |
| 1884 __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset)); | 1888 __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset)); |
| 1885 __ sw(result_register(), FieldMemOperand(a1, offset)); | 1889 __ sw(result_register(), FieldMemOperand(a1, offset)); |
| 1886 // Update the write barrier for the array store. | 1890 // Update the write barrier for the array store. |
| 1887 __ RecordWriteField(a1, offset, result_register(), a2, | 1891 __ RecordWriteField(a1, offset, result_register(), a2, |
| 1888 kRAHasBeenSaved, kDontSaveFPRegs, | 1892 kRAHasBeenSaved, kDontSaveFPRegs, |
| 1889 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); | 1893 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); |
| 1890 } else { | 1894 } else { |
| 1891 __ li(a3, Operand(Smi::FromInt(i))); | 1895 __ li(a3, Operand(Smi::FromInt(i))); |
| 1892 __ mov(a0, result_register()); | 1896 __ mov(a0, result_register()); |
| 1893 StoreArrayLiteralElementStub stub; | 1897 StoreArrayLiteralElementStub stub(isolate()); |
| 1894 __ CallStub(&stub); | 1898 __ CallStub(&stub); |
| 1895 } | 1899 } |
| 1896 | 1900 |
| 1897 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); | 1901 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); |
| 1898 } | 1902 } |
| 1899 if (result_saved) { | 1903 if (result_saved) { |
| 1900 __ Pop(); // literal index | 1904 __ Pop(); // literal index |
| 1901 context()->PlugTOS(); | 1905 context()->PlugTOS(); |
| 1902 } else { | 1906 } else { |
| 1903 context()->Plug(v0); | 1907 context()->Plug(v0); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 | 2135 |
| 2132 // result = receiver[f](arg); | 2136 // result = receiver[f](arg); |
| 2133 __ bind(&l_call); | 2137 __ bind(&l_call); |
| 2134 __ lw(a1, MemOperand(sp, kPointerSize)); | 2138 __ lw(a1, MemOperand(sp, kPointerSize)); |
| 2135 __ lw(a0, MemOperand(sp, 2 * kPointerSize)); | 2139 __ lw(a0, MemOperand(sp, 2 * kPointerSize)); |
| 2136 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2140 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2137 CallIC(ic, TypeFeedbackId::None()); | 2141 CallIC(ic, TypeFeedbackId::None()); |
| 2138 __ mov(a0, v0); | 2142 __ mov(a0, v0); |
| 2139 __ mov(a1, a0); | 2143 __ mov(a1, a0); |
| 2140 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); | 2144 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); |
| 2141 CallFunctionStub stub(1, CALL_AS_METHOD); | 2145 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2142 __ CallStub(&stub); | 2146 __ CallStub(&stub); |
| 2143 | 2147 |
| 2144 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2148 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2145 __ Drop(1); // The function is still on the stack; drop it. | 2149 __ Drop(1); // The function is still on the stack; drop it. |
| 2146 | 2150 |
| 2147 // if (!result.done) goto l_try; | 2151 // if (!result.done) goto l_try; |
| 2148 __ bind(&l_loop); | 2152 __ bind(&l_loop); |
| 2149 __ mov(a0, v0); | 2153 __ mov(a0, v0); |
| 2150 __ push(a0); // save result | 2154 __ push(a0); // save result |
| 2151 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" | 2155 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2352 __ pop(left); | 2356 __ pop(left); |
| 2353 __ mov(a0, result_register()); | 2357 __ mov(a0, result_register()); |
| 2354 | 2358 |
| 2355 // Perform combined smi check on both operands. | 2359 // Perform combined smi check on both operands. |
| 2356 __ Or(scratch1, left, Operand(right)); | 2360 __ Or(scratch1, left, Operand(right)); |
| 2357 STATIC_ASSERT(kSmiTag == 0); | 2361 STATIC_ASSERT(kSmiTag == 0); |
| 2358 JumpPatchSite patch_site(masm_); | 2362 JumpPatchSite patch_site(masm_); |
| 2359 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2363 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 2360 | 2364 |
| 2361 __ bind(&stub_call); | 2365 __ bind(&stub_call); |
| 2362 BinaryOpICStub stub(op, mode); | 2366 BinaryOpICStub stub(isolate(), op, mode); |
| 2363 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2367 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
| 2364 patch_site.EmitPatchInfo(); | 2368 patch_site.EmitPatchInfo(); |
| 2365 __ jmp(&done); | 2369 __ jmp(&done); |
| 2366 | 2370 |
| 2367 __ bind(&smi_case); | 2371 __ bind(&smi_case); |
| 2368 // Smi case. This code works the same way as the smi-smi case in the type | 2372 // Smi case. This code works the same way as the smi-smi case in the type |
| 2369 // recording binary operation stub, see | 2373 // recording binary operation stub, see |
| 2370 switch (op) { | 2374 switch (op) { |
| 2371 case Token::SAR: | 2375 case Token::SAR: |
| 2372 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2376 __ GetLeastBitsFromSmi(scratch1, right, 5); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2430 __ bind(&done); | 2434 __ bind(&done); |
| 2431 context()->Plug(v0); | 2435 context()->Plug(v0); |
| 2432 } | 2436 } |
| 2433 | 2437 |
| 2434 | 2438 |
| 2435 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2439 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2436 Token::Value op, | 2440 Token::Value op, |
| 2437 OverwriteMode mode) { | 2441 OverwriteMode mode) { |
| 2438 __ mov(a0, result_register()); | 2442 __ mov(a0, result_register()); |
| 2439 __ pop(a1); | 2443 __ pop(a1); |
| 2440 BinaryOpICStub stub(op, mode); | 2444 BinaryOpICStub stub(isolate(), op, mode); |
| 2441 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2445 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2442 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); | 2446 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); |
| 2443 patch_site.EmitPatchInfo(); | 2447 patch_site.EmitPatchInfo(); |
| 2444 context()->Plug(v0); | 2448 context()->Plug(v0); |
| 2445 } | 2449 } |
| 2446 | 2450 |
| 2447 | 2451 |
| 2448 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2452 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2449 ASSERT(expr->IsValidReferenceExpression()); | 2453 ASSERT(expr->IsValidReferenceExpression()); |
| 2450 | 2454 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2679 } | 2683 } |
| 2680 | 2684 |
| 2681 // Load the arguments. | 2685 // Load the arguments. |
| 2682 { PreservePositionScope scope(masm()->positions_recorder()); | 2686 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2683 for (int i = 0; i < arg_count; i++) { | 2687 for (int i = 0; i < arg_count; i++) { |
| 2684 VisitForStackValue(args->at(i)); | 2688 VisitForStackValue(args->at(i)); |
| 2685 } | 2689 } |
| 2686 } | 2690 } |
| 2687 // Record source position for debugger. | 2691 // Record source position for debugger. |
| 2688 SetSourcePosition(expr->position()); | 2692 SetSourcePosition(expr->position()); |
| 2689 CallFunctionStub stub(arg_count, flags); | 2693 CallFunctionStub stub(isolate(), arg_count, flags); |
| 2690 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2694 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2691 __ CallStub(&stub); | 2695 __ CallStub(&stub); |
| 2692 | 2696 |
| 2693 RecordJSReturnSite(expr); | 2697 RecordJSReturnSite(expr); |
| 2694 | 2698 |
| 2695 // Restore context register. | 2699 // Restore context register. |
| 2696 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2700 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2697 | 2701 |
| 2698 context()->DropAndPlug(1, v0); | 2702 context()->DropAndPlug(1, v0); |
| 2699 } | 2703 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2721 __ sw(v0, MemOperand(sp, kPointerSize)); | 2725 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2722 | 2726 |
| 2723 { PreservePositionScope scope(masm()->positions_recorder()); | 2727 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2724 for (int i = 0; i < arg_count; i++) { | 2728 for (int i = 0; i < arg_count; i++) { |
| 2725 VisitForStackValue(args->at(i)); | 2729 VisitForStackValue(args->at(i)); |
| 2726 } | 2730 } |
| 2727 } | 2731 } |
| 2728 | 2732 |
| 2729 // Record source position for debugger. | 2733 // Record source position for debugger. |
| 2730 SetSourcePosition(expr->position()); | 2734 SetSourcePosition(expr->position()); |
| 2731 CallFunctionStub stub(arg_count, CALL_AS_METHOD); | 2735 CallFunctionStub stub(isolate(), arg_count, CALL_AS_METHOD); |
| 2732 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2736 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2733 __ CallStub(&stub); | 2737 __ CallStub(&stub); |
| 2734 | 2738 |
| 2735 RecordJSReturnSite(expr); | 2739 RecordJSReturnSite(expr); |
| 2736 // Restore context register. | 2740 // Restore context register. |
| 2737 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2741 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2738 | 2742 |
| 2739 context()->DropAndPlug(1, v0); | 2743 context()->DropAndPlug(1, v0); |
| 2740 } | 2744 } |
| 2741 | 2745 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2752 // Record source position for debugger. | 2756 // Record source position for debugger. |
| 2753 SetSourcePosition(expr->position()); | 2757 SetSourcePosition(expr->position()); |
| 2754 | 2758 |
| 2755 Handle<Object> uninitialized = | 2759 Handle<Object> uninitialized = |
| 2756 TypeFeedbackInfo::UninitializedSentinel(isolate()); | 2760 TypeFeedbackInfo::UninitializedSentinel(isolate()); |
| 2757 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); | 2761 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); |
| 2758 __ li(a2, FeedbackVector()); | 2762 __ li(a2, FeedbackVector()); |
| 2759 __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); | 2763 __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); |
| 2760 | 2764 |
| 2761 // Record call targets in unoptimized code. | 2765 // Record call targets in unoptimized code. |
| 2762 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); | 2766 CallFunctionStub stub(isolate(), arg_count, RECORD_CALL_TARGET); |
| 2763 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2767 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2764 __ CallStub(&stub); | 2768 __ CallStub(&stub); |
| 2765 RecordJSReturnSite(expr); | 2769 RecordJSReturnSite(expr); |
| 2766 // Restore context register. | 2770 // Restore context register. |
| 2767 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2771 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2768 context()->DropAndPlug(1, v0); | 2772 context()->DropAndPlug(1, v0); |
| 2769 } | 2773 } |
| 2770 | 2774 |
| 2771 | 2775 |
| 2772 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2776 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2828 __ push(a1); | 2832 __ push(a1); |
| 2829 EmitResolvePossiblyDirectEval(arg_count); | 2833 EmitResolvePossiblyDirectEval(arg_count); |
| 2830 | 2834 |
| 2831 // The runtime call returns a pair of values in v0 (function) and | 2835 // The runtime call returns a pair of values in v0 (function) and |
| 2832 // v1 (receiver). Touch up the stack with the right values. | 2836 // v1 (receiver). Touch up the stack with the right values. |
| 2833 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2837 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2834 __ sw(v1, MemOperand(sp, arg_count * kPointerSize)); | 2838 __ sw(v1, MemOperand(sp, arg_count * kPointerSize)); |
| 2835 } | 2839 } |
| 2836 // Record source position for debugger. | 2840 // Record source position for debugger. |
| 2837 SetSourcePosition(expr->position()); | 2841 SetSourcePosition(expr->position()); |
| 2838 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2842 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 2839 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2843 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2840 __ CallStub(&stub); | 2844 __ CallStub(&stub); |
| 2841 RecordJSReturnSite(expr); | 2845 RecordJSReturnSite(expr); |
| 2842 // Restore context register. | 2846 // Restore context register. |
| 2843 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2847 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2844 context()->DropAndPlug(1, v0); | 2848 context()->DropAndPlug(1, v0); |
| 2845 } else if (call_type == Call::GLOBAL_CALL) { | 2849 } else if (call_type == Call::GLOBAL_CALL) { |
| 2846 EmitCallWithIC(expr); | 2850 EmitCallWithIC(expr); |
| 2847 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2851 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| 2848 // Call to a lookup slot (dynamically introduced variable). | 2852 // Call to a lookup slot (dynamically introduced variable). |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2945 if (FLAG_pretenuring_call_new) { | 2949 if (FLAG_pretenuring_call_new) { |
| 2946 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), | 2950 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), |
| 2947 isolate()->factory()->NewAllocationSite()); | 2951 isolate()->factory()->NewAllocationSite()); |
| 2948 ASSERT(expr->AllocationSiteFeedbackSlot() == | 2952 ASSERT(expr->AllocationSiteFeedbackSlot() == |
| 2949 expr->CallNewFeedbackSlot() + 1); | 2953 expr->CallNewFeedbackSlot() + 1); |
| 2950 } | 2954 } |
| 2951 | 2955 |
| 2952 __ li(a2, FeedbackVector()); | 2956 __ li(a2, FeedbackVector()); |
| 2953 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); | 2957 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); |
| 2954 | 2958 |
| 2955 CallConstructStub stub(RECORD_CALL_TARGET); | 2959 CallConstructStub stub(isolate(), RECORD_CALL_TARGET); |
| 2956 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 2960 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |
| 2957 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2961 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2958 context()->Plug(v0); | 2962 context()->Plug(v0); |
| 2959 } | 2963 } |
| 2960 | 2964 |
| 2961 | 2965 |
| 2962 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2966 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 2963 ZoneList<Expression*>* args = expr->arguments(); | 2967 ZoneList<Expression*>* args = expr->arguments(); |
| 2964 ASSERT(args->length() == 1); | 2968 ASSERT(args->length() == 1); |
| 2965 | 2969 |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3321 | 3325 |
| 3322 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { | 3326 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
| 3323 ZoneList<Expression*>* args = expr->arguments(); | 3327 ZoneList<Expression*>* args = expr->arguments(); |
| 3324 ASSERT(args->length() == 1); | 3328 ASSERT(args->length() == 1); |
| 3325 | 3329 |
| 3326 // ArgumentsAccessStub expects the key in a1 and the formal | 3330 // ArgumentsAccessStub expects the key in a1 and the formal |
| 3327 // parameter count in a0. | 3331 // parameter count in a0. |
| 3328 VisitForAccumulatorValue(args->at(0)); | 3332 VisitForAccumulatorValue(args->at(0)); |
| 3329 __ mov(a1, v0); | 3333 __ mov(a1, v0); |
| 3330 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 3334 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| 3331 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 3335 ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); |
| 3332 __ CallStub(&stub); | 3336 __ CallStub(&stub); |
| 3333 context()->Plug(v0); | 3337 context()->Plug(v0); |
| 3334 } | 3338 } |
| 3335 | 3339 |
| 3336 | 3340 |
| 3337 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { | 3341 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
| 3338 ASSERT(expr->arguments()->length() == 0); | 3342 ASSERT(expr->arguments()->length() == 0); |
| 3339 Label exit; | 3343 Label exit; |
| 3340 // Get the number of formal parameters. | 3344 // Get the number of formal parameters. |
| 3341 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 3345 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3432 } | 3436 } |
| 3433 | 3437 |
| 3434 // Finally, we're expected to leave a value on the top of the stack. | 3438 // Finally, we're expected to leave a value on the top of the stack. |
| 3435 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3439 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| 3436 context()->Plug(v0); | 3440 context()->Plug(v0); |
| 3437 } | 3441 } |
| 3438 | 3442 |
| 3439 | 3443 |
| 3440 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3444 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3441 // Load the arguments on the stack and call the stub. | 3445 // Load the arguments on the stack and call the stub. |
| 3442 SubStringStub stub; | 3446 SubStringStub stub(isolate()); |
| 3443 ZoneList<Expression*>* args = expr->arguments(); | 3447 ZoneList<Expression*>* args = expr->arguments(); |
| 3444 ASSERT(args->length() == 3); | 3448 ASSERT(args->length() == 3); |
| 3445 VisitForStackValue(args->at(0)); | 3449 VisitForStackValue(args->at(0)); |
| 3446 VisitForStackValue(args->at(1)); | 3450 VisitForStackValue(args->at(1)); |
| 3447 VisitForStackValue(args->at(2)); | 3451 VisitForStackValue(args->at(2)); |
| 3448 __ CallStub(&stub); | 3452 __ CallStub(&stub); |
| 3449 context()->Plug(v0); | 3453 context()->Plug(v0); |
| 3450 } | 3454 } |
| 3451 | 3455 |
| 3452 | 3456 |
| 3453 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | 3457 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3454 // Load the arguments on the stack and call the stub. | 3458 // Load the arguments on the stack and call the stub. |
| 3455 RegExpExecStub stub; | 3459 RegExpExecStub stub(isolate()); |
| 3456 ZoneList<Expression*>* args = expr->arguments(); | 3460 ZoneList<Expression*>* args = expr->arguments(); |
| 3457 ASSERT(args->length() == 4); | 3461 ASSERT(args->length() == 4); |
| 3458 VisitForStackValue(args->at(0)); | 3462 VisitForStackValue(args->at(0)); |
| 3459 VisitForStackValue(args->at(1)); | 3463 VisitForStackValue(args->at(1)); |
| 3460 VisitForStackValue(args->at(2)); | 3464 VisitForStackValue(args->at(2)); |
| 3461 VisitForStackValue(args->at(3)); | 3465 VisitForStackValue(args->at(3)); |
| 3462 __ CallStub(&stub); | 3466 __ CallStub(&stub); |
| 3463 context()->Plug(v0); | 3467 context()->Plug(v0); |
| 3464 } | 3468 } |
| 3465 | 3469 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3604 context()->Plug(string); | 3608 context()->Plug(string); |
| 3605 } | 3609 } |
| 3606 | 3610 |
| 3607 | 3611 |
| 3608 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { | 3612 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 3609 // Load the arguments on the stack and call the runtime function. | 3613 // Load the arguments on the stack and call the runtime function. |
| 3610 ZoneList<Expression*>* args = expr->arguments(); | 3614 ZoneList<Expression*>* args = expr->arguments(); |
| 3611 ASSERT(args->length() == 2); | 3615 ASSERT(args->length() == 2); |
| 3612 VisitForStackValue(args->at(0)); | 3616 VisitForStackValue(args->at(0)); |
| 3613 VisitForStackValue(args->at(1)); | 3617 VisitForStackValue(args->at(1)); |
| 3614 MathPowStub stub(MathPowStub::ON_STACK); | 3618 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 3615 __ CallStub(&stub); | 3619 __ CallStub(&stub); |
| 3616 context()->Plug(v0); | 3620 context()->Plug(v0); |
| 3617 } | 3621 } |
| 3618 | 3622 |
| 3619 | 3623 |
| 3620 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 3624 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 3621 ZoneList<Expression*>* args = expr->arguments(); | 3625 ZoneList<Expression*>* args = expr->arguments(); |
| 3622 ASSERT(args->length() == 2); | 3626 ASSERT(args->length() == 2); |
| 3623 | 3627 |
| 3624 VisitForStackValue(args->at(0)); // Load the object. | 3628 VisitForStackValue(args->at(0)); // Load the object. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3647 | 3651 |
| 3648 | 3652 |
| 3649 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { | 3653 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 3650 ZoneList<Expression*>* args = expr->arguments(); | 3654 ZoneList<Expression*>* args = expr->arguments(); |
| 3651 ASSERT_EQ(args->length(), 1); | 3655 ASSERT_EQ(args->length(), 1); |
| 3652 | 3656 |
| 3653 // Load the argument into a0 and call the stub. | 3657 // Load the argument into a0 and call the stub. |
| 3654 VisitForAccumulatorValue(args->at(0)); | 3658 VisitForAccumulatorValue(args->at(0)); |
| 3655 __ mov(a0, result_register()); | 3659 __ mov(a0, result_register()); |
| 3656 | 3660 |
| 3657 NumberToStringStub stub; | 3661 NumberToStringStub stub(isolate()); |
| 3658 __ CallStub(&stub); | 3662 __ CallStub(&stub); |
| 3659 context()->Plug(v0); | 3663 context()->Plug(v0); |
| 3660 } | 3664 } |
| 3661 | 3665 |
| 3662 | 3666 |
| 3663 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 3667 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 3664 ZoneList<Expression*>* args = expr->arguments(); | 3668 ZoneList<Expression*>* args = expr->arguments(); |
| 3665 ASSERT(args->length() == 1); | 3669 ASSERT(args->length() == 1); |
| 3666 | 3670 |
| 3667 VisitForAccumulatorValue(args->at(0)); | 3671 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3776 | 3780 |
| 3777 | 3781 |
| 3778 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { | 3782 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
| 3779 ZoneList<Expression*>* args = expr->arguments(); | 3783 ZoneList<Expression*>* args = expr->arguments(); |
| 3780 ASSERT_EQ(2, args->length()); | 3784 ASSERT_EQ(2, args->length()); |
| 3781 VisitForStackValue(args->at(0)); | 3785 VisitForStackValue(args->at(0)); |
| 3782 VisitForAccumulatorValue(args->at(1)); | 3786 VisitForAccumulatorValue(args->at(1)); |
| 3783 | 3787 |
| 3784 __ pop(a1); | 3788 __ pop(a1); |
| 3785 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. | 3789 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. |
| 3786 StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED); | 3790 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
| 3787 __ CallStub(&stub); | 3791 __ CallStub(&stub); |
| 3788 context()->Plug(v0); | 3792 context()->Plug(v0); |
| 3789 } | 3793 } |
| 3790 | 3794 |
| 3791 | 3795 |
| 3792 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { | 3796 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 3793 ZoneList<Expression*>* args = expr->arguments(); | 3797 ZoneList<Expression*>* args = expr->arguments(); |
| 3794 ASSERT_EQ(2, args->length()); | 3798 ASSERT_EQ(2, args->length()); |
| 3795 | 3799 |
| 3796 VisitForStackValue(args->at(0)); | 3800 VisitForStackValue(args->at(0)); |
| 3797 VisitForStackValue(args->at(1)); | 3801 VisitForStackValue(args->at(1)); |
| 3798 | 3802 |
| 3799 StringCompareStub stub; | 3803 StringCompareStub stub(isolate()); |
| 3800 __ CallStub(&stub); | 3804 __ CallStub(&stub); |
| 3801 context()->Plug(v0); | 3805 context()->Plug(v0); |
| 3802 } | 3806 } |
| 3803 | 3807 |
| 3804 | 3808 |
| 3805 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 3809 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3806 ZoneList<Expression*>* args = expr->arguments(); | 3810 ZoneList<Expression*>* args = expr->arguments(); |
| 3807 ASSERT(args->length() >= 2); | 3811 ASSERT(args->length() >= 2); |
| 3808 | 3812 |
| 3809 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3813 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3828 __ bind(&runtime); | 3832 __ bind(&runtime); |
| 3829 __ push(v0); | 3833 __ push(v0); |
| 3830 __ CallRuntime(Runtime::kCall, args->length()); | 3834 __ CallRuntime(Runtime::kCall, args->length()); |
| 3831 __ bind(&done); | 3835 __ bind(&done); |
| 3832 | 3836 |
| 3833 context()->Plug(v0); | 3837 context()->Plug(v0); |
| 3834 } | 3838 } |
| 3835 | 3839 |
| 3836 | 3840 |
| 3837 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { | 3841 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
| 3838 RegExpConstructResultStub stub; | 3842 RegExpConstructResultStub stub(isolate()); |
| 3839 ZoneList<Expression*>* args = expr->arguments(); | 3843 ZoneList<Expression*>* args = expr->arguments(); |
| 3840 ASSERT(args->length() == 3); | 3844 ASSERT(args->length() == 3); |
| 3841 VisitForStackValue(args->at(0)); | 3845 VisitForStackValue(args->at(0)); |
| 3842 VisitForStackValue(args->at(1)); | 3846 VisitForStackValue(args->at(1)); |
| 3843 VisitForAccumulatorValue(args->at(2)); | 3847 VisitForAccumulatorValue(args->at(2)); |
| 3844 __ mov(a0, result_register()); | 3848 __ mov(a0, result_register()); |
| 3845 __ pop(a1); | 3849 __ pop(a1); |
| 3846 __ pop(a2); | 3850 __ pop(a2); |
| 3847 __ CallStub(&stub); | 3851 __ CallStub(&stub); |
| 3848 context()->Plug(v0); | 3852 context()->Plug(v0); |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4203 __ sw(v0, MemOperand(sp, kPointerSize)); | 4207 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 4204 | 4208 |
| 4205 // Push the arguments ("left-to-right"). | 4209 // Push the arguments ("left-to-right"). |
| 4206 int arg_count = args->length(); | 4210 int arg_count = args->length(); |
| 4207 for (int i = 0; i < arg_count; i++) { | 4211 for (int i = 0; i < arg_count; i++) { |
| 4208 VisitForStackValue(args->at(i)); | 4212 VisitForStackValue(args->at(i)); |
| 4209 } | 4213 } |
| 4210 | 4214 |
| 4211 // Record source position of the IC call. | 4215 // Record source position of the IC call. |
| 4212 SetSourcePosition(expr->position()); | 4216 SetSourcePosition(expr->position()); |
| 4213 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 4217 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4214 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 4218 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 4215 __ CallStub(&stub); | 4219 __ CallStub(&stub); |
| 4216 | 4220 |
| 4217 // Restore context register. | 4221 // Restore context register. |
| 4218 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4222 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4219 | 4223 |
| 4220 context()->DropAndPlug(1, v0); | 4224 context()->DropAndPlug(1, v0); |
| 4221 } else { | 4225 } else { |
| 4222 // Push the arguments ("left-to-right"). | 4226 // Push the arguments ("left-to-right"). |
| 4223 for (int i = 0; i < arg_count; i++) { | 4227 for (int i = 0; i < arg_count; i++) { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4425 Register scratch1 = a1; | 4429 Register scratch1 = a1; |
| 4426 Register scratch2 = t0; | 4430 Register scratch2 = t0; |
| 4427 __ li(scratch1, Operand(Smi::FromInt(count_value))); | 4431 __ li(scratch1, Operand(Smi::FromInt(count_value))); |
| 4428 __ AdduAndCheckForOverflow(v0, v0, scratch1, scratch2); | 4432 __ AdduAndCheckForOverflow(v0, v0, scratch1, scratch2); |
| 4429 __ BranchOnNoOverflow(&done, scratch2); | 4433 __ BranchOnNoOverflow(&done, scratch2); |
| 4430 // Call stub. Undo operation first. | 4434 // Call stub. Undo operation first. |
| 4431 __ Move(v0, a0); | 4435 __ Move(v0, a0); |
| 4432 __ jmp(&stub_call); | 4436 __ jmp(&stub_call); |
| 4433 __ bind(&slow); | 4437 __ bind(&slow); |
| 4434 } | 4438 } |
| 4435 ToNumberStub convert_stub; | 4439 ToNumberStub convert_stub(isolate()); |
| 4436 __ CallStub(&convert_stub); | 4440 __ CallStub(&convert_stub); |
| 4437 | 4441 |
| 4438 // Save result for postfix expressions. | 4442 // Save result for postfix expressions. |
| 4439 if (expr->is_postfix()) { | 4443 if (expr->is_postfix()) { |
| 4440 if (!context()->IsEffect()) { | 4444 if (!context()->IsEffect()) { |
| 4441 // Save the result on the stack. If we have a named or keyed property | 4445 // Save the result on the stack. If we have a named or keyed property |
| 4442 // we store the result under the receiver that is currently on top | 4446 // we store the result under the receiver that is currently on top |
| 4443 // of the stack. | 4447 // of the stack. |
| 4444 switch (assign_type) { | 4448 switch (assign_type) { |
| 4445 case VARIABLE: | 4449 case VARIABLE: |
| 4446 __ push(v0); | 4450 __ push(v0); |
| 4447 break; | 4451 break; |
| 4448 case NAMED_PROPERTY: | 4452 case NAMED_PROPERTY: |
| 4449 __ sw(v0, MemOperand(sp, kPointerSize)); | 4453 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 4450 break; | 4454 break; |
| 4451 case KEYED_PROPERTY: | 4455 case KEYED_PROPERTY: |
| 4452 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | 4456 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
| 4453 break; | 4457 break; |
| 4454 } | 4458 } |
| 4455 } | 4459 } |
| 4456 } | 4460 } |
| 4457 | 4461 |
| 4458 __ bind(&stub_call); | 4462 __ bind(&stub_call); |
| 4459 __ mov(a1, v0); | 4463 __ mov(a1, v0); |
| 4460 __ li(a0, Operand(Smi::FromInt(count_value))); | 4464 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 4461 | 4465 |
| 4462 // Record position before stub call. | 4466 // Record position before stub call. |
| 4463 SetSourcePosition(expr->position()); | 4467 SetSourcePosition(expr->position()); |
| 4464 | 4468 |
| 4465 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); | 4469 BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE); |
| 4466 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); | 4470 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); |
| 4467 patch_site.EmitPatchInfo(); | 4471 patch_site.EmitPatchInfo(); |
| 4468 __ bind(&done); | 4472 __ bind(&done); |
| 4469 | 4473 |
| 4470 // Store the value returned in v0. | 4474 // Store the value returned in v0. |
| 4471 switch (assign_type) { | 4475 switch (assign_type) { |
| 4472 case VARIABLE: | 4476 case VARIABLE: |
| 4473 if (expr->is_postfix()) { | 4477 if (expr->is_postfix()) { |
| 4474 { EffectContext context(this); | 4478 { EffectContext context(this); |
| 4475 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4479 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4664 case Token::IN: | 4668 case Token::IN: |
| 4665 VisitForStackValue(expr->right()); | 4669 VisitForStackValue(expr->right()); |
| 4666 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4670 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 4667 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 4671 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 4668 __ LoadRoot(t0, Heap::kTrueValueRootIndex); | 4672 __ LoadRoot(t0, Heap::kTrueValueRootIndex); |
| 4669 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); | 4673 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); |
| 4670 break; | 4674 break; |
| 4671 | 4675 |
| 4672 case Token::INSTANCEOF: { | 4676 case Token::INSTANCEOF: { |
| 4673 VisitForStackValue(expr->right()); | 4677 VisitForStackValue(expr->right()); |
| 4674 InstanceofStub stub(InstanceofStub::kNoFlags); | 4678 InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); |
| 4675 __ CallStub(&stub); | 4679 __ CallStub(&stub); |
| 4676 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4680 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4677 // The stub returns 0 for true. | 4681 // The stub returns 0 for true. |
| 4678 Split(eq, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4682 Split(eq, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4679 break; | 4683 break; |
| 4680 } | 4684 } |
| 4681 | 4685 |
| 4682 default: { | 4686 default: { |
| 4683 VisitForAccumulatorValue(expr->right()); | 4687 VisitForAccumulatorValue(expr->right()); |
| 4684 Condition cc = CompareIC::ComputeCondition(op); | 4688 Condition cc = CompareIC::ComputeCondition(op); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4962 Assembler::target_address_at(pc_immediate_load_address)) == | 4966 Assembler::target_address_at(pc_immediate_load_address)) == |
| 4963 reinterpret_cast<uint32_t>( | 4967 reinterpret_cast<uint32_t>( |
| 4964 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4968 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4965 return OSR_AFTER_STACK_CHECK; | 4969 return OSR_AFTER_STACK_CHECK; |
| 4966 } | 4970 } |
| 4967 | 4971 |
| 4968 | 4972 |
| 4969 } } // namespace v8::internal | 4973 } } // namespace v8::internal |
| 4970 | 4974 |
| 4971 #endif // V8_TARGET_ARCH_MIPS | 4975 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |