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 27 matching lines...) Expand all Loading... |
38 // R5 : address of the runtime function to call. | 38 // R5 : address of the runtime function to call. |
39 // R4 : number of arguments to the call. | 39 // R4 : number of arguments to the call. |
40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
41 const intptr_t thread_offset = NativeArguments::thread_offset(); | 41 const intptr_t thread_offset = NativeArguments::thread_offset(); |
42 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 42 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
43 const intptr_t argv_offset = NativeArguments::argv_offset(); | 43 const intptr_t argv_offset = NativeArguments::argv_offset(); |
44 const intptr_t retval_offset = NativeArguments::retval_offset(); | 44 const intptr_t retval_offset = NativeArguments::retval_offset(); |
45 | 45 |
46 __ EnterStubFrame(); | 46 __ EnterStubFrame(); |
47 | 47 |
48 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R7)) != 0); | |
49 __ LoadIsolate(R7); | |
50 | |
51 // Save exit frame information to enable stack walking as we are about | 48 // Save exit frame information to enable stack walking as we are about |
52 // to transition to Dart VM C++ code. | 49 // to transition to Dart VM C++ code. |
53 __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset()); | 50 __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset()); |
54 | 51 |
55 #if defined(DEBUG) | 52 #if defined(DEBUG) |
56 { Label ok; | 53 { Label ok; |
57 // Check that we are always entering from Dart code. | 54 // Check that we are always entering from Dart code. |
58 __ LoadFromOffset(kWord, R6, R7, Isolate::vm_tag_offset()); | 55 __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset()); |
59 __ CompareImmediate(R6, VMTag::kDartTagId); | 56 __ CompareImmediate(R6, VMTag::kDartTagId); |
60 __ b(&ok, EQ); | 57 __ b(&ok, EQ); |
61 __ Stop("Not coming from Dart code."); | 58 __ Stop("Not coming from Dart code."); |
62 __ Bind(&ok); | 59 __ Bind(&ok); |
63 } | 60 } |
64 #endif | 61 #endif |
65 | 62 |
66 // Mark that the isolate is executing VM code. | 63 // Mark that the thread is executing VM code. |
67 __ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset()); | 64 __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset()); |
68 | 65 |
69 // Reserve space for arguments and align frame before entering C++ world. | 66 // Reserve space for arguments and align frame before entering C++ world. |
70 // NativeArguments are passed in registers. | 67 // NativeArguments are passed in registers. |
71 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 68 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
72 __ ReserveAlignedFrameSpace(0); | 69 __ ReserveAlignedFrameSpace(0); |
73 | 70 |
74 // Pass NativeArguments structure by value and call runtime. | 71 // Pass NativeArguments structure by value and call runtime. |
75 // Registers R0, R1, R2, and R3 are used. | 72 // Registers R0, R1, R2, and R3 are used. |
76 | 73 |
77 ASSERT(thread_offset == 0 * kWordSize); | 74 ASSERT(thread_offset == 0 * kWordSize); |
78 // Set thread in NativeArgs. | 75 // Set thread in NativeArgs. |
79 __ mov(R0, Operand(THR)); | 76 __ mov(R0, Operand(THR)); |
80 | 77 |
81 // There are no runtime calls to closures, so we do not need to set the tag | 78 // There are no runtime calls to closures, so we do not need to set the tag |
82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 79 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
83 ASSERT(argc_tag_offset == 1 * kWordSize); | 80 ASSERT(argc_tag_offset == 1 * kWordSize); |
84 __ mov(R1, Operand(R4)); // Set argc in NativeArguments. | 81 __ mov(R1, Operand(R4)); // Set argc in NativeArguments. |
85 | 82 |
86 ASSERT(argv_offset == 2 * kWordSize); | 83 ASSERT(argv_offset == 2 * kWordSize); |
87 __ add(R2, FP, Operand(R4, LSL, 2)); // Compute argv. | 84 __ add(R2, FP, Operand(R4, LSL, 2)); // Compute argv. |
88 // Set argv in NativeArguments. | 85 // Set argv in NativeArguments. |
89 __ AddImmediate(R2, kParamEndSlotFromFp * kWordSize); | 86 __ AddImmediate(R2, kParamEndSlotFromFp * kWordSize); |
90 | 87 |
91 ASSERT(retval_offset == 3 * kWordSize); | 88 ASSERT(retval_offset == 3 * kWordSize); |
92 __ add(R3, R2, Operand(kWordSize)); // Retval is next to 1st argument. | 89 __ add(R3, R2, Operand(kWordSize)); // Retval is next to 1st argument. |
93 | 90 |
94 // Call runtime or redirection via simulator. | 91 // Call runtime or redirection via simulator. |
95 __ blx(R5); | 92 __ blx(R5); |
96 | 93 |
97 // Mark that the isolate is executing Dart code. | 94 // Mark that the thread is executing Dart code. |
98 __ LoadImmediate(R2, VMTag::kDartTagId); | 95 __ LoadImmediate(R2, VMTag::kDartTagId); |
99 __ StoreToOffset(kWord, R2, R7, Isolate::vm_tag_offset()); | 96 __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset()); |
100 | 97 |
101 // Reset exit frame information in Isolate structure. | 98 // Reset exit frame information in Isolate structure. |
102 __ LoadImmediate(R2, 0); | 99 __ LoadImmediate(R2, 0); |
103 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); | 100 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); |
104 | 101 |
105 __ LeaveStubFrame(); | 102 __ LeaveStubFrame(); |
106 __ Ret(); | 103 __ Ret(); |
107 } | 104 } |
108 | 105 |
109 | 106 |
(...skipping 23 matching lines...) Expand all Loading... |
133 // R2 : address of first argument in argument array. | 130 // R2 : address of first argument in argument array. |
134 // R1 : argc_tag including number of arguments and function kind. | 131 // R1 : argc_tag including number of arguments and function kind. |
135 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 132 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
136 const intptr_t thread_offset = NativeArguments::thread_offset(); | 133 const intptr_t thread_offset = NativeArguments::thread_offset(); |
137 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 134 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
138 const intptr_t argv_offset = NativeArguments::argv_offset(); | 135 const intptr_t argv_offset = NativeArguments::argv_offset(); |
139 const intptr_t retval_offset = NativeArguments::retval_offset(); | 136 const intptr_t retval_offset = NativeArguments::retval_offset(); |
140 | 137 |
141 __ EnterStubFrame(); | 138 __ EnterStubFrame(); |
142 | 139 |
143 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R7)) != 0); | |
144 __ LoadIsolate(R7); | |
145 | |
146 // Save exit frame information to enable stack walking as we are about | 140 // Save exit frame information to enable stack walking as we are about |
147 // to transition to native code. | 141 // to transition to native code. |
148 __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset()); | 142 __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset()); |
149 | 143 |
150 #if defined(DEBUG) | 144 #if defined(DEBUG) |
151 { Label ok; | 145 { Label ok; |
152 // Check that we are always entering from Dart code. | 146 // Check that we are always entering from Dart code. |
153 __ LoadFromOffset(kWord, R6, R7, Isolate::vm_tag_offset()); | 147 __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset()); |
154 __ CompareImmediate(R6, VMTag::kDartTagId); | 148 __ CompareImmediate(R6, VMTag::kDartTagId); |
155 __ b(&ok, EQ); | 149 __ b(&ok, EQ); |
156 __ Stop("Not coming from Dart code."); | 150 __ Stop("Not coming from Dart code."); |
157 __ Bind(&ok); | 151 __ Bind(&ok); |
158 } | 152 } |
159 #endif | 153 #endif |
160 | 154 |
161 // Mark that the isolate is executing Native code. | 155 // Mark that the thread is executing native code. |
162 __ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset()); | 156 __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset()); |
163 | 157 |
164 // Reserve space for the native arguments structure passed on the stack (the | 158 // Reserve space for the native arguments structure passed on the stack (the |
165 // outgoing pointer parameter to the native arguments structure is passed in | 159 // outgoing pointer parameter to the native arguments structure is passed in |
166 // R0) and align frame before entering the C++ world. | 160 // R0) and align frame before entering the C++ world. |
167 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 161 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
168 | 162 |
169 // Initialize NativeArguments structure and call native function. | 163 // Initialize NativeArguments structure and call native function. |
170 // Registers R0, R1, R2, and R3 are used. | 164 // Registers R0, R1, R2, and R3 are used. |
171 | 165 |
172 ASSERT(thread_offset == 0 * kWordSize); | 166 ASSERT(thread_offset == 0 * kWordSize); |
(...skipping 17 matching lines...) Expand all Loading... |
190 // For now, space is reserved on the stack and we pass a pointer to it. | 184 // For now, space is reserved on the stack and we pass a pointer to it. |
191 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 185 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
192 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. | 186 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. |
193 | 187 |
194 __ mov(R1, Operand(R5)); // Pass the function entrypoint to call. | 188 __ mov(R1, Operand(R5)); // Pass the function entrypoint to call. |
195 | 189 |
196 // Call native function invocation wrapper or redirection via simulator. | 190 // Call native function invocation wrapper or redirection via simulator. |
197 __ ldr(LR, Address(THR, Thread::native_call_wrapper_entry_point_offset())); | 191 __ ldr(LR, Address(THR, Thread::native_call_wrapper_entry_point_offset())); |
198 __ blx(LR); | 192 __ blx(LR); |
199 | 193 |
200 // Mark that the isolate is executing Dart code. | 194 // Mark that the thread is executing Dart code. |
201 __ LoadImmediate(R2, VMTag::kDartTagId); | 195 __ LoadImmediate(R2, VMTag::kDartTagId); |
202 __ StoreToOffset(kWord, R2, R7, Isolate::vm_tag_offset()); | 196 __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset()); |
203 | 197 |
204 // Reset exit frame information in Isolate structure. | 198 // Reset exit frame information in Isolate structure. |
205 __ LoadImmediate(R2, 0); | 199 __ LoadImmediate(R2, 0); |
206 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); | 200 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); |
207 | 201 |
208 __ LeaveStubFrame(); | 202 __ LeaveStubFrame(); |
209 __ Ret(); | 203 __ Ret(); |
210 } | 204 } |
211 | 205 |
212 | 206 |
213 // Input parameters: | 207 // Input parameters: |
214 // LR : return address. | 208 // LR : return address. |
215 // SP : address of return value. | 209 // SP : address of return value. |
216 // R5 : address of the native function to call. | 210 // R5 : address of the native function to call. |
217 // R2 : address of first argument in argument array. | 211 // R2 : address of first argument in argument array. |
218 // R1 : argc_tag including number of arguments and function kind. | 212 // R1 : argc_tag including number of arguments and function kind. |
219 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 213 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
220 const intptr_t thread_offset = NativeArguments::thread_offset(); | 214 const intptr_t thread_offset = NativeArguments::thread_offset(); |
221 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 215 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
222 const intptr_t argv_offset = NativeArguments::argv_offset(); | 216 const intptr_t argv_offset = NativeArguments::argv_offset(); |
223 const intptr_t retval_offset = NativeArguments::retval_offset(); | 217 const intptr_t retval_offset = NativeArguments::retval_offset(); |
224 | 218 |
225 __ EnterStubFrame(); | 219 __ EnterStubFrame(); |
226 | 220 |
227 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R7)) != 0); | |
228 __ LoadIsolate(R7); | |
229 | |
230 // Save exit frame information to enable stack walking as we are about | 221 // Save exit frame information to enable stack walking as we are about |
231 // to transition to native code. | 222 // to transition to native code. |
232 __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset()); | 223 __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset()); |
233 | 224 |
234 #if defined(DEBUG) | 225 #if defined(DEBUG) |
235 { Label ok; | 226 { Label ok; |
236 // Check that we are always entering from Dart code. | 227 // Check that we are always entering from Dart code. |
237 __ LoadFromOffset(kWord, R6, R7, Isolate::vm_tag_offset()); | 228 __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset()); |
238 __ CompareImmediate(R6, VMTag::kDartTagId); | 229 __ CompareImmediate(R6, VMTag::kDartTagId); |
239 __ b(&ok, EQ); | 230 __ b(&ok, EQ); |
240 __ Stop("Not coming from Dart code."); | 231 __ Stop("Not coming from Dart code."); |
241 __ Bind(&ok); | 232 __ Bind(&ok); |
242 } | 233 } |
243 #endif | 234 #endif |
244 | 235 |
245 // Mark that the isolate is executing Native code. | 236 // Mark that the thread is executing native code. |
246 __ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset()); | 237 __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset()); |
247 | 238 |
248 // Reserve space for the native arguments structure passed on the stack (the | 239 // Reserve space for the native arguments structure passed on the stack (the |
249 // outgoing pointer parameter to the native arguments structure is passed in | 240 // outgoing pointer parameter to the native arguments structure is passed in |
250 // R0) and align frame before entering the C++ world. | 241 // R0) and align frame before entering the C++ world. |
251 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 242 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
252 | 243 |
253 // Initialize NativeArguments structure and call native function. | 244 // Initialize NativeArguments structure and call native function. |
254 // Registers R0, R1, R2, and R3 are used. | 245 // Registers R0, R1, R2, and R3 are used. |
255 | 246 |
256 ASSERT(thread_offset == 0 * kWordSize); | 247 ASSERT(thread_offset == 0 * kWordSize); |
(...skipping 14 matching lines...) Expand all Loading... |
271 | 262 |
272 // Passing the structure by value as in runtime calls would require changing | 263 // Passing the structure by value as in runtime calls would require changing |
273 // Dart API for native functions. | 264 // Dart API for native functions. |
274 // For now, space is reserved on the stack and we pass a pointer to it. | 265 // For now, space is reserved on the stack and we pass a pointer to it. |
275 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 266 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
276 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. | 267 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. |
277 | 268 |
278 // Call native function or redirection via simulator. | 269 // Call native function or redirection via simulator. |
279 __ blx(R5); | 270 __ blx(R5); |
280 | 271 |
281 // Mark that the isolate is executing Dart code. | 272 // Mark that the thread is executing Dart code. |
282 __ LoadImmediate(R2, VMTag::kDartTagId); | 273 __ LoadImmediate(R2, VMTag::kDartTagId); |
283 __ StoreToOffset(kWord, R2, R7, Isolate::vm_tag_offset()); | 274 __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset()); |
284 | 275 |
285 // Reset exit frame information in Isolate structure. | 276 // Reset exit frame information in Isolate structure. |
286 __ LoadImmediate(R2, 0); | 277 __ LoadImmediate(R2, 0); |
287 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); | 278 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); |
288 | 279 |
289 __ LeaveStubFrame(); | 280 __ LeaveStubFrame(); |
290 __ Ret(); | 281 __ Ret(); |
291 } | 282 } |
292 | 283 |
293 | 284 |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 // Save FPU registers. 2 D registers per Q register. | 745 // Save FPU registers. 2 D registers per Q register. |
755 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); | 746 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
756 } else { | 747 } else { |
757 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); | 748 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); |
758 } | 749 } |
759 | 750 |
760 // Set up THR, which caches the current thread in Dart code. | 751 // Set up THR, which caches the current thread in Dart code. |
761 if (THR != R3) { | 752 if (THR != R3) { |
762 __ mov(THR, Operand(R3)); | 753 __ mov(THR, Operand(R3)); |
763 } | 754 } |
764 __ LoadIsolate(R7); | |
765 | 755 |
766 // Save the current VMTag on the stack. | 756 // Save the current VMTag on the stack. |
767 __ LoadFromOffset(kWord, R5, R7, Isolate::vm_tag_offset()); | 757 __ LoadFromOffset(kWord, R5, THR, Thread::vm_tag_offset()); |
768 __ Push(R5); | 758 __ Push(R5); |
769 | 759 |
770 // Mark that the isolate is executing Dart code. | 760 // Mark that the thread is executing Dart code. |
771 __ LoadImmediate(R5, VMTag::kDartTagId); | 761 __ LoadImmediate(R5, VMTag::kDartTagId); |
772 __ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset()); | 762 __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset()); |
773 | 763 |
774 // Save top resource and top exit frame info. Use R4-6 as temporary registers. | 764 // Save top resource and top exit frame info. Use R4-6 as temporary registers. |
775 // StackFrameIterator reads the top exit frame info saved in this frame. | 765 // StackFrameIterator reads the top exit frame info saved in this frame. |
776 __ LoadFromOffset(kWord, R5, THR, Thread::top_exit_frame_info_offset()); | 766 __ LoadFromOffset(kWord, R5, THR, Thread::top_exit_frame_info_offset()); |
777 __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset()); | 767 __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset()); |
778 __ LoadImmediate(R6, 0); | 768 __ LoadImmediate(R6, 0); |
779 __ StoreToOffset(kWord, R6, THR, Thread::top_resource_offset()); | 769 __ StoreToOffset(kWord, R6, THR, Thread::top_resource_offset()); |
780 __ StoreToOffset(kWord, R6, THR, Thread::top_exit_frame_info_offset()); | 770 __ StoreToOffset(kWord, R6, THR, Thread::top_exit_frame_info_offset()); |
781 | 771 |
782 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 772 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
(...skipping 29 matching lines...) Expand all Loading... |
812 | 802 |
813 // Call the Dart code entrypoint. | 803 // Call the Dart code entrypoint. |
814 __ LoadImmediate(PP, 0); // GC safe value into PP. | 804 __ LoadImmediate(PP, 0); // GC safe value into PP. |
815 __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle)); | 805 __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle)); |
816 __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset())); | 806 __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset())); |
817 __ blx(R0); // R4 is the arguments descriptor array. | 807 __ blx(R0); // R4 is the arguments descriptor array. |
818 | 808 |
819 // Get rid of arguments pushed on the stack. | 809 // Get rid of arguments pushed on the stack. |
820 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); | 810 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); |
821 | 811 |
822 __ LoadIsolate(R7); | |
823 // Restore the saved top exit frame info and top resource back into the | 812 // Restore the saved top exit frame info and top resource back into the |
824 // Isolate structure. Uses R5 as a temporary register for this. | 813 // Isolate structure. Uses R5 as a temporary register for this. |
825 __ Pop(R5); | 814 __ Pop(R5); |
826 __ StoreToOffset(kWord, R5, THR, Thread::top_exit_frame_info_offset()); | 815 __ StoreToOffset(kWord, R5, THR, Thread::top_exit_frame_info_offset()); |
827 __ Pop(R5); | 816 __ Pop(R5); |
828 __ StoreToOffset(kWord, R5, THR, Thread::top_resource_offset()); | 817 __ StoreToOffset(kWord, R5, THR, Thread::top_resource_offset()); |
829 | 818 |
830 // Restore the current VMTag from the stack. | 819 // Restore the current VMTag from the stack. |
831 __ Pop(R4); | 820 __ Pop(R4); |
832 __ StoreToOffset(kWord, R4, R7, Isolate::vm_tag_offset()); | 821 __ StoreToOffset(kWord, R4, THR, Thread::vm_tag_offset()); |
833 | 822 |
834 // Restore C++ ABI callee-saved registers. | 823 // Restore C++ ABI callee-saved registers. |
835 if (TargetCPUFeatures::vfp_supported()) { | 824 if (TargetCPUFeatures::vfp_supported()) { |
836 // Restore FPU registers. 2 D registers per Q register. | 825 // Restore FPU registers. 2 D registers per Q register. |
837 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); | 826 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
838 } else { | 827 } else { |
839 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); | 828 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); |
840 } | 829 } |
841 // Restore CPU registers. | 830 // Restore CPU registers. |
842 __ PopList(kAbiPreservedCpuRegs); | 831 __ PopList(kAbiPreservedCpuRegs); |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1883 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
1895 ASSERT(kExceptionObjectReg == R0); | 1884 ASSERT(kExceptionObjectReg == R0); |
1896 ASSERT(kStackTraceObjectReg == R1); | 1885 ASSERT(kStackTraceObjectReg == R1); |
1897 __ mov(IP, Operand(R1)); // Copy Stack pointer into IP. | 1886 __ mov(IP, Operand(R1)); // Copy Stack pointer into IP. |
1898 __ mov(LR, Operand(R0)); // Program counter. | 1887 __ mov(LR, Operand(R0)); // Program counter. |
1899 __ mov(R0, Operand(R3)); // Exception object. | 1888 __ mov(R0, Operand(R3)); // Exception object. |
1900 __ ldr(R1, Address(SP, 0)); // StackTrace object. | 1889 __ ldr(R1, Address(SP, 0)); // StackTrace object. |
1901 __ ldr(THR, Address(SP, 4)); // Thread. | 1890 __ ldr(THR, Address(SP, 4)); // Thread. |
1902 __ mov(FP, Operand(R2)); // Frame_pointer. | 1891 __ mov(FP, Operand(R2)); // Frame_pointer. |
1903 __ mov(SP, Operand(IP)); // Set Stack pointer. | 1892 __ mov(SP, Operand(IP)); // Set Stack pointer. |
1904 __ LoadIsolate(R3); | |
1905 // Set the tag. | 1893 // Set the tag. |
1906 __ LoadImmediate(R2, VMTag::kDartTagId); | 1894 __ LoadImmediate(R2, VMTag::kDartTagId); |
1907 __ StoreToOffset(kWord, R2, R3, Isolate::vm_tag_offset()); | 1895 __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset()); |
1908 // Clear top exit frame. | 1896 // Clear top exit frame. |
1909 __ LoadImmediate(R2, 0); | 1897 __ LoadImmediate(R2, 0); |
1910 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); | 1898 __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset()); |
1911 __ bx(LR); // Jump to the exception handler code. | 1899 __ bx(LR); // Jump to the exception handler code. |
1912 } | 1900 } |
1913 | 1901 |
1914 | 1902 |
1915 // Calls to the runtime to optimize the given function. | 1903 // Calls to the runtime to optimize the given function. |
1916 // R6: function to be reoptimized. | 1904 // R6: function to be reoptimized. |
1917 // R4: argument descriptor (preserved). | 1905 // R4: argument descriptor (preserved). |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 // Result: | 2088 // Result: |
2101 // R1: entry point. | 2089 // R1: entry point. |
2102 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2090 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2103 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2091 EmitMegamorphicLookup(assembler, R0, R1, R1); |
2104 __ Ret(); | 2092 __ Ret(); |
2105 } | 2093 } |
2106 | 2094 |
2107 } // namespace dart | 2095 } // namespace dart |
2108 | 2096 |
2109 #endif // defined TARGET_ARCH_ARM | 2097 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |