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