OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 } | 279 } |
280 | 280 |
281 | 281 |
282 // Input parameters: | 282 // Input parameters: |
283 // R4: arguments descriptor array. | 283 // R4: arguments descriptor array. |
284 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 284 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
285 // Create a stub frame as we are pushing some objects on the stack before | 285 // Create a stub frame as we are pushing some objects on the stack before |
286 // calling into the runtime. | 286 // calling into the runtime. |
287 __ EnterStubFrame(); | 287 __ EnterStubFrame(); |
288 // Setup space on stack for return value and preserve arguments descriptor. | 288 // Setup space on stack for return value and preserve arguments descriptor. |
289 __ LoadObject(R0, Object::null_object()); | 289 __ LoadImmediate(R0, 0); |
290 __ PushList((1 << R0) | (1 << R4)); | 290 __ PushList((1 << R0) | (1 << R4)); |
291 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 291 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
292 // Get Code object result and restore arguments descriptor array. | 292 // Get Code object result and restore arguments descriptor array. |
293 __ PopList((1 << R0) | (1 << R4)); | 293 __ PopList((1 << R0) | (1 << R4)); |
294 // Remove the stub frame. | 294 // Remove the stub frame. |
295 __ LeaveStubFrame(); | 295 __ LeaveStubFrame(); |
296 // Jump to the dart function. | 296 // Jump to the dart function. |
297 __ mov(CODE_REG, Operand(R0)); | 297 __ mov(CODE_REG, Operand(R0)); |
298 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 298 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
299 __ bx(R0); | 299 __ bx(R0); |
300 } | 300 } |
301 | 301 |
302 | 302 |
303 // Called from a static call only when an invalid code has been entered | 303 // Called from a static call only when an invalid code has been entered |
304 // (invalid because its function was optimized or deoptimized). | 304 // (invalid because its function was optimized or deoptimized). |
305 // R4: arguments descriptor array. | 305 // R4: arguments descriptor array. |
306 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 306 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
307 // Load code pointer to this stub from the thread: | 307 // Load code pointer to this stub from the thread: |
308 // The one that is passed in, is not correct - it points to the code object | 308 // The one that is passed in, is not correct - it points to the code object |
309 // that needs to be replaced. | 309 // that needs to be replaced. |
310 __ ldr(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset())); | 310 __ ldr(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset())); |
311 // Create a stub frame as we are pushing some objects on the stack before | 311 // Create a stub frame as we are pushing some objects on the stack before |
312 // calling into the runtime. | 312 // calling into the runtime. |
313 __ EnterStubFrame(); | 313 __ EnterStubFrame(); |
314 // Setup space on stack for return value and preserve arguments descriptor. | 314 // Setup space on stack for return value and preserve arguments descriptor. |
315 __ LoadObject(R0, Object::null_object()); | 315 __ LoadImmediate(R0, 0); |
316 __ PushList((1 << R0) | (1 << R4)); | 316 __ PushList((1 << R0) | (1 << R4)); |
317 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 317 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
318 // Get Code object result and restore arguments descriptor array. | 318 // Get Code object result and restore arguments descriptor array. |
319 __ PopList((1 << R0) | (1 << R4)); | 319 __ PopList((1 << R0) | (1 << R4)); |
320 // Remove the stub frame. | 320 // Remove the stub frame. |
321 __ LeaveStubFrame(); | 321 __ LeaveStubFrame(); |
322 // Jump to the dart function. | 322 // Jump to the dart function. |
323 __ mov(CODE_REG, Operand(R0)); | 323 __ mov(CODE_REG, Operand(R0)); |
324 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 324 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
325 __ bx(R0); | 325 __ bx(R0); |
326 } | 326 } |
327 | 327 |
328 | 328 |
329 // Called from object allocate instruction when the allocation stub has been | 329 // Called from object allocate instruction when the allocation stub has been |
330 // disabled. | 330 // disabled. |
331 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 331 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
332 // Load code pointer to this stub from the thread: | 332 // Load code pointer to this stub from the thread: |
333 // The one that is passed in, is not correct - it points to the code object | 333 // The one that is passed in, is not correct - it points to the code object |
334 // that needs to be replaced. | 334 // that needs to be replaced. |
335 __ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset())); | 335 __ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset())); |
336 __ EnterStubFrame(); | 336 __ EnterStubFrame(); |
337 // Setup space on stack for return value. | 337 // Setup space on stack for return value. |
338 __ LoadObject(R0, Object::null_object()); | 338 __ LoadImmediate(R0, 0); |
339 __ Push(R0); | 339 __ Push(R0); |
340 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 340 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
341 // Get Code object result. | 341 // Get Code object result. |
342 __ Pop(R0); | 342 __ Pop(R0); |
343 // Remove the stub frame. | 343 // Remove the stub frame. |
344 __ LeaveStubFrame(); | 344 __ LeaveStubFrame(); |
345 // Jump to the dart function. | 345 // Jump to the dart function. |
346 __ mov(CODE_REG, Operand(R0)); | 346 __ mov(CODE_REG, Operand(R0)); |
347 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 347 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
348 __ bx(R0); | 348 __ bx(R0); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 __ Comment("NoSuchMethodDispatch"); | 535 __ Comment("NoSuchMethodDispatch"); |
536 // When lazily generated invocation dispatchers are disabled, the | 536 // When lazily generated invocation dispatchers are disabled, the |
537 // miss-handler may return null. | 537 // miss-handler may return null. |
538 __ CompareObject(R0, Object::null_object()); | 538 __ CompareObject(R0, Object::null_object()); |
539 __ b(call_target_function, NE); | 539 __ b(call_target_function, NE); |
540 __ EnterStubFrame(); | 540 __ EnterStubFrame(); |
541 // Load the receiver. | 541 // Load the receiver. |
542 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 542 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
543 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. | 543 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. |
544 __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize)); | 544 __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize)); |
545 __ PushObject(Object::null_object()); | 545 __ LoadImmediate(IP, 0); |
| 546 __ Push(IP); // Result slot. |
546 __ Push(R8); // Receiver. | 547 __ Push(R8); // Receiver. |
547 __ Push(R9); // ICData/MegamorphicCache. | 548 __ Push(R9); // ICData/MegamorphicCache. |
548 __ Push(R4); // Arguments descriptor. | 549 __ Push(R4); // Arguments descriptor. |
549 // R2: Smi-tagged arguments array length. | 550 // R2: Smi-tagged arguments array length. |
550 PushArgumentsArray(assembler); | 551 PushArgumentsArray(assembler); |
551 const intptr_t kNumArgs = 4; | 552 const intptr_t kNumArgs = 4; |
552 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 553 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); |
553 __ Drop(4); | 554 __ Drop(4); |
554 __ Pop(R0); // Return value. | 555 __ Pop(R0); // Return value. |
555 __ LeaveStubFrame(); | 556 __ LeaveStubFrame(); |
556 __ Ret(); | 557 __ Ret(); |
557 } | 558 } |
558 | 559 |
559 | 560 |
560 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 561 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
561 __ EnterStubFrame(); | 562 __ EnterStubFrame(); |
562 | 563 |
563 // Load the receiver. | 564 // Load the receiver. |
564 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 565 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
565 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. | 566 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. |
566 __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize)); | 567 __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize)); |
567 | 568 |
568 // Preserve IC data and arguments descriptor. | 569 // Preserve IC data and arguments descriptor. |
569 __ PushList((1 << R4) | (1 << R9)); | 570 __ PushList((1 << R4) | (1 << R9)); |
570 | 571 |
571 __ LoadObject(IP, Object::null_object()); | 572 __ LoadImmediate(IP, 0); |
572 __ Push(IP); // result | 573 __ Push(IP); // result slot |
573 __ Push(R8); // receiver | 574 __ Push(R8); // receiver |
574 __ Push(R9); // ICData | 575 __ Push(R9); // ICData |
575 __ Push(R4); // arguments descriptor | 576 __ Push(R4); // arguments descriptor |
576 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 577 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
577 // Remove arguments. | 578 // Remove arguments. |
578 __ Drop(3); | 579 __ Drop(3); |
579 __ Pop(R0); // Get result into R0 (target function). | 580 __ Pop(R0); // Get result into R0 (target function). |
580 | 581 |
581 // Restore IC data and arguments descriptor. | 582 // Restore IC data and arguments descriptor. |
582 __ PopList((1 << R4) | (1 << R9)); | 583 __ PopList((1 << R4) | (1 << R9)); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag); | 704 __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag); |
704 __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9); | 705 __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9); |
705 __ Ret(); // Returns the newly allocated object in R0. | 706 __ Ret(); // Returns the newly allocated object in R0. |
706 // Unable to allocate the array using the fast inline code, just call | 707 // Unable to allocate the array using the fast inline code, just call |
707 // into the runtime. | 708 // into the runtime. |
708 __ Bind(&slow_case); | 709 __ Bind(&slow_case); |
709 | 710 |
710 // Create a stub frame as we are pushing some objects on the stack before | 711 // Create a stub frame as we are pushing some objects on the stack before |
711 // calling into the runtime. | 712 // calling into the runtime. |
712 __ EnterStubFrame(); | 713 __ EnterStubFrame(); |
713 __ LoadObject(IP, Object::null_object()); | 714 __ LoadImmediate(IP, 0); |
714 // Setup space on stack for return value. | 715 // Setup space on stack for return value. |
715 // Push array length as Smi and element type. | 716 // Push array length as Smi and element type. |
716 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); | 717 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); |
717 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 718 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
718 // Pop arguments; result is popped in IP. | 719 // Pop arguments; result is popped in IP. |
719 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. | 720 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. |
720 __ mov(R0, Operand(IP)); | 721 __ mov(R0, Operand(IP)); |
721 __ LeaveStubFrame(); | 722 __ LeaveStubFrame(); |
722 __ Ret(); | 723 __ Ret(); |
723 } | 724 } |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 // Done allocating and initializing the context. | 946 // Done allocating and initializing the context. |
946 // R0: new object. | 947 // R0: new object. |
947 __ Ret(); | 948 __ Ret(); |
948 | 949 |
949 __ Bind(&slow_case); | 950 __ Bind(&slow_case); |
950 } | 951 } |
951 // Create a stub frame as we are pushing some objects on the stack before | 952 // Create a stub frame as we are pushing some objects on the stack before |
952 // calling into the runtime. | 953 // calling into the runtime. |
953 __ EnterStubFrame(); | 954 __ EnterStubFrame(); |
954 // Setup space on stack for return value. | 955 // Setup space on stack for return value. |
955 __ LoadObject(R2, Object::null_object()); | 956 __ LoadImmediate(R2, 0); |
956 __ SmiTag(R1); | 957 __ SmiTag(R1); |
957 __ PushList((1 << R1) | (1 << R2)); | 958 __ PushList((1 << R1) | (1 << R2)); |
958 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. | 959 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
959 __ Drop(1); // Pop number of context variables argument. | 960 __ Drop(1); // Pop number of context variables argument. |
960 __ Pop(R0); // Pop the new context object. | 961 __ Pop(R0); // Pop the new context object. |
961 // R0: new object | 962 // R0: new object |
962 // Restore the frame pointer. | 963 // Restore the frame pointer. |
963 __ LeaveStubFrame(); | 964 __ LeaveStubFrame(); |
964 __ Ret(); | 965 __ Ret(); |
965 } | 966 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 __ EnterStubFrame(); | 1187 __ EnterStubFrame(); |
1187 | 1188 |
1188 // Load the receiver. | 1189 // Load the receiver. |
1189 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 1190 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
1190 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. | 1191 __ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi. |
1191 __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize)); | 1192 __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize)); |
1192 | 1193 |
1193 // Push space for the return value. | 1194 // Push space for the return value. |
1194 // Push the receiver. | 1195 // Push the receiver. |
1195 // Push arguments descriptor array. | 1196 // Push arguments descriptor array. |
1196 __ LoadObject(IP, Object::null_object()); | 1197 __ LoadImmediate(IP, 0); |
1197 __ PushList((1 << R4) | (1 << R8) | (1 << IP)); | 1198 __ PushList((1 << R4) | (1 << R8) | (1 << IP)); |
1198 | 1199 |
1199 // R2: Smi-tagged arguments array length. | 1200 // R2: Smi-tagged arguments array length. |
1200 PushArgumentsArray(assembler); | 1201 PushArgumentsArray(assembler); |
1201 | 1202 |
1202 const intptr_t kNumArgs = 3; | 1203 const intptr_t kNumArgs = 3; |
1203 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); | 1204 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); |
1204 // noSuchMethod on closures always throws an error, so it will never return. | 1205 // noSuchMethod on closures always throws an error, so it will never return. |
1205 __ bkpt(0); | 1206 __ bkpt(0); |
1206 } | 1207 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 __ b(&loop, NE); | 1416 __ b(&loop, NE); |
1416 | 1417 |
1417 __ Comment("IC miss"); | 1418 __ Comment("IC miss"); |
1418 // Compute address of arguments. | 1419 // Compute address of arguments. |
1419 // NOTFP: argument_count - 1 (smi). | 1420 // NOTFP: argument_count - 1 (smi). |
1420 __ add(NOTFP, SP, Operand(NOTFP, LSL, 1)); // NOTFP is Smi. | 1421 __ add(NOTFP, SP, Operand(NOTFP, LSL, 1)); // NOTFP is Smi. |
1421 // NOTFP: address of receiver. | 1422 // NOTFP: address of receiver. |
1422 // Create a stub frame as we are pushing some objects on the stack before | 1423 // Create a stub frame as we are pushing some objects on the stack before |
1423 // calling into the runtime. | 1424 // calling into the runtime. |
1424 __ EnterStubFrame(); | 1425 __ EnterStubFrame(); |
1425 __ LoadObject(R0, Object::null_object()); | 1426 __ LoadImmediate(R0, 0); |
1426 // Preserve IC data object and arguments descriptor array and | 1427 // Preserve IC data object and arguments descriptor array and |
1427 // setup space on stack for result (target code object). | 1428 // setup space on stack for result (target code object). |
1428 __ PushList((1 << R0) | (1 << R4) | (1 << R9)); | 1429 __ PushList((1 << R0) | (1 << R4) | (1 << R9)); |
1429 // Push call arguments. | 1430 // Push call arguments. |
1430 for (intptr_t i = 0; i < num_args; i++) { | 1431 for (intptr_t i = 0; i < num_args; i++) { |
1431 __ LoadFromOffset(kWord, IP, NOTFP, -i * kWordSize); | 1432 __ LoadFromOffset(kWord, IP, NOTFP, -i * kWordSize); |
1432 __ Push(IP); | 1433 __ Push(IP); |
1433 } | 1434 } |
1434 // Pass IC data object. | 1435 // Pass IC data object. |
1435 __ Push(R9); | 1436 __ Push(R9); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 | 1649 |
1649 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); | 1650 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); |
1650 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset())); | 1651 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset())); |
1651 __ bx(R2); | 1652 __ bx(R2); |
1652 } | 1653 } |
1653 | 1654 |
1654 | 1655 |
1655 // R9: Contains an ICData. | 1656 // R9: Contains an ICData. |
1656 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1657 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
1657 __ EnterStubFrame(); | 1658 __ EnterStubFrame(); |
1658 __ LoadObject(R0, Object::null_object()); | 1659 __ LoadImmediate(R0, 0); |
1659 // Preserve arguments descriptor and make room for result. | 1660 // Preserve arguments descriptor and make room for result. |
1660 __ PushList((1 << R0) | (1 << R9)); | 1661 __ PushList((1 << R0) | (1 << R9)); |
1661 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1662 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1662 __ PopList((1 << R0) | (1 << R9)); | 1663 __ PopList((1 << R0) | (1 << R9)); |
1663 __ LeaveStubFrame(); | 1664 __ LeaveStubFrame(); |
1664 __ mov(CODE_REG, Operand(R0)); | 1665 __ mov(CODE_REG, Operand(R0)); |
1665 __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset())); | 1666 __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset())); |
1666 __ bx(R0); | 1667 __ bx(R0); |
1667 } | 1668 } |
1668 | 1669 |
1669 | 1670 |
1670 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { | 1671 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { |
1671 __ EnterStubFrame(); | 1672 __ EnterStubFrame(); |
1672 __ LoadObject(R0, Object::null_object()); | 1673 __ LoadImmediate(R0, 0); |
1673 // Make room for result. | 1674 // Make room for result. |
1674 __ PushList((1 << R0)); | 1675 __ PushList((1 << R0)); |
1675 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1676 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1676 __ PopList((1 << CODE_REG)); | 1677 __ PopList((1 << CODE_REG)); |
1677 __ LeaveStubFrame(); | 1678 __ LeaveStubFrame(); |
1678 __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset())); | 1679 __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset())); |
1679 __ bx(R0); | 1680 __ bx(R0); |
1680 } | 1681 } |
1681 | 1682 |
1682 | 1683 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 __ bx(LR); // Jump to the exception handler code. | 1845 __ bx(LR); // Jump to the exception handler code. |
1845 } | 1846 } |
1846 | 1847 |
1847 | 1848 |
1848 // Calls to the runtime to optimize the given function. | 1849 // Calls to the runtime to optimize the given function. |
1849 // R8: function to be reoptimized. | 1850 // R8: function to be reoptimized. |
1850 // R4: argument descriptor (preserved). | 1851 // R4: argument descriptor (preserved). |
1851 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1852 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
1852 __ EnterStubFrame(); | 1853 __ EnterStubFrame(); |
1853 __ Push(R4); | 1854 __ Push(R4); |
1854 __ LoadObject(IP, Object::null_object()); | 1855 __ LoadImmediate(IP, 0); |
1855 __ Push(IP); // Setup space on stack for return value. | 1856 __ Push(IP); // Setup space on stack for return value. |
1856 __ Push(R8); | 1857 __ Push(R8); |
1857 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1858 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
1858 __ Pop(R0); // Discard argument. | 1859 __ Pop(R0); // Discard argument. |
1859 __ Pop(R0); // Get Code object | 1860 __ Pop(R0); // Get Code object |
1860 __ Pop(R4); // Restore argument descriptor. | 1861 __ Pop(R4); // Restore argument descriptor. |
1861 __ LeaveStubFrame(); | 1862 __ LeaveStubFrame(); |
1862 __ mov(CODE_REG, Operand(R0)); | 1863 __ mov(CODE_REG, Operand(R0)); |
1863 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); | 1864 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset())); |
1864 __ bx(R0); | 1865 __ bx(R0); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2125 | 2126 |
2126 // Called from switchable IC calls. | 2127 // Called from switchable IC calls. |
2127 // R0: receiver | 2128 // R0: receiver |
2128 // R9: UnlinkedCall | 2129 // R9: UnlinkedCall |
2129 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { | 2130 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { |
2130 __ NoMonomorphicCheckedEntry(); | 2131 __ NoMonomorphicCheckedEntry(); |
2131 | 2132 |
2132 __ EnterStubFrame(); | 2133 __ EnterStubFrame(); |
2133 __ Push(R0); // Preserve receiver. | 2134 __ Push(R0); // Preserve receiver. |
2134 | 2135 |
2135 __ PushObject(Object::null_object()); // Result. | 2136 __ LoadImmediate(IP, 0); |
2136 __ Push(R0); // Arg0: Receiver | 2137 __ Push(IP); // Result slot |
2137 __ Push(R9); // Arg1: UnlinkedCall | 2138 __ Push(R0); // Arg0: Receiver |
| 2139 __ Push(R9); // Arg1: UnlinkedCall |
2138 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); | 2140 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); |
2139 __ Drop(2); | 2141 __ Drop(2); |
2140 __ Pop(R9); // result = IC | 2142 __ Pop(R9); // result = IC |
2141 | 2143 |
2142 __ Pop(R0); // Restore receiver. | 2144 __ Pop(R0); // Restore receiver. |
2143 __ LeaveStubFrame(); | 2145 __ LeaveStubFrame(); |
2144 | 2146 |
2145 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2147 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
2146 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2148 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
2147 __ bx(R1); | 2149 __ bx(R1); |
(...skipping 20 matching lines...) Expand all Loading... |
2168 __ b(&miss, GT); | 2170 __ b(&miss, GT); |
2169 | 2171 |
2170 __ ldr(R1, FieldAddress(R9, SingleTargetCache::entry_point_offset())); | 2172 __ ldr(R1, FieldAddress(R9, SingleTargetCache::entry_point_offset())); |
2171 __ ldr(CODE_REG, FieldAddress(R9, SingleTargetCache::target_offset())); | 2173 __ ldr(CODE_REG, FieldAddress(R9, SingleTargetCache::target_offset())); |
2172 __ bx(R1); | 2174 __ bx(R1); |
2173 | 2175 |
2174 __ Bind(&miss); | 2176 __ Bind(&miss); |
2175 __ EnterStubFrame(); | 2177 __ EnterStubFrame(); |
2176 __ Push(R0); // Preserve receiver. | 2178 __ Push(R0); // Preserve receiver. |
2177 | 2179 |
2178 __ PushObject(Object::null_object()); // Result. | 2180 __ LoadImmediate(IP, 0); |
2179 __ Push(R0); // Arg0: Receiver | 2181 __ Push(IP); // Result slot |
| 2182 __ Push(R0); // Arg0: Receiver |
2180 __ CallRuntime(kSingleTargetMissRuntimeEntry, 1); | 2183 __ CallRuntime(kSingleTargetMissRuntimeEntry, 1); |
2181 __ Drop(1); | 2184 __ Drop(1); |
2182 __ Pop(R9); // result = IC | 2185 __ Pop(R9); // result = IC |
2183 | 2186 |
2184 __ Pop(R0); // Restore receiver. | 2187 __ Pop(R0); // Restore receiver. |
2185 __ LeaveStubFrame(); | 2188 __ LeaveStubFrame(); |
2186 | 2189 |
2187 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2190 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
2188 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2191 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
2189 __ bx(R1); | 2192 __ bx(R1); |
2190 } | 2193 } |
2191 | 2194 |
2192 | 2195 |
2193 // Called from the monomorphic checked entry. | 2196 // Called from the monomorphic checked entry. |
2194 // R0: receiver | 2197 // R0: receiver |
2195 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { | 2198 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { |
2196 __ EnterStubFrame(); | 2199 __ EnterStubFrame(); |
2197 __ Push(R0); // Preserve receiver. | 2200 __ Push(R0); // Preserve receiver. |
2198 | 2201 |
2199 __ PushObject(Object::null_object()); // Result. | 2202 __ LoadImmediate(IP, 0); |
2200 __ Push(R0); // Arg0: Receiver | 2203 __ Push(IP); // Result slot |
| 2204 __ Push(R0); // Arg0: Receiver |
2201 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); | 2205 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); |
2202 __ Drop(1); | 2206 __ Drop(1); |
2203 __ Pop(R9); // result = IC | 2207 __ Pop(R9); // result = IC |
2204 | 2208 |
2205 __ Pop(R0); // Restore receiver. | 2209 __ Pop(R0); // Restore receiver. |
2206 __ LeaveStubFrame(); | 2210 __ LeaveStubFrame(); |
2207 | 2211 |
2208 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2212 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
2209 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2213 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
2210 __ bx(R1); | 2214 __ bx(R1); |
2211 } | 2215 } |
2212 | 2216 |
2213 | 2217 |
2214 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2218 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
2215 __ bkpt(0); | 2219 __ bkpt(0); |
2216 } | 2220 } |
2217 | 2221 |
2218 } // namespace dart | 2222 } // namespace dart |
2219 | 2223 |
2220 #endif // defined TARGET_ARCH_ARM | 2224 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |