| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 26 matching lines...) Expand all Loading... |
| 37 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 37 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 38 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 38 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 39 const intptr_t argv_offset = NativeArguments::argv_offset(); | 39 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 40 const intptr_t retval_offset = NativeArguments::retval_offset(); | 40 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 41 const intptr_t exitframe_last_param_slot_from_fp = 1; | 41 const intptr_t exitframe_last_param_slot_from_fp = 1; |
| 42 | 42 |
| 43 __ SetPrologueOffset(); | 43 __ SetPrologueOffset(); |
| 44 __ Comment("CallToRuntimeStub"); | 44 __ Comment("CallToRuntimeStub"); |
| 45 __ EnterFrame(0); | 45 __ EnterFrame(0); |
| 46 | 46 |
| 47 __ LoadIsolate(R0, kNoPP); | 47 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 48 __ LoadIsolate(R28, kNoPP); |
| 48 | 49 |
| 49 // Save exit frame information to enable stack walking as we are about | 50 // Save exit frame information to enable stack walking as we are about |
| 50 // to transition to Dart VM C++ code. | 51 // to transition to Dart VM C++ code. |
| 51 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP); | 52 __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 52 | |
| 53 // Save current Context pointer into Isolate structure. | |
| 54 __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP); | |
| 55 | |
| 56 // Cache Isolate pointer into CTX while executing runtime code. | |
| 57 __ mov(CTX, R0); | |
| 58 | 53 |
| 59 #if defined(DEBUG) | 54 #if defined(DEBUG) |
| 60 { Label ok; | 55 { Label ok; |
| 61 // Check that we are always entering from Dart code. | 56 // Check that we are always entering from Dart code. |
| 62 __ LoadFromOffset(R8, R0, Isolate::vm_tag_offset(), kNoPP); | 57 __ LoadFromOffset(R8, R28, Isolate::vm_tag_offset(), kNoPP); |
| 63 __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP); | 58 __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP); |
| 64 __ b(&ok, EQ); | 59 __ b(&ok, EQ); |
| 65 __ Stop("Not coming from Dart code."); | 60 __ Stop("Not coming from Dart code."); |
| 66 __ Bind(&ok); | 61 __ Bind(&ok); |
| 67 } | 62 } |
| 68 #endif | 63 #endif |
| 69 | 64 |
| 70 // Mark that the isolate is executing VM code. | 65 // Mark that the isolate is executing VM code. |
| 71 __ StoreToOffset(R5, R0, Isolate::vm_tag_offset(), kNoPP); | 66 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
| 72 | 67 |
| 73 // Reserve space for arguments and align frame before entering C++ world. | 68 // Reserve space for arguments and align frame before entering C++ world. |
| 74 // NativeArguments are passed in registers. | 69 // NativeArguments are passed in registers. |
| 75 __ Comment("align stack"); | 70 __ Comment("align stack"); |
| 76 // Reserve space for arguments. | 71 // Reserve space for arguments. |
| 77 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 72 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
| 78 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 73 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 79 | 74 |
| 80 // Pass NativeArguments structure by value and call runtime. | 75 // Pass NativeArguments structure by value and call runtime. |
| 81 // Registers R0, R1, R2, and R3 are used. | 76 // Registers R0, R1, R2, and R3 are used. |
| 82 | 77 |
| 83 ASSERT(isolate_offset == 0 * kWordSize); | 78 ASSERT(isolate_offset == 0 * kWordSize); |
| 84 // Set isolate in NativeArgs: R0 already contains CTX. | 79 // Set isolate in NativeArgs. |
| 80 __ mov(R0, R28); |
| 85 | 81 |
| 86 // There are no runtime calls to closures, so we do not need to set the tag | 82 // There are no runtime calls to closures, so we do not need to set the tag |
| 87 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 83 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 88 ASSERT(argc_tag_offset == 1 * kWordSize); | 84 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 89 __ mov(R1, R4); // Set argc in NativeArguments. | 85 __ mov(R1, R4); // Set argc in NativeArguments. |
| 90 | 86 |
| 91 ASSERT(argv_offset == 2 * kWordSize); | 87 ASSERT(argv_offset == 2 * kWordSize); |
| 92 __ add(R2, ZR, Operand(R4, LSL, 3)); | 88 __ add(R2, ZR, Operand(R4, LSL, 3)); |
| 93 __ add(R2, FP, Operand(R2)); // Compute argv. | 89 __ add(R2, FP, Operand(R2)); // Compute argv. |
| 94 // Set argv in NativeArguments. | 90 // Set argv in NativeArguments. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 112 __ blr(R5); | 108 __ blr(R5); |
| 113 __ Comment("CallToRuntimeStub return"); | 109 __ Comment("CallToRuntimeStub return"); |
| 114 | 110 |
| 115 // Restore SP and CSP. | 111 // Restore SP and CSP. |
| 116 __ mov(SP, CSP); | 112 __ mov(SP, CSP); |
| 117 __ mov(CSP, R26); | 113 __ mov(CSP, R26); |
| 118 | 114 |
| 119 // Retval is next to 1st argument. | 115 // Retval is next to 1st argument. |
| 120 // Mark that the isolate is executing Dart code. | 116 // Mark that the isolate is executing Dart code. |
| 121 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 117 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
| 122 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP); | 118 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
| 123 | 119 |
| 124 // Reset exit frame information in Isolate structure. | 120 // Reset exit frame information in Isolate structure. |
| 125 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP); | 121 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 126 | |
| 127 // Load Context pointer from Isolate structure into A2. | |
| 128 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP); | |
| 129 | |
| 130 // Load null. | |
| 131 __ LoadObject(TMP, Object::null_object(), PP); | |
| 132 | |
| 133 // Reset Context pointer in Isolate structure. | |
| 134 __ StoreToOffset(TMP, CTX, Isolate::top_context_offset(), kNoPP); | |
| 135 | |
| 136 // Cache Context pointer into CTX while executing Dart code. | |
| 137 __ mov(CTX, R2); | |
| 138 | 122 |
| 139 __ LeaveFrame(); | 123 __ LeaveFrame(); |
| 140 __ ret(); | 124 __ ret(); |
| 141 } | 125 } |
| 142 | 126 |
| 143 | 127 |
| 144 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 128 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 145 __ Stop("GeneratePrintStopMessageStub"); | 129 __ Stop("GeneratePrintStopMessageStub"); |
| 146 } | 130 } |
| 147 | 131 |
| 148 | 132 |
| 149 // Input parameters: | 133 // Input parameters: |
| 150 // LR : return address. | 134 // LR : return address. |
| 151 // SP : address of return value. | 135 // SP : address of return value. |
| 152 // R5 : address of the native function to call. | 136 // R5 : address of the native function to call. |
| 153 // R2 : address of first argument in argument array. | 137 // R2 : address of first argument in argument array. |
| 154 // R1 : argc_tag including number of arguments and function kind. | 138 // R1 : argc_tag including number of arguments and function kind. |
| 155 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 139 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 156 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 140 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 157 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 141 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 158 const intptr_t argv_offset = NativeArguments::argv_offset(); | 142 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 159 const intptr_t retval_offset = NativeArguments::retval_offset(); | 143 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 160 | 144 |
| 161 __ EnterFrame(0); | 145 __ EnterFrame(0); |
| 162 | 146 |
| 163 __ LoadIsolate(R0, kNoPP); | 147 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 148 __ LoadIsolate(R28, kNoPP); |
| 164 | 149 |
| 165 // 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 |
| 166 // to transition to native code. | 151 // to transition to native code. |
| 167 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP); | 152 __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 168 | |
| 169 // Save current Context pointer into Isolate structure. | |
| 170 __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP); | |
| 171 | |
| 172 // Cache Isolate pointer into CTX while executing native code. | |
| 173 __ mov(CTX, R0); | |
| 174 | 153 |
| 175 #if defined(DEBUG) | 154 #if defined(DEBUG) |
| 176 { Label ok; | 155 { Label ok; |
| 177 // Check that we are always entering from Dart code. | 156 // Check that we are always entering from Dart code. |
| 178 __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset(), kNoPP); | 157 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); |
| 179 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); | 158 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); |
| 180 __ b(&ok, EQ); | 159 __ b(&ok, EQ); |
| 181 __ Stop("Not coming from Dart code."); | 160 __ Stop("Not coming from Dart code."); |
| 182 __ Bind(&ok); | 161 __ Bind(&ok); |
| 183 } | 162 } |
| 184 #endif | 163 #endif |
| 185 | 164 |
| 186 // Mark that the isolate is executing Native code. | 165 // Mark that the isolate is executing Native code. |
| 187 __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset(), kNoPP); | 166 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
| 188 | 167 |
| 189 // 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 |
| 190 // outgoing pointer parameter to the native arguments structure is passed in | 169 // outgoing pointer parameter to the native arguments structure is passed in |
| 191 // R0) and align frame before entering the C++ world. | 170 // R0) and align frame before entering the C++ world. |
| 192 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 171 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 193 | 172 |
| 194 // Initialize NativeArguments structure and call native function. | 173 // Initialize NativeArguments structure and call native function. |
| 195 // Registers R0, R1, R2, and R3 are used. | 174 // Registers R0, R1, R2, and R3 are used. |
| 196 | 175 |
| 197 ASSERT(isolate_offset == 0 * kWordSize); | 176 ASSERT(isolate_offset == 0 * kWordSize); |
| 198 // Set isolate in NativeArgs: R0 already contains CTX. | 177 // Set isolate in NativeArgs. |
| 178 __ mov(R0, R28); |
| 199 | 179 |
| 200 // 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 |
| 201 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 181 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 202 ASSERT(argc_tag_offset == 1 * kWordSize); | 182 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 203 // Set argc in NativeArguments: R1 already contains argc. | 183 // Set argc in NativeArguments: R1 already contains argc. |
| 204 | 184 |
| 205 ASSERT(argv_offset == 2 * kWordSize); | 185 ASSERT(argv_offset == 2 * kWordSize); |
| 206 // Set argv in NativeArguments: R2 already contains argv. | 186 // Set argv in NativeArguments: R2 already contains argv. |
| 207 | 187 |
| 208 // Set retval in NativeArgs. | 188 // Set retval in NativeArgs. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 235 #else | 215 #else |
| 236 __ BranchLink(&NativeEntry::NativeCallWrapperLabel(), kNoPP); | 216 __ BranchLink(&NativeEntry::NativeCallWrapperLabel(), kNoPP); |
| 237 #endif | 217 #endif |
| 238 | 218 |
| 239 // Restore SP and CSP. | 219 // Restore SP and CSP. |
| 240 __ mov(SP, CSP); | 220 __ mov(SP, CSP); |
| 241 __ mov(CSP, R26); | 221 __ mov(CSP, R26); |
| 242 | 222 |
| 243 // Mark that the isolate is executing Dart code. | 223 // Mark that the isolate is executing Dart code. |
| 244 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 224 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
| 245 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP); | 225 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
| 246 | 226 |
| 247 // Reset exit frame information in Isolate structure. | 227 // Reset exit frame information in Isolate structure. |
| 248 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP); | 228 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 249 | |
| 250 // Load Context pointer from Isolate structure into R2. | |
| 251 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP); | |
| 252 | |
| 253 // Reset Context pointer in Isolate structure. | |
| 254 __ LoadObject(R3, Object::null_object(), PP); | |
| 255 __ StoreToOffset(R3, CTX, Isolate::top_context_offset(), kNoPP); | |
| 256 | |
| 257 // Cache Context pointer into CTX while executing Dart code. | |
| 258 __ mov(CTX, R2); | |
| 259 | 229 |
| 260 __ LeaveFrame(); | 230 __ LeaveFrame(); |
| 261 __ ret(); | 231 __ ret(); |
| 262 } | 232 } |
| 263 | 233 |
| 264 | 234 |
| 265 // Input parameters: | 235 // Input parameters: |
| 266 // LR : return address. | 236 // LR : return address. |
| 267 // SP : address of return value. | 237 // SP : address of return value. |
| 268 // R5 : address of the native function to call. | 238 // R5 : address of the native function to call. |
| 269 // R2 : address of first argument in argument array. | 239 // R2 : address of first argument in argument array. |
| 270 // R1 : argc_tag including number of arguments and function kind. | 240 // R1 : argc_tag including number of arguments and function kind. |
| 271 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 241 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 272 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 242 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 273 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 243 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 274 const intptr_t argv_offset = NativeArguments::argv_offset(); | 244 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 275 const intptr_t retval_offset = NativeArguments::retval_offset(); | 245 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 276 | 246 |
| 277 __ EnterFrame(0); | 247 __ EnterFrame(0); |
| 278 | 248 |
| 279 __ LoadIsolate(R0, kNoPP); | 249 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 250 __ LoadIsolate(R28, kNoPP); |
| 280 | 251 |
| 281 // Save exit frame information to enable stack walking as we are about | 252 // Save exit frame information to enable stack walking as we are about |
| 282 // to transition to native code. | 253 // to transition to native code. |
| 283 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP); | 254 __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 284 | |
| 285 // Save current Context pointer into Isolate structure. | |
| 286 __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP); | |
| 287 | |
| 288 // Cache Isolate pointer into CTX while executing native code. | |
| 289 __ mov(CTX, R0); | |
| 290 | 255 |
| 291 #if defined(DEBUG) | 256 #if defined(DEBUG) |
| 292 { Label ok; | 257 { Label ok; |
| 293 // Check that we are always entering from Dart code. | 258 // Check that we are always entering from Dart code. |
| 294 __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset(), kNoPP); | 259 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); |
| 295 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); | 260 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); |
| 296 __ b(&ok, EQ); | 261 __ b(&ok, EQ); |
| 297 __ Stop("Not coming from Dart code."); | 262 __ Stop("Not coming from Dart code."); |
| 298 __ Bind(&ok); | 263 __ Bind(&ok); |
| 299 } | 264 } |
| 300 #endif | 265 #endif |
| 301 | 266 |
| 302 // Mark that the isolate is executing Native code. | 267 // Mark that the isolate is executing Native code. |
| 303 __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset(), kNoPP); | 268 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
| 304 | 269 |
| 305 // Reserve space for the native arguments structure passed on the stack (the | 270 // Reserve space for the native arguments structure passed on the stack (the |
| 306 // outgoing pointer parameter to the native arguments structure is passed in | 271 // outgoing pointer parameter to the native arguments structure is passed in |
| 307 // R0) and align frame before entering the C++ world. | 272 // R0) and align frame before entering the C++ world. |
| 308 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 273 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
| 309 | 274 |
| 310 // Initialize NativeArguments structure and call native function. | 275 // Initialize NativeArguments structure and call native function. |
| 311 // Registers R0, R1, R2, and R3 are used. | 276 // Registers R0, R1, R2, and R3 are used. |
| 312 | 277 |
| 313 ASSERT(isolate_offset == 0 * kWordSize); | 278 ASSERT(isolate_offset == 0 * kWordSize); |
| 314 // Set isolate in NativeArgs: R0 already contains CTX. | 279 // Set isolate in NativeArgs. |
| 280 __ mov(R0, R28); |
| 315 | 281 |
| 316 // There are no native calls to closures, so we do not need to set the tag | 282 // There are no native calls to closures, so we do not need to set the tag |
| 317 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 283 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 318 ASSERT(argc_tag_offset == 1 * kWordSize); | 284 ASSERT(argc_tag_offset == 1 * kWordSize); |
| 319 // Set argc in NativeArguments: R1 already contains argc. | 285 // Set argc in NativeArguments: R1 already contains argc. |
| 320 | 286 |
| 321 ASSERT(argv_offset == 2 * kWordSize); | 287 ASSERT(argv_offset == 2 * kWordSize); |
| 322 // Set argv in NativeArguments: R2 already contains argv. | 288 // Set argv in NativeArguments: R2 already contains argv. |
| 323 | 289 |
| 324 // Set retval in NativeArgs. | 290 // Set retval in NativeArgs. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 342 | 308 |
| 343 // Call native function or redirection via simulator. | 309 // Call native function or redirection via simulator. |
| 344 __ blr(R5); | 310 __ blr(R5); |
| 345 | 311 |
| 346 // Restore SP and CSP. | 312 // Restore SP and CSP. |
| 347 __ mov(SP, CSP); | 313 __ mov(SP, CSP); |
| 348 __ mov(CSP, R26); | 314 __ mov(CSP, R26); |
| 349 | 315 |
| 350 // Mark that the isolate is executing Dart code. | 316 // Mark that the isolate is executing Dart code. |
| 351 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 317 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
| 352 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP); | 318 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
| 353 | 319 |
| 354 // Reset exit frame information in Isolate structure. | 320 // Reset exit frame information in Isolate structure. |
| 355 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP); | 321 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
| 356 | |
| 357 // Load Context pointer from Isolate structure into R2. | |
| 358 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP); | |
| 359 | |
| 360 // Reset Context pointer in Isolate structure. | |
| 361 __ LoadObject(R3, Object::null_object(), PP); | |
| 362 __ StoreToOffset(R3, CTX, Isolate::top_context_offset(), kNoPP); | |
| 363 | |
| 364 // Cache Context pointer into CTX while executing Dart code. | |
| 365 __ mov(CTX, R2); | |
| 366 | 322 |
| 367 __ LeaveFrame(); | 323 __ LeaveFrame(); |
| 368 __ ret(); | 324 __ ret(); |
| 369 } | 325 } |
| 370 | 326 |
| 371 | 327 |
| 372 // Input parameters: | 328 // Input parameters: |
| 373 // R4: arguments descriptor array. | 329 // R4: arguments descriptor array. |
| 374 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 330 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 375 // Create a stub frame as we are pushing some objects on the stack before | 331 // Create a stub frame as we are pushing some objects on the stack before |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 // C++ code. | 782 // C++ code. |
| 827 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex)); | 783 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex)); |
| 828 } | 784 } |
| 829 | 785 |
| 830 // Save the bottom 64-bits of callee-saved V registers. | 786 // Save the bottom 64-bits of callee-saved V registers. |
| 831 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { | 787 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { |
| 832 const VRegister r = static_cast<VRegister>(i); | 788 const VRegister r = static_cast<VRegister>(i); |
| 833 __ PushDouble(r); | 789 __ PushDouble(r); |
| 834 } | 790 } |
| 835 | 791 |
| 836 // Push new context. | |
| 837 __ Push(R3); | |
| 838 #if defined(DEBUG) | |
| 839 { | |
| 840 Label ok; | |
| 841 // The new context, saved vm tag, the top exit frame, and the old context. | |
| 842 const intptr_t kNewContextOffsetFromFp = | |
| 843 -(1 + kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount) * kWordSize; | |
| 844 __ AddImmediate(R4, FP, kNewContextOffsetFromFp, kNoPP); | |
| 845 __ CompareRegisters(R4, SP); | |
| 846 __ b(&ok, EQ); | |
| 847 __ Stop("kNewContextOffsetFromFp mismatch"); | |
| 848 __ Bind(&ok); | |
| 849 } | |
| 850 #endif | |
| 851 | |
| 852 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 792 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
| 853 // could potentially invoke some intrinsic functions which need the PP to be | 793 // could potentially invoke some intrinsic functions which need the PP to be |
| 854 // set up. | 794 // set up. |
| 855 __ LoadPoolPointer(PP); | 795 __ LoadPoolPointer(PP); |
| 856 | 796 |
| 857 // The new Context structure contains a pointer to the current Isolate | |
| 858 // structure. Cache the Context pointer in the CTX register so that it is | |
| 859 // available in generated code and calls to Isolate::Current() need not be | |
| 860 // done. The assumption is that this register will never be clobbered by | |
| 861 // compiled or runtime stub code. | |
| 862 | |
| 863 // Cache the new Context pointer into CTX while executing Dart code. | |
| 864 __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle, PP); | |
| 865 | |
| 866 // Load Isolate pointer into temporary register R5. | 797 // Load Isolate pointer into temporary register R5. |
| 867 __ LoadIsolate(R5, PP); | 798 __ LoadIsolate(R5, PP); |
| 868 | 799 |
| 869 // Save the current VMTag on the stack. | 800 // Save the current VMTag on the stack. |
| 870 ASSERT(kSavedVMTagSlotFromEntryFp == -20); | |
| 871 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP); | 801 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP); |
| 872 __ Push(R4); | 802 __ Push(R4); |
| 873 | 803 |
| 874 // Mark that the isolate is executing Dart code. | 804 // Mark that the isolate is executing Dart code. |
| 875 __ LoadImmediate(R6, VMTag::kDartTagId, PP); | 805 __ LoadImmediate(R6, VMTag::kDartTagId, PP); |
| 876 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset(), PP); | 806 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset(), PP); |
| 877 | 807 |
| 878 // Save the top exit frame info. Use R6 as a temporary register. | 808 // Save the top exit frame info. Use R6 as a temporary register. |
| 879 // StackFrameIterator reads the top exit frame info saved in this frame. | 809 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 880 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset(), PP); | 810 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset(), PP); |
| 881 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), PP); | 811 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), PP); |
| 882 | 812 |
| 883 // Save the old Context pointer. Use R4 as a temporary register. | |
| 884 // Note that VisitObjectPointers will find this saved Context pointer during | |
| 885 // GC marking, since it traverses any information between SP and | |
| 886 // FP - kExitLinkSlotFromEntryFp. | |
| 887 // EntryFrame::SavedContext reads the context saved in this frame. | |
| 888 __ LoadFromOffset(R4, R5, Isolate::top_context_offset(), PP); | |
| 889 | |
| 890 // The constants kSavedContextSlotFromEntryFp and | |
| 891 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 813 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
| 892 ASSERT(kExitLinkSlotFromEntryFp == -21); | 814 ASSERT(kExitLinkSlotFromEntryFp == -20); |
| 893 ASSERT(kSavedContextSlotFromEntryFp == -22); | |
| 894 __ Push(R6); | 815 __ Push(R6); |
| 895 __ Push(R4); | |
| 896 | 816 |
| 897 // Load arguments descriptor array into R4, which is passed to Dart code. | 817 // Load arguments descriptor array into R4, which is passed to Dart code. |
| 898 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle, PP); | 818 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle, PP); |
| 899 | 819 |
| 900 // Load number of arguments into S5. | 820 // Load number of arguments into S5. |
| 901 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset(), PP); | 821 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset(), PP); |
| 902 __ SmiUntag(R5); | 822 __ SmiUntag(R5); |
| 903 | 823 |
| 904 // Compute address of 'arguments array' data area into R2. | 824 // Compute address of 'arguments array' data area into R2. |
| 905 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle, PP); | 825 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle, PP); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 921 __ Bind(&done_push_arguments); | 841 __ Bind(&done_push_arguments); |
| 922 | 842 |
| 923 // Call the Dart code entrypoint. | 843 // Call the Dart code entrypoint. |
| 924 __ blr(R0); // R4 is the arguments descriptor array. | 844 __ blr(R0); // R4 is the arguments descriptor array. |
| 925 __ Comment("InvokeDartCodeStub return"); | 845 __ Comment("InvokeDartCodeStub return"); |
| 926 | 846 |
| 927 // Restore constant pool pointer after return. | 847 // Restore constant pool pointer after return. |
| 928 __ LoadPoolPointer(PP); | 848 __ LoadPoolPointer(PP); |
| 929 | 849 |
| 930 // Get rid of arguments pushed on the stack. | 850 // Get rid of arguments pushed on the stack. |
| 931 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize, PP); | 851 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize, PP); |
| 932 | 852 |
| 933 // Load Isolate pointer into CTX. | 853 __ LoadIsolate(R28, PP); |
| 934 __ LoadIsolate(CTX, PP); | 854 |
| 855 // Restore the saved top exit frame info back into the Isolate structure. |
| 856 // Uses R6 as a temporary register for this. |
| 857 __ Pop(R6); |
| 858 __ StoreToOffset(R6, R28, Isolate::top_exit_frame_info_offset(), PP); |
| 935 | 859 |
| 936 // Restore the current VMTag from the stack. | 860 // Restore the current VMTag from the stack. |
| 937 __ ldr(R4, Address(SP, 2 * kWordSize)); | |
| 938 __ StoreToOffset(R4, CTX, Isolate::vm_tag_offset(), PP); | |
| 939 | |
| 940 // Restore the saved Context pointer into the Isolate structure. | |
| 941 // Uses R4 as a temporary register for this. | |
| 942 // Restore the saved top exit frame info back into the Isolate structure. | |
| 943 // Uses R6 as a temporary register for this. | |
| 944 __ Pop(R4); | 861 __ Pop(R4); |
| 945 __ Pop(R6); | 862 __ StoreToOffset(R4, R28, Isolate::vm_tag_offset(), PP); |
| 946 __ StoreToOffset(R4, CTX, Isolate::top_context_offset(), PP); | |
| 947 __ StoreToOffset(R6, CTX, Isolate::top_exit_frame_info_offset(), PP); | |
| 948 | |
| 949 __ Pop(R3); | |
| 950 __ Pop(R4); | |
| 951 | 863 |
| 952 // Restore the bottom 64-bits of callee-saved V registers. | 864 // Restore the bottom 64-bits of callee-saved V registers. |
| 953 for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) { | 865 for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) { |
| 954 const VRegister r = static_cast<VRegister>(i); | 866 const VRegister r = static_cast<VRegister>(i); |
| 955 __ PopDouble(r); | 867 __ PopDouble(r); |
| 956 } | 868 } |
| 957 | 869 |
| 958 // Restore C++ ABI callee-saved registers. | 870 // Restore C++ ABI callee-saved registers. |
| 959 for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) { | 871 for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) { |
| 960 Register r = static_cast<Register>(i); | 872 Register r = static_cast<Register>(i); |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2104 const Register right = R0; | 2016 const Register right = R0; |
| 2105 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); | 2017 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); |
| 2106 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); | 2018 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); |
| 2107 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2019 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2108 __ ret(); | 2020 __ ret(); |
| 2109 } | 2021 } |
| 2110 | 2022 |
| 2111 } // namespace dart | 2023 } // namespace dart |
| 2112 | 2024 |
| 2113 #endif // defined TARGET_ARCH_ARM64 | 2025 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |