| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 // LR : points to return address. | 775 // LR : points to return address. |
| 776 // R0 : entrypoint of the Dart function to call. | 776 // R0 : entrypoint of the Dart function to call. |
| 777 // R1 : arguments descriptor array. | 777 // R1 : arguments descriptor array. |
| 778 // R2 : arguments array. | 778 // R2 : arguments array. |
| 779 // R3 : new context containing the current isolate pointer. | 779 // R3 : new context containing the current isolate pointer. |
| 780 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 780 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 781 // Save frame pointer coming in. | 781 // Save frame pointer coming in. |
| 782 __ EnterStubFrame(); | 782 __ EnterStubFrame(); |
| 783 | 783 |
| 784 // Save new context and C++ ABI callee-saved registers. | 784 // Save new context and C++ ABI callee-saved registers. |
| 785 const intptr_t kNewContextOffset = | 785 const intptr_t kNewContextOffsetFromFp = |
| 786 -(1 + kAbiPreservedCpuRegCount) * kWordSize; | 786 -(1 + kAbiPreservedCpuRegCount) * kWordSize; |
| 787 __ PushList((1 << R3) | kAbiPreservedCpuRegs); | 787 __ PushList((1 << R3) | kAbiPreservedCpuRegs); |
| 788 | 788 |
| 789 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); |
| 790 ASSERT(2 * kAbiPreservedFpuRegCount < 16); |
| 791 // Save FPU registers. 2 D registers per Q register. |
| 792 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
| 793 |
| 789 // The new Context structure contains a pointer to the current Isolate | 794 // The new Context structure contains a pointer to the current Isolate |
| 790 // structure. Cache the Context pointer in the CTX register so that it is | 795 // structure. Cache the Context pointer in the CTX register so that it is |
| 791 // available in generated code and calls to Isolate::Current() need not be | 796 // available in generated code and calls to Isolate::Current() need not be |
| 792 // done. The assumption is that this register will never be clobbered by | 797 // done. The assumption is that this register will never be clobbered by |
| 793 // compiled or runtime stub code. | 798 // compiled or runtime stub code. |
| 794 | 799 |
| 795 // Cache the new Context pointer into CTX while executing Dart code. | 800 // Cache the new Context pointer into CTX while executing Dart code. |
| 796 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); | 801 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); |
| 797 | 802 |
| 798 // Load Isolate pointer from Context structure into temporary register R8. | 803 // Load Isolate pointer from Context structure into temporary register R8. |
| 799 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); | 804 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); |
| 800 | 805 |
| 801 // Save the top exit frame info. Use R5 as a temporary register. | 806 // Save the top exit frame info. Use R5 as a temporary register. |
| 802 // StackFrameIterator reads the top exit frame info saved in this frame. | 807 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 803 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); | 808 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); |
| 804 __ LoadImmediate(R6, 0); | 809 __ LoadImmediate(R6, 0); |
| 805 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); | 810 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); |
| 806 | 811 |
| 807 // Save the old Context pointer. Use R4 as a temporary register. | 812 // Save the old Context pointer. Use R4 as a temporary register. |
| 808 // Note that VisitObjectPointers will find this saved Context pointer during | 813 // Note that VisitObjectPointers will find this saved Context pointer during |
| 809 // GC marking, since it traverses any information between SP and | 814 // GC marking, since it traverses any information between SP and |
| 810 // FP - kExitLinkSlotFromEntryFp. | 815 // FP - kExitLinkSlotFromEntryFp. |
| 811 // EntryFrame::SavedContext reads the context saved in this frame. | 816 // EntryFrame::SavedContext reads the context saved in this frame. |
| 812 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset()); | 817 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset()); |
| 813 | 818 |
| 814 // The constants kSavedContextSlotFromEntryFp and | 819 // The constants kSavedContextSlotFromEntryFp and |
| 815 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 820 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
| 816 ASSERT(kExitLinkSlotFromEntryFp == -9); | 821 ASSERT(kExitLinkSlotFromEntryFp == -25); |
| 817 ASSERT(kSavedContextSlotFromEntryFp == -10); | 822 ASSERT(kSavedContextSlotFromEntryFp == -26); |
| 818 __ PushList((1 << R4) | (1 << R5)); | 823 __ PushList((1 << R4) | (1 << R5)); |
| 819 | 824 |
| 820 // The stack pointer is restored after the call to this location. | |
| 821 const intptr_t kSavedContextSlotFromEntryFp = -10 * kWordSize; | |
| 822 | |
| 823 // Load arguments descriptor array into R4, which is passed to Dart code. | 825 // Load arguments descriptor array into R4, which is passed to Dart code. |
| 824 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); | 826 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); |
| 825 | 827 |
| 826 // Load number of arguments into R5. | 828 // Load number of arguments into R5. |
| 827 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 829 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| 828 __ SmiUntag(R5); | 830 __ SmiUntag(R5); |
| 829 | 831 |
| 830 // Compute address of 'arguments array' data area into R2. | 832 // Compute address of 'arguments array' data area into R2. |
| 831 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); | 833 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); |
| 832 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); | 834 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 843 __ AddImmediate(R2, kWordSize); | 845 __ AddImmediate(R2, kWordSize); |
| 844 __ AddImmediate(R1, 1); | 846 __ AddImmediate(R1, 1); |
| 845 __ cmp(R1, ShifterOperand(R5)); | 847 __ cmp(R1, ShifterOperand(R5)); |
| 846 __ b(&push_arguments, LT); | 848 __ b(&push_arguments, LT); |
| 847 __ Bind(&done_push_arguments); | 849 __ Bind(&done_push_arguments); |
| 848 | 850 |
| 849 // Call the Dart code entrypoint. | 851 // Call the Dart code entrypoint. |
| 850 __ blx(R0); // R4 is the arguments descriptor array. | 852 __ blx(R0); // R4 is the arguments descriptor array. |
| 851 | 853 |
| 852 // Read the saved new Context pointer. | 854 // Read the saved new Context pointer. |
| 853 __ ldr(CTX, Address(FP, kNewContextOffset)); | 855 __ ldr(CTX, Address(FP, kNewContextOffsetFromFp)); |
| 854 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | 856 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 855 | 857 |
| 856 // Get rid of arguments pushed on the stack. | 858 // Get rid of arguments pushed on the stack. |
| 857 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp); | 859 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); |
| 858 | 860 |
| 859 // Load Isolate pointer from Context structure into CTX. Drop Context. | 861 // Load Isolate pointer from Context structure into CTX. Drop Context. |
| 860 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); | 862 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); |
| 861 | 863 |
| 862 // Restore the saved Context pointer into the Isolate structure. | 864 // Restore the saved Context pointer into the Isolate structure. |
| 863 // Uses R4 as a temporary register for this. | 865 // Uses R4 as a temporary register for this. |
| 864 // Restore the saved top exit frame info back into the Isolate structure. | 866 // Restore the saved top exit frame info back into the Isolate structure. |
| 865 // Uses R5 as a temporary register for this. | 867 // Uses R5 as a temporary register for this. |
| 866 __ PopList((1 << R4) | (1 << R5)); | 868 __ PopList((1 << R4) | (1 << R5)); |
| 867 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); | 869 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); |
| 868 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); | 870 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); |
| 869 | 871 |
| 870 // Restore C++ ABI callee-saved registers. | 872 // Restore C++ ABI callee-saved registers. |
| 873 // Restore FPU registers. 2 D registers per Q register. |
| 874 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
| 875 // Restore CPU registers. |
| 871 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. | 876 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. |
| 872 | 877 |
| 873 // Restore the frame pointer and return. | 878 // Restore the frame pointer and return. |
| 874 __ LeaveStubFrame(); | 879 __ LeaveStubFrame(); |
| 875 __ Ret(); | 880 __ Ret(); |
| 876 } | 881 } |
| 877 | 882 |
| 878 | 883 |
| 879 // Called for inline allocation of contexts. | 884 // Called for inline allocation of contexts. |
| 880 // Input: | 885 // Input: |
| (...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2178 __ ldr(left, Address(SP, 4 * kWordSize)); | 2183 __ ldr(left, Address(SP, 4 * kWordSize)); |
| 2179 __ ldr(right, Address(SP, 3 * kWordSize)); | 2184 __ ldr(right, Address(SP, 3 * kWordSize)); |
| 2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2185 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); | 2186 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); |
| 2182 __ Ret(); | 2187 __ Ret(); |
| 2183 } | 2188 } |
| 2184 | 2189 |
| 2185 } // namespace dart | 2190 } // namespace dart |
| 2186 | 2191 |
| 2187 #endif // defined TARGET_ARCH_ARM | 2192 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |