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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 193 |
194 __ mov(R1, Operand(R5)); // Pass the function entrypoint to call. | 194 __ mov(R1, Operand(R5)); // Pass the function entrypoint to call. |
195 // Call native function invocation wrapper or redirection via simulator. | 195 // Call native function invocation wrapper or redirection via simulator. |
196 #if defined(USING_SIMULATOR) | 196 #if defined(USING_SIMULATOR) |
197 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); | 197 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); |
198 entry = Simulator::RedirectExternalReference( | 198 entry = Simulator::RedirectExternalReference( |
199 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); | 199 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
200 __ LoadImmediate(R2, entry); | 200 __ LoadImmediate(R2, entry); |
201 __ blx(R2); | 201 __ blx(R2); |
202 #else | 202 #else |
203 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); | 203 __ BranchLink(&NativeEntry::NativeCallWrapperLabel(), kNotPatchable); |
204 #endif | 204 #endif |
205 | 205 |
206 // Mark that the isolate is executing Dart code. | 206 // Mark that the isolate is executing Dart code. |
207 __ LoadImmediate(R2, VMTag::kDartTagId); | 207 __ LoadImmediate(R2, VMTag::kDartTagId); |
208 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); | 208 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
209 | 209 |
210 // Reset exit frame information in Isolate structure. | 210 // Reset exit frame information in Isolate structure. |
211 __ LoadImmediate(R2, 0); | 211 __ LoadImmediate(R2, 0); |
212 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); | 212 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); |
213 | 213 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 __ eor(IP, IP, Operand(LR)); | 420 __ eor(IP, IP, Operand(LR)); |
421 | 421 |
422 // Set up the frame manually. We can't use EnterFrame because we can't | 422 // Set up the frame manually. We can't use EnterFrame because we can't |
423 // clobber LR (or any other register) with 0, yet. | 423 // clobber LR (or any other register) with 0, yet. |
424 __ sub(SP, SP, Operand(kWordSize)); // Make room for PC marker of 0. | 424 __ sub(SP, SP, Operand(kWordSize)); // Make room for PC marker of 0. |
425 __ Push(IP); // Push return address. | 425 __ Push(IP); // Push return address. |
426 __ Push(FP); | 426 __ Push(FP); |
427 __ mov(FP, Operand(SP)); | 427 __ mov(FP, Operand(SP)); |
428 __ Push(PP); | 428 __ Push(PP); |
429 | 429 |
| 430 __ LoadPoolPointer(); |
| 431 |
430 // Now that IP holding the return address has been written to the stack, | 432 // Now that IP holding the return address has been written to the stack, |
431 // we can clobber it with 0 to write the null PC marker. | 433 // we can clobber it with 0 to write the null PC marker. |
432 __ mov(IP, Operand(0)); | 434 __ mov(IP, Operand(0)); |
433 __ str(IP, Address(SP, +3 * kWordSize)); | 435 __ str(IP, Address(SP, +3 * kWordSize)); |
434 | 436 |
435 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry | 437 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry |
436 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. | 438 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. |
437 const intptr_t saved_result_slot_from_fp = | 439 const intptr_t saved_result_slot_from_fp = |
438 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0); | 440 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0); |
439 // Result in R0 is preserved as part of pushing all registers below. | 441 // Result in R0 is preserved as part of pushing all registers below. |
(...skipping 22 matching lines...) Expand all Loading... |
462 if (preserve_result) { | 464 if (preserve_result) { |
463 // Restore result into R1 temporarily. | 465 // Restore result into R1 temporarily. |
464 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); | 466 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); |
465 } | 467 } |
466 | 468 |
467 __ LeaveDartFrame(); | 469 __ LeaveDartFrame(); |
468 __ sub(SP, FP, Operand(R0)); | 470 __ sub(SP, FP, Operand(R0)); |
469 | 471 |
470 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there | 472 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
471 // is no need to set the correct PC marker or load PP, since they get patched. | 473 // is no need to set the correct PC marker or load PP, since they get patched. |
472 __ mov(IP, Operand(LR)); | 474 __ EnterStubFrame(); |
473 __ mov(LR, Operand(0)); | |
474 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); | |
475 __ mov(R0, Operand(FP)); // Get last FP address. | 475 __ mov(R0, Operand(FP)); // Get last FP address. |
476 if (preserve_result) { | 476 if (preserve_result) { |
477 __ Push(R1); // Preserve result as first local. | 477 __ Push(R1); // Preserve result as first local. |
478 } | 478 } |
479 __ ReserveAlignedFrameSpace(0); | 479 __ ReserveAlignedFrameSpace(0); |
480 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); // Pass last FP in R0. | 480 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); // Pass last FP in R0. |
481 if (preserve_result) { | 481 if (preserve_result) { |
482 // Restore result into R1. | 482 // Restore result into R1. |
483 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); | 483 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); |
484 } | 484 } |
485 // Code above cannot cause GC. | 485 // Code above cannot cause GC. |
486 __ LeaveDartFrame(); | 486 __ LeaveStubFrame(); |
487 | 487 |
488 // Frame is fully rewritten at this point and it is safe to perform a GC. | 488 // Frame is fully rewritten at this point and it is safe to perform a GC. |
489 // Materialize any objects that were deferred by FillFrame because they | 489 // Materialize any objects that were deferred by FillFrame because they |
490 // require allocation. | 490 // require allocation. |
491 // Enter stub frame with loading PP. The caller's PP is not materialized yet. | 491 // Enter stub frame with loading PP. The caller's PP is not materialized yet. |
492 __ EnterStubFrame(); | 492 __ EnterStubFrame(); |
493 if (preserve_result) { | 493 if (preserve_result) { |
494 __ Push(R1); // Preserve result, it will be GC-d here. | 494 __ Push(R1); // Preserve result, it will be GC-d here. |
495 } | 495 } |
496 __ PushObject(Smi::ZoneHandle()); // Space for the result. | 496 __ PushObject(Smi::ZoneHandle()); // Space for the result. |
(...skipping 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 // Result: | 2068 // Result: |
2069 // R1: entry point. | 2069 // R1: entry point. |
2070 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2070 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2071 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2071 EmitMegamorphicLookup(assembler, R0, R1, R1); |
2072 __ Ret(); | 2072 __ Ret(); |
2073 } | 2073 } |
2074 | 2074 |
2075 } // namespace dart | 2075 } // namespace dart |
2076 | 2076 |
2077 #endif // defined TARGET_ARCH_ARM | 2077 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |