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