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