| 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 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 38 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 40 const intptr_t argv_offset = NativeArguments::argv_offset(); | 40 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 41 const intptr_t retval_offset = NativeArguments::retval_offset(); | 41 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 42 const intptr_t exitframe_last_param_slot_from_fp = 2; | 42 const intptr_t exitframe_last_param_slot_from_fp = 2; |
| 43 | 43 |
| 44 __ mov(IP, Operand(0)); | 44 __ mov(IP, Operand(0)); |
| 45 __ Push(IP); // Push 0 for the PC marker. | 45 __ Push(IP); // Push 0 for the PC marker. |
| 46 __ EnterFrame((1 << FP) | (1 << LR), 0); | 46 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 47 | 47 |
| 48 __ LoadIsolate(R0); | 48 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 49 __ LoadIsolate(R9); |
| 49 | 50 |
| 50 // Save exit frame information to enable stack walking as we are about | 51 // Save exit frame information to enable stack walking as we are about |
| 51 // to transition to Dart VM C++ code. | 52 // to transition to Dart VM C++ code. |
| 52 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 53 __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset()); |
| 53 | |
| 54 // Save current Context pointer into Isolate structure. | |
| 55 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); | |
| 56 | |
| 57 // Cache Isolate pointer into CTX while executing runtime code. | |
| 58 __ mov(CTX, Operand(R0)); | |
| 59 | 54 |
| 60 #if defined(DEBUG) | 55 #if defined(DEBUG) |
| 61 { Label ok; | 56 { Label ok; |
| 62 // Check that we are always entering from Dart code. | 57 // Check that we are always entering from Dart code. |
| 63 __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset()); | 58 __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset()); |
| 64 __ CompareImmediate(R6, VMTag::kDartTagId); | 59 __ CompareImmediate(R6, VMTag::kDartTagId); |
| 65 __ b(&ok, EQ); | 60 __ b(&ok, EQ); |
| 66 __ Stop("Not coming from Dart code."); | 61 __ Stop("Not coming from Dart code."); |
| 67 __ Bind(&ok); | 62 __ Bind(&ok); |
| 68 } | 63 } |
| 69 #endif | 64 #endif |
| 70 | 65 |
| 71 // Mark that the isolate is executing VM code. | 66 // Mark that the isolate is executing VM code. |
| 72 __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset()); | 67 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset()); |
| 73 | 68 |
| 74 // Reserve space for arguments and align frame before entering C++ world. | 69 // Reserve space for arguments and align frame before entering C++ world. |
| 75 // NativeArguments are passed in registers. | 70 // NativeArguments are passed in registers. |
| 76 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 71 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
| 77 __ ReserveAlignedFrameSpace(0); | 72 __ ReserveAlignedFrameSpace(0); |
| 78 | 73 |
| 79 // Pass NativeArguments structure by value and call runtime. | 74 // Pass NativeArguments structure by value and call runtime. |
| 80 // Registers R0, R1, R2, and R3 are used. | 75 // Registers R0, R1, R2, and R3 are used. |
| 81 | 76 |
| 82 ASSERT(isolate_offset == 0 * kWordSize); | 77 ASSERT(isolate_offset == 0 * kWordSize); |
| 83 // Set isolate in NativeArgs: R0 already contains CTX. | 78 // Set isolate in NativeArgs. |
| 79 __ mov(R0, Operand(R9)); |
| 84 | 80 |
| 85 // There are no runtime calls to closures, so we do not need to set the tag | 81 // There are no runtime calls to closures, so we do not need to set the tag |
| 86 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 87 ASSERT(argc_tag_offset == 1 * kWordSize); | 83 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 88 __ mov(R1, Operand(R4)); // Set argc in NativeArguments. | 84 __ mov(R1, Operand(R4)); // Set argc in NativeArguments. |
| 89 | 85 |
| 90 ASSERT(argv_offset == 2 * kWordSize); | 86 ASSERT(argv_offset == 2 * kWordSize); |
| 91 __ add(R2, FP, Operand(R4, LSL, 2)); // Compute argv. | 87 __ add(R2, FP, Operand(R4, LSL, 2)); // Compute argv. |
| 92 // Set argv in NativeArguments. | 88 // Set argv in NativeArguments. |
| 93 __ AddImmediate(R2, exitframe_last_param_slot_from_fp * kWordSize); | 89 __ AddImmediate(R2, exitframe_last_param_slot_from_fp * kWordSize); |
| 94 | 90 |
| 95 ASSERT(retval_offset == 3 * kWordSize); | 91 ASSERT(retval_offset == 3 * kWordSize); |
| 96 __ add(R3, R2, Operand(kWordSize)); // Retval is next to 1st argument. | 92 __ add(R3, R2, Operand(kWordSize)); // Retval is next to 1st argument. |
| 97 | 93 |
| 98 // Call runtime or redirection via simulator. | 94 // Call runtime or redirection via simulator. |
| 99 __ blx(R5); | 95 __ blx(R5); |
| 100 | 96 |
| 101 // Mark that the isolate is executing Dart code. | 97 // Mark that the isolate is executing Dart code. |
| 102 __ LoadImmediate(R2, VMTag::kDartTagId); | 98 __ LoadImmediate(R2, VMTag::kDartTagId); |
| 103 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 99 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
| 104 | 100 |
| 105 // Reset exit frame information in Isolate structure. | 101 // Reset exit frame information in Isolate structure. |
| 106 __ LoadImmediate(R2, 0); | 102 __ LoadImmediate(R2, 0); |
| 107 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 103 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
| 108 | |
| 109 // Load Context pointer from Isolate structure into R2. | |
| 110 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | |
| 111 | |
| 112 // Reset Context pointer in Isolate structure. | |
| 113 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | |
| 114 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | |
| 115 | |
| 116 // Cache Context pointer into CTX while executing Dart code. | |
| 117 __ mov(CTX, Operand(R2)); | |
| 118 | 104 |
| 119 __ LeaveFrame((1 << FP) | (1 << LR)); | 105 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 120 // Adjust SP for the empty PC marker. | 106 // Adjust SP for the empty PC marker. |
| 121 __ AddImmediate(SP, kWordSize); | 107 __ AddImmediate(SP, kWordSize); |
| 122 __ Ret(); | 108 __ Ret(); |
| 123 } | 109 } |
| 124 | 110 |
| 125 | 111 |
| 126 // Print the stop message. | 112 // Print the stop message. |
| 127 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 113 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 151 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 137 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 152 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 138 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 153 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 139 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 154 const intptr_t argv_offset = NativeArguments::argv_offset(); | 140 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 155 const intptr_t retval_offset = NativeArguments::retval_offset(); | 141 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 156 | 142 |
| 157 __ mov(IP, Operand(0)); | 143 __ mov(IP, Operand(0)); |
| 158 __ Push(IP); // Push 0 for the PC marker. | 144 __ Push(IP); // Push 0 for the PC marker. |
| 159 __ EnterFrame((1 << FP) | (1 << LR), 0); | 145 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 160 | 146 |
| 161 __ LoadIsolate(R0); | 147 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 148 __ LoadIsolate(R9); |
| 162 | 149 |
| 163 // Save exit frame information to enable stack walking as we are about | 150 // Save exit frame information to enable stack walking as we are about |
| 164 // to transition to native code. | 151 // to transition to native code. |
| 165 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 152 __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset()); |
| 166 | |
| 167 // Save current Context pointer into Isolate structure. | |
| 168 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); | |
| 169 | |
| 170 // Cache Isolate pointer into CTX while executing native code. | |
| 171 __ mov(CTX, Operand(R0)); | |
| 172 | 153 |
| 173 #if defined(DEBUG) | 154 #if defined(DEBUG) |
| 174 { Label ok; | 155 { Label ok; |
| 175 // Check that we are always entering from Dart code. | 156 // Check that we are always entering from Dart code. |
| 176 __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset()); | 157 __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset()); |
| 177 __ CompareImmediate(R6, VMTag::kDartTagId); | 158 __ CompareImmediate(R6, VMTag::kDartTagId); |
| 178 __ b(&ok, EQ); | 159 __ b(&ok, EQ); |
| 179 __ Stop("Not coming from Dart code."); | 160 __ Stop("Not coming from Dart code."); |
| 180 __ Bind(&ok); | 161 __ Bind(&ok); |
| 181 } | 162 } |
| 182 #endif | 163 #endif |
| 183 | 164 |
| 184 // Mark that the isolate is executing Native code. | 165 // Mark that the isolate is executing Native code. |
| 185 __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset()); | 166 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset()); |
| 186 | 167 |
| 187 // Reserve space for the native arguments structure passed on the stack (the | 168 // Reserve space for the native arguments structure passed on the stack (the |
| 188 // outgoing pointer parameter to the native arguments structure is passed in | 169 // outgoing pointer parameter to the native arguments structure is passed in |
| 189 // R0) and align frame before entering the C++ world. | 170 // R0) and align frame before entering the C++ world. |
| 190 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 171 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 191 | 172 |
| 192 // Initialize NativeArguments structure and call native function. | 173 // Initialize NativeArguments structure and call native function. |
| 193 // Registers R0, R1, R2, and R3 are used. | 174 // Registers R0, R1, R2, and R3 are used. |
| 194 | 175 |
| 195 ASSERT(isolate_offset == 0 * kWordSize); | 176 ASSERT(isolate_offset == 0 * kWordSize); |
| 196 // Set isolate in NativeArgs: R0 already contains CTX. | 177 // Set isolate in NativeArgs. |
| 178 __ mov(R0, Operand(R9)); |
| 197 | 179 |
| 198 // There are no native calls to closures, so we do not need to set the tag | 180 // There are no native calls to closures, so we do not need to set the tag |
| 199 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 181 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 200 ASSERT(argc_tag_offset == 1 * kWordSize); | 182 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 201 // Set argc in NativeArguments: R1 already contains argc. | 183 // Set argc in NativeArguments: R1 already contains argc. |
| 202 | 184 |
| 203 ASSERT(argv_offset == 2 * kWordSize); | 185 ASSERT(argv_offset == 2 * kWordSize); |
| 204 // Set argv in NativeArguments: R2 already contains argv. | 186 // Set argv in NativeArguments: R2 already contains argv. |
| 205 | 187 |
| 206 ASSERT(retval_offset == 3 * kWordSize); | 188 ASSERT(retval_offset == 3 * kWordSize); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 219 entry = Simulator::RedirectExternalReference( | 201 entry = Simulator::RedirectExternalReference( |
| 220 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); | 202 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
| 221 __ LoadImmediate(R2, entry); | 203 __ LoadImmediate(R2, entry); |
| 222 __ blx(R2); | 204 __ blx(R2); |
| 223 #else | 205 #else |
| 224 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); | 206 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); |
| 225 #endif | 207 #endif |
| 226 | 208 |
| 227 // Mark that the isolate is executing Dart code. | 209 // Mark that the isolate is executing Dart code. |
| 228 __ LoadImmediate(R2, VMTag::kDartTagId); | 210 __ LoadImmediate(R2, VMTag::kDartTagId); |
| 229 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 211 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
| 230 | 212 |
| 231 // Reset exit frame information in Isolate structure. | 213 // Reset exit frame information in Isolate structure. |
| 232 __ LoadImmediate(R2, 0); | 214 __ LoadImmediate(R2, 0); |
| 233 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 215 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
| 234 | |
| 235 // Load Context pointer from Isolate structure into R2. | |
| 236 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | |
| 237 | |
| 238 // Reset Context pointer in Isolate structure. | |
| 239 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | |
| 240 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | |
| 241 | |
| 242 // Cache Context pointer into CTX while executing Dart code. | |
| 243 __ mov(CTX, Operand(R2)); | |
| 244 | 216 |
| 245 __ LeaveFrame((1 << FP) | (1 << LR)); | 217 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 246 // Adjust SP for the empty PC marker. | 218 // Adjust SP for the empty PC marker. |
| 247 __ AddImmediate(SP, kWordSize); | 219 __ AddImmediate(SP, kWordSize); |
| 248 __ Ret(); | 220 __ Ret(); |
| 249 } | 221 } |
| 250 | 222 |
| 251 | 223 |
| 252 // Input parameters: | 224 // Input parameters: |
| 253 // LR : return address. | 225 // LR : return address. |
| 254 // SP : address of return value. | 226 // SP : address of return value. |
| 255 // R5 : address of the native function to call. | 227 // R5 : address of the native function to call. |
| 256 // R2 : address of first argument in argument array. | 228 // R2 : address of first argument in argument array. |
| 257 // R1 : argc_tag including number of arguments and function kind. | 229 // R1 : argc_tag including number of arguments and function kind. |
| 258 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 230 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 259 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 231 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 260 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 232 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 261 const intptr_t argv_offset = NativeArguments::argv_offset(); | 233 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 262 const intptr_t retval_offset = NativeArguments::retval_offset(); | 234 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 263 | 235 |
| 264 __ mov(IP, Operand(0)); | 236 __ mov(IP, Operand(0)); |
| 265 __ Push(IP); // Push 0 for the PC marker. | 237 __ Push(IP); // Push 0 for the PC marker. |
| 266 __ EnterFrame((1 << FP) | (1 << LR), 0); | 238 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 267 | 239 |
| 268 __ LoadIsolate(R0); | 240 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 241 __ LoadIsolate(R9); |
| 269 | 242 |
| 270 // Save exit frame information to enable stack walking as we are about | 243 // Save exit frame information to enable stack walking as we are about |
| 271 // to transition to native code. | 244 // to transition to native code. |
| 272 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 245 __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset()); |
| 273 | |
| 274 // Save current Context pointer into Isolate structure. | |
| 275 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); | |
| 276 | |
| 277 // Cache Isolate pointer into CTX while executing native code. | |
| 278 __ mov(CTX, Operand(R0)); | |
| 279 | 246 |
| 280 #if defined(DEBUG) | 247 #if defined(DEBUG) |
| 281 { Label ok; | 248 { Label ok; |
| 282 // Check that we are always entering from Dart code. | 249 // Check that we are always entering from Dart code. |
| 283 __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset()); | 250 __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset()); |
| 284 __ CompareImmediate(R6, VMTag::kDartTagId); | 251 __ CompareImmediate(R6, VMTag::kDartTagId); |
| 285 __ b(&ok, EQ); | 252 __ b(&ok, EQ); |
| 286 __ Stop("Not coming from Dart code."); | 253 __ Stop("Not coming from Dart code."); |
| 287 __ Bind(&ok); | 254 __ Bind(&ok); |
| 288 } | 255 } |
| 289 #endif | 256 #endif |
| 290 | 257 |
| 291 // Mark that the isolate is executing Native code. | 258 // Mark that the isolate is executing Native code. |
| 292 __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset()); | 259 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset()); |
| 293 | 260 |
| 294 // Reserve space for the native arguments structure passed on the stack (the | 261 // Reserve space for the native arguments structure passed on the stack (the |
| 295 // outgoing pointer parameter to the native arguments structure is passed in | 262 // outgoing pointer parameter to the native arguments structure is passed in |
| 296 // R0) and align frame before entering the C++ world. | 263 // R0) and align frame before entering the C++ world. |
| 297 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 264 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 298 | 265 |
| 299 // Initialize NativeArguments structure and call native function. | 266 // Initialize NativeArguments structure and call native function. |
| 300 // Registers R0, R1, R2, and R3 are used. | 267 // Registers R0, R1, R2, and R3 are used. |
| 301 | 268 |
| 302 ASSERT(isolate_offset == 0 * kWordSize); | 269 ASSERT(isolate_offset == 0 * kWordSize); |
| 303 // Set isolate in NativeArgs: R0 already contains CTX. | 270 // Set isolate in NativeArgs. |
| 271 __ mov(R0, Operand(R9)); |
| 304 | 272 |
| 305 // There are no native calls to closures, so we do not need to set the tag | 273 // There are no native calls to closures, so we do not need to set the tag |
| 306 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 274 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 307 ASSERT(argc_tag_offset == 1 * kWordSize); | 275 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 308 // Set argc in NativeArguments: R1 already contains argc. | 276 // Set argc in NativeArguments: R1 already contains argc. |
| 309 | 277 |
| 310 ASSERT(argv_offset == 2 * kWordSize); | 278 ASSERT(argv_offset == 2 * kWordSize); |
| 311 // Set argv in NativeArguments: R2 already contains argv. | 279 // Set argv in NativeArguments: R2 already contains argv. |
| 312 | 280 |
| 313 ASSERT(retval_offset == 3 * kWordSize); | 281 ASSERT(retval_offset == 3 * kWordSize); |
| 314 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. | 282 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. |
| 315 | 283 |
| 316 // Passing the structure by value as in runtime calls would require changing | 284 // Passing the structure by value as in runtime calls would require changing |
| 317 // Dart API for native functions. | 285 // Dart API for native functions. |
| 318 // For now, space is reserved on the stack and we pass a pointer to it. | 286 // For now, space is reserved on the stack and we pass a pointer to it. |
| 319 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 287 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
| 320 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. | 288 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. |
| 321 | 289 |
| 322 // Call native function or redirection via simulator. | 290 // Call native function or redirection via simulator. |
| 323 __ blx(R5); | 291 __ blx(R5); |
| 324 | 292 |
| 325 // Mark that the isolate is executing Dart code. | 293 // Mark that the isolate is executing Dart code. |
| 326 __ LoadImmediate(R2, VMTag::kDartTagId); | 294 __ LoadImmediate(R2, VMTag::kDartTagId); |
| 327 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 295 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
| 328 | 296 |
| 329 // Reset exit frame information in Isolate structure. | 297 // Reset exit frame information in Isolate structure. |
| 330 __ LoadImmediate(R2, 0); | 298 __ LoadImmediate(R2, 0); |
| 331 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 299 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
| 332 | |
| 333 // Load Context pointer from Isolate structure into R2. | |
| 334 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | |
| 335 | |
| 336 // Reset Context pointer in Isolate structure. | |
| 337 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | |
| 338 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | |
| 339 | |
| 340 // Cache Context pointer into CTX while executing Dart code. | |
| 341 __ mov(CTX, Operand(R2)); | |
| 342 | 300 |
| 343 __ LeaveFrame((1 << FP) | (1 << LR)); | 301 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 344 // Adjust SP for the empty PC marker. | 302 // Adjust SP for the empty PC marker. |
| 345 __ AddImmediate(SP, kWordSize); | 303 __ AddImmediate(SP, kWordSize); |
| 346 __ Ret(); | 304 __ Ret(); |
| 347 } | 305 } |
| 348 | 306 |
| 349 | 307 |
| 350 // Input parameters: | 308 // Input parameters: |
| 351 // R4: arguments descriptor array. | 309 // R4: arguments descriptor array. |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 // LR : points to return address. | 736 // LR : points to return address. |
| 779 // R0 : entrypoint of the Dart function to call. | 737 // R0 : entrypoint of the Dart function to call. |
| 780 // R1 : arguments descriptor array. | 738 // R1 : arguments descriptor array. |
| 781 // R2 : arguments array. | 739 // R2 : arguments array. |
| 782 // R3 : new context containing the current isolate pointer. | 740 // R3 : new context containing the current isolate pointer. |
| 783 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 741 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 784 // Save frame pointer coming in. | 742 // Save frame pointer coming in. |
| 785 __ EnterFrame((1 << FP) | (1 << LR), 0); | 743 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| 786 | 744 |
| 787 // Save new context and C++ ABI callee-saved registers. | 745 // Save new context and C++ ABI callee-saved registers. |
| 788 __ PushList((1 << R3) | kAbiPreservedCpuRegs); | 746 __ PushList(kAbiPreservedCpuRegs); |
| 789 | 747 |
| 790 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); | 748 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); |
| 791 if (TargetCPUFeatures::vfp_supported()) { | 749 if (TargetCPUFeatures::vfp_supported()) { |
| 792 ASSERT(2 * kAbiPreservedFpuRegCount < 16); | 750 ASSERT(2 * kAbiPreservedFpuRegCount < 16); |
| 793 // Save FPU registers. 2 D registers per Q register. | 751 // Save FPU registers. 2 D registers per Q register. |
| 794 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); | 752 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
| 795 } else { | 753 } else { |
| 796 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); | 754 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); |
| 797 } | 755 } |
| 798 | 756 |
| 799 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 757 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
| 800 // could potentially invoke some intrinsic functions which need the PP to be | 758 // could potentially invoke some intrinsic functions which need the PP to be |
| 801 // set up. | 759 // set up. |
| 802 __ LoadPoolPointer(); | 760 __ LoadPoolPointer(); |
| 803 | 761 |
| 804 // The new Context structure contains a pointer to the current Isolate | |
| 805 // structure. Cache the Context pointer in the CTX register so that it is | |
| 806 // available in generated code and calls to Isolate::Current() need not be | |
| 807 // done. The assumption is that this register will never be clobbered by | |
| 808 // compiled or runtime stub code. | |
| 809 | |
| 810 // Cache the new Context pointer into CTX while executing Dart code. | |
| 811 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 812 | |
| 813 __ LoadIsolate(R8); | 762 __ LoadIsolate(R8); |
| 814 | 763 |
| 815 // Save the current VMTag on the stack. | 764 // Save the current VMTag on the stack. |
| 816 ASSERT(kSavedVMTagSlotFromEntryFp == -25); | |
| 817 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); | 765 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); |
| 818 __ Push(R5); | 766 __ Push(R5); |
| 819 | 767 |
| 820 // Mark that the isolate is executing Dart code. | 768 // Mark that the isolate is executing Dart code. |
| 821 __ LoadImmediate(R5, VMTag::kDartTagId); | 769 __ LoadImmediate(R5, VMTag::kDartTagId); |
| 822 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); | 770 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); |
| 823 | 771 |
| 824 // Save the top exit frame info. Use R5 as a temporary register. | 772 // Save the top exit frame info. Use R5 as a temporary register. |
| 825 // StackFrameIterator reads the top exit frame info saved in this frame. | 773 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 826 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); | 774 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); |
| 827 __ LoadImmediate(R6, 0); | 775 __ LoadImmediate(R6, 0); |
| 828 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); | 776 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); |
| 829 | 777 |
| 830 // Save the old Context pointer. Use R4 as a temporary register. | |
| 831 // Note that VisitObjectPointers will find this saved Context pointer during | |
| 832 // GC marking, since it traverses any information between SP and | |
| 833 // FP - kExitLinkSlotFromEntryFp. | |
| 834 // EntryFrame::SavedContext reads the context saved in this frame. | |
| 835 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset()); | |
| 836 | |
| 837 // The constants kSavedContextSlotFromEntryFp and | |
| 838 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 778 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
| 839 ASSERT(kExitLinkSlotFromEntryFp == -26); | 779 ASSERT(kExitLinkSlotFromEntryFp == -25); |
| 840 ASSERT(kSavedContextSlotFromEntryFp == -27); | 780 __ Push(R5); |
| 841 __ PushList((1 << R4) | (1 << R5)); | |
| 842 | 781 |
| 843 // Load arguments descriptor array into R4, which is passed to Dart code. | 782 // Load arguments descriptor array into R4, which is passed to Dart code. |
| 844 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); | 783 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); |
| 845 | 784 |
| 846 // Load number of arguments into R5. | 785 // Load number of arguments into R5. |
| 847 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 786 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| 848 __ SmiUntag(R5); | 787 __ SmiUntag(R5); |
| 849 | 788 |
| 850 // Compute address of 'arguments array' data area into R2. | 789 // Compute address of 'arguments array' data area into R2. |
| 851 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); | 790 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 863 __ AddImmediate(R2, kWordSize); | 802 __ AddImmediate(R2, kWordSize); |
| 864 __ AddImmediate(R1, 1); | 803 __ AddImmediate(R1, 1); |
| 865 __ cmp(R1, Operand(R5)); | 804 __ cmp(R1, Operand(R5)); |
| 866 __ b(&push_arguments, LT); | 805 __ b(&push_arguments, LT); |
| 867 __ Bind(&done_push_arguments); | 806 __ Bind(&done_push_arguments); |
| 868 | 807 |
| 869 // Call the Dart code entrypoint. | 808 // Call the Dart code entrypoint. |
| 870 __ blx(R0); // R4 is the arguments descriptor array. | 809 __ blx(R0); // R4 is the arguments descriptor array. |
| 871 | 810 |
| 872 // Get rid of arguments pushed on the stack. | 811 // Get rid of arguments pushed on the stack. |
| 873 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); | 812 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); |
| 874 | 813 |
| 875 // Load Isolate pointer into CTX. | 814 __ LoadIsolate(R8); |
| 876 __ LoadIsolate(CTX); | |
| 877 | 815 |
| 878 // Restore the saved Context pointer into the Isolate structure. | |
| 879 // Uses R4 as a temporary register for this. | |
| 880 // Restore the saved top exit frame info back into the Isolate structure. | 816 // Restore the saved top exit frame info back into the Isolate structure. |
| 881 // Uses R5 as a temporary register for this. | 817 // Uses R5 as a temporary register for this. |
| 882 __ PopList((1 << R4) | (1 << R5)); | 818 __ Pop(R5); |
| 883 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); | 819 __ StoreToOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); |
| 884 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); | |
| 885 | 820 |
| 886 // Restore the current VMTag from the stack. | 821 // Restore the current VMTag from the stack. |
| 887 __ Pop(R4); | 822 __ Pop(R4); |
| 888 __ StoreToOffset(kWord, R4, CTX, Isolate::vm_tag_offset()); | 823 __ StoreToOffset(kWord, R4, R8, Isolate::vm_tag_offset()); |
| 889 | 824 |
| 890 // Restore C++ ABI callee-saved registers. | 825 // Restore C++ ABI callee-saved registers. |
| 891 if (TargetCPUFeatures::vfp_supported()) { | 826 if (TargetCPUFeatures::vfp_supported()) { |
| 892 // Restore FPU registers. 2 D registers per Q register. | 827 // Restore FPU registers. 2 D registers per Q register. |
| 893 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); | 828 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
| 894 } else { | 829 } else { |
| 895 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); | 830 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); |
| 896 } | 831 } |
| 897 // Restore CPU registers. | 832 // Restore CPU registers. |
| 898 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. | 833 __ PopList(kAbiPreservedCpuRegs); |
| 899 | 834 |
| 900 // Restore the frame pointer and return. | 835 // Restore the frame pointer and return. |
| 901 __ LeaveFrame((1 << FP) | (1 << LR)); | 836 __ LeaveFrame((1 << FP) | (1 << LR)); |
| 902 __ Ret(); | 837 __ Ret(); |
| 903 } | 838 } |
| 904 | 839 |
| 905 | 840 |
| 906 // Called for inline allocation of contexts. | 841 // Called for inline allocation of contexts. |
| 907 // Input: | 842 // Input: |
| 908 // R1: number of context variables. | 843 // R1: number of context variables. |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 const Register right = R0; | 1987 const Register right = R0; |
| 2053 __ ldr(left, Address(SP, 1 * kWordSize)); | 1988 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 2054 __ ldr(right, Address(SP, 0 * kWordSize)); | 1989 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 2055 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1990 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2056 __ Ret(); | 1991 __ Ret(); |
| 2057 } | 1992 } |
| 2058 | 1993 |
| 2059 } // namespace dart | 1994 } // namespace dart |
| 2060 | 1995 |
| 2061 #endif // defined TARGET_ARCH_ARM | 1996 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |