| 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_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 // Input parameters: | 30 // Input parameters: |
| 31 // RSP : points to return address. | 31 // RSP : points to return address. |
| 32 // RSP + 8 : address of last argument in argument array. | 32 // RSP + 8 : address of last argument in argument array. |
| 33 // RSP + 8*R10 : address of first argument in argument array. | 33 // RSP + 8*R10 : address of first argument in argument array. |
| 34 // RSP + 8*R10 + 8 : address of return value. | 34 // RSP + 8*R10 + 8 : address of return value. |
| 35 // RBX : address of the runtime function to call. | 35 // RBX : address of the runtime function to call. |
| 36 // R10 : number of arguments to the call. | 36 // R10 : number of arguments to the call. |
| 37 // Must preserve callee saved registers R12 and R13. | 37 // Must preserve callee saved registers R12 and R13. |
| 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 39 ASSERT((R12 != CTX) && (R13 != CTX)); | |
| 40 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 39 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 41 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 42 const intptr_t argv_offset = NativeArguments::argv_offset(); | 41 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 43 const intptr_t retval_offset = NativeArguments::retval_offset(); | 42 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 44 | 43 |
| 45 __ EnterFrame(0); | 44 __ EnterFrame(0); |
| 46 | 45 |
| 47 __ LoadIsolate(RAX); | 46 COMPILE_ASSERT( |
| 47 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
| 48 __ LoadIsolate(R12); |
| 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 __ movq(Address(RAX, Isolate::top_exit_frame_info_offset()), RSP); | 52 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP); |
| 52 | |
| 53 // Save current Context pointer into Isolate structure. | |
| 54 __ movq(Address(RAX, Isolate::top_context_offset()), CTX); | |
| 55 | |
| 56 // Cache Isolate pointer into CTX while executing runtime code. | |
| 57 __ movq(CTX, RAX); | |
| 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 __ movq(RAX, Immediate(VMTag::kDartTagId)); | 57 __ movq(RAX, Immediate(VMTag::kDartTagId)); |
| 63 __ cmpq(RAX, Address(CTX, Isolate::vm_tag_offset())); | 58 __ cmpq(RAX, Address(R12, Isolate::vm_tag_offset())); |
| 64 __ j(EQUAL, &ok, Assembler::kNearJump); | 59 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 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 __ movq(Address(CTX, Isolate::vm_tag_offset()), RBX); | 66 __ movq(Address(R12, Isolate::vm_tag_offset()), RBX); |
| 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 __ subq(RSP, Immediate(sizeof(NativeArguments))); | 69 __ subq(RSP, Immediate(sizeof(NativeArguments))); |
| 75 if (OS::ActivationFrameAlignment() > 1) { | 70 if (OS::ActivationFrameAlignment() > 1) { |
| 76 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 71 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 77 } | 72 } |
| 78 | 73 |
| 79 // Pass NativeArguments structure by value and call runtime. | 74 // Pass NativeArguments structure by value and call runtime. |
| 80 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. | 75 __ movq(Address(RSP, isolate_offset), R12); // Set isolate in NativeArgs. |
| 81 // There are no runtime calls to closures, so we do not need to set the tag | 76 // There are no runtime calls to closures, so we do not need to set the tag |
| 82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 77 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 83 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 78 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
| 84 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv. | 79 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv. |
| 85 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 80 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
| 86 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. | 81 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. |
| 87 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 82 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
| 88 #if defined(_WIN64) | 83 #if defined(_WIN64) |
| 89 ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit); | 84 ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit); |
| 90 __ movq(CallingConventions::kArg1Reg, RSP); | 85 __ movq(CallingConventions::kArg1Reg, RSP); |
| 91 #endif | 86 #endif |
| 92 __ CallCFunction(RBX); | 87 __ CallCFunction(RBX); |
| 93 | 88 |
| 94 // Mark that the isolate is executing Dart code. | 89 // Mark that the isolate is executing Dart code. |
| 95 __ movq(Address(CTX, Isolate::vm_tag_offset()), | 90 __ movq(Address(R12, Isolate::vm_tag_offset()), |
| 96 Immediate(VMTag::kDartTagId)); | 91 Immediate(VMTag::kDartTagId)); |
| 97 | 92 |
| 98 // Reset exit frame information in Isolate structure. | 93 // Reset exit frame information in Isolate structure. |
| 99 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 94 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 100 | |
| 101 // Load Context pointer from Isolate structure into RBX. | |
| 102 __ movq(RBX, Address(CTX, Isolate::top_context_offset())); | |
| 103 | |
| 104 // Reset Context pointer in Isolate structure. | |
| 105 __ LoadObject(R12, Object::null_object(), PP); | |
| 106 __ movq(Address(CTX, Isolate::top_context_offset()), R12); | |
| 107 | |
| 108 // Cache Context pointer into CTX while executing Dart code. | |
| 109 __ movq(CTX, RBX); | |
| 110 | 95 |
| 111 __ LeaveFrame(); | 96 __ LeaveFrame(); |
| 112 __ ret(); | 97 __ ret(); |
| 113 } | 98 } |
| 114 | 99 |
| 115 | 100 |
| 116 // Print the stop message. | 101 // Print the stop message. |
| 117 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 102 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| 118 OS::Print("Stop message: %s\n", message); | 103 OS::Print("Stop message: %s\n", message); |
| 119 } | 104 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 148 NativeArguments::isolate_offset() + native_args_struct_offset; | 133 NativeArguments::isolate_offset() + native_args_struct_offset; |
| 149 const intptr_t argc_tag_offset = | 134 const intptr_t argc_tag_offset = |
| 150 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 135 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 151 const intptr_t argv_offset = | 136 const intptr_t argv_offset = |
| 152 NativeArguments::argv_offset() + native_args_struct_offset; | 137 NativeArguments::argv_offset() + native_args_struct_offset; |
| 153 const intptr_t retval_offset = | 138 const intptr_t retval_offset = |
| 154 NativeArguments::retval_offset() + native_args_struct_offset; | 139 NativeArguments::retval_offset() + native_args_struct_offset; |
| 155 | 140 |
| 156 __ EnterFrame(0); | 141 __ EnterFrame(0); |
| 157 | 142 |
| 158 __ LoadIsolate(R8); | 143 COMPILE_ASSERT( |
| 144 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
| 145 __ LoadIsolate(R12); |
| 159 | 146 |
| 160 // Save exit frame information to enable stack walking as we are about | 147 // Save exit frame information to enable stack walking as we are about |
| 161 // to transition to native code. | 148 // to transition to native code. |
| 162 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), RSP); | 149 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP); |
| 163 | |
| 164 // Save current Context pointer into Isolate structure. | |
| 165 __ movq(Address(R8, Isolate::top_context_offset()), CTX); | |
| 166 | |
| 167 // Cache Isolate pointer into CTX while executing native code. | |
| 168 __ movq(CTX, R8); | |
| 169 | 150 |
| 170 #if defined(DEBUG) | 151 #if defined(DEBUG) |
| 171 { Label ok; | 152 { Label ok; |
| 172 // Check that we are always entering from Dart code. | 153 // Check that we are always entering from Dart code. |
| 173 __ movq(R8, Immediate(VMTag::kDartTagId)); | 154 __ movq(R8, Immediate(VMTag::kDartTagId)); |
| 174 __ cmpq(R8, Address(CTX, Isolate::vm_tag_offset())); | 155 __ cmpq(R8, Address(R12, Isolate::vm_tag_offset())); |
| 175 __ j(EQUAL, &ok, Assembler::kNearJump); | 156 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 176 __ Stop("Not coming from Dart code."); | 157 __ Stop("Not coming from Dart code."); |
| 177 __ Bind(&ok); | 158 __ Bind(&ok); |
| 178 } | 159 } |
| 179 #endif | 160 #endif |
| 180 | 161 |
| 181 // Mark that the isolate is executing Native code. | 162 // Mark that the isolate is executing Native code. |
| 182 __ movq(Address(CTX, Isolate::vm_tag_offset()), RBX); | 163 __ movq(Address(R12, Isolate::vm_tag_offset()), RBX); |
| 183 | 164 |
| 184 // Reserve space for the native arguments structure passed on the stack (the | 165 // Reserve space for the native arguments structure passed on the stack (the |
| 185 // outgoing pointer parameter to the native arguments structure is passed in | 166 // outgoing pointer parameter to the native arguments structure is passed in |
| 186 // RDI) and align frame before entering the C++ world. | 167 // RDI) and align frame before entering the C++ world. |
| 187 __ subq(RSP, Immediate(sizeof(NativeArguments))); | 168 __ subq(RSP, Immediate(sizeof(NativeArguments))); |
| 188 if (OS::ActivationFrameAlignment() > 1) { | 169 if (OS::ActivationFrameAlignment() > 1) { |
| 189 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 170 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 190 } | 171 } |
| 191 | 172 |
| 192 // Pass NativeArguments structure by value and call native function. | 173 // Pass NativeArguments structure by value and call native function. |
| 193 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. | 174 __ movq(Address(RSP, isolate_offset), R12); // Set isolate in NativeArgs. |
| 194 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 175 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
| 195 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 176 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
| 196 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. | 177 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. |
| 197 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 178 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
| 198 | 179 |
| 199 // Pass the pointer to the NativeArguments. | 180 // Pass the pointer to the NativeArguments. |
| 200 __ movq(CallingConventions::kArg1Reg, RSP); | 181 __ movq(CallingConventions::kArg1Reg, RSP); |
| 201 // Pass pointer to function entrypoint. | 182 // Pass pointer to function entrypoint. |
| 202 __ movq(CallingConventions::kArg2Reg, RBX); | 183 __ movq(CallingConventions::kArg2Reg, RBX); |
| 203 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); | 184 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); |
| 204 | 185 |
| 205 // Mark that the isolate is executing Dart code. | 186 // Mark that the isolate is executing Dart code. |
| 206 __ movq(Address(CTX, Isolate::vm_tag_offset()), | 187 __ movq(Address(R12, Isolate::vm_tag_offset()), |
| 207 Immediate(VMTag::kDartTagId)); | 188 Immediate(VMTag::kDartTagId)); |
| 208 | 189 |
| 209 // Reset exit frame information in Isolate structure. | 190 // Reset exit frame information in Isolate structure. |
| 210 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 191 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 211 | |
| 212 // Load Context pointer from Isolate structure into R8. | |
| 213 __ movq(R8, Address(CTX, Isolate::top_context_offset())); | |
| 214 | |
| 215 // Reset Context pointer in Isolate structure. | |
| 216 __ LoadObject(R12, Object::null_object(), PP); | |
| 217 __ movq(Address(CTX, Isolate::top_context_offset()), R12); | |
| 218 | |
| 219 // Cache Context pointer into CTX while executing Dart code. | |
| 220 __ movq(CTX, R8); | |
| 221 | 192 |
| 222 __ LeaveFrame(); | 193 __ LeaveFrame(); |
| 223 __ ret(); | 194 __ ret(); |
| 224 } | 195 } |
| 225 | 196 |
| 226 | 197 |
| 227 // Input parameters: | 198 // Input parameters: |
| 228 // RSP : points to return address. | 199 // RSP : points to return address. |
| 229 // RSP + 8 : address of return value. | 200 // RSP + 8 : address of return value. |
| 230 // RAX : address of first argument in argument array. | 201 // RAX : address of first argument in argument array. |
| 231 // RBX : address of the native function to call. | 202 // RBX : address of the native function to call. |
| 232 // R10 : argc_tag including number of arguments and function kind. | 203 // R10 : argc_tag including number of arguments and function kind. |
| 233 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 204 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 234 const intptr_t native_args_struct_offset = 0; | 205 const intptr_t native_args_struct_offset = 0; |
| 235 const intptr_t isolate_offset = | 206 const intptr_t isolate_offset = |
| 236 NativeArguments::isolate_offset() + native_args_struct_offset; | 207 NativeArguments::isolate_offset() + native_args_struct_offset; |
| 237 const intptr_t argc_tag_offset = | 208 const intptr_t argc_tag_offset = |
| 238 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 209 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 239 const intptr_t argv_offset = | 210 const intptr_t argv_offset = |
| 240 NativeArguments::argv_offset() + native_args_struct_offset; | 211 NativeArguments::argv_offset() + native_args_struct_offset; |
| 241 const intptr_t retval_offset = | 212 const intptr_t retval_offset = |
| 242 NativeArguments::retval_offset() + native_args_struct_offset; | 213 NativeArguments::retval_offset() + native_args_struct_offset; |
| 243 | 214 |
| 244 __ EnterFrame(0); | 215 __ EnterFrame(0); |
| 245 | 216 |
| 246 __ LoadIsolate(R8); | 217 COMPILE_ASSERT( |
| 218 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
| 219 __ LoadIsolate(R12); |
| 247 | 220 |
| 248 // 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 |
| 249 // to transition to native code. | 222 // to transition to native code. |
| 250 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), RSP); | 223 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP); |
| 251 | |
| 252 // Save current Context pointer into Isolate structure. | |
| 253 __ movq(Address(R8, Isolate::top_context_offset()), CTX); | |
| 254 | |
| 255 // Cache Isolate pointer into CTX while executing native code. | |
| 256 __ movq(CTX, R8); | |
| 257 | 224 |
| 258 #if defined(DEBUG) | 225 #if defined(DEBUG) |
| 259 { Label ok; | 226 { Label ok; |
| 260 // Check that we are always entering from Dart code. | 227 // Check that we are always entering from Dart code. |
| 261 __ movq(R8, Immediate(VMTag::kDartTagId)); | 228 __ movq(R8, Immediate(VMTag::kDartTagId)); |
| 262 __ cmpq(R8, Address(CTX, Isolate::vm_tag_offset())); | 229 __ cmpq(R8, Address(R12, Isolate::vm_tag_offset())); |
| 263 __ j(EQUAL, &ok, Assembler::kNearJump); | 230 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 264 __ Stop("Not coming from Dart code."); | 231 __ Stop("Not coming from Dart code."); |
| 265 __ Bind(&ok); | 232 __ Bind(&ok); |
| 266 } | 233 } |
| 267 #endif | 234 #endif |
| 268 | 235 |
| 269 // Mark that the isolate is executing Native code. | 236 // Mark that the isolate is executing Native code. |
| 270 __ movq(Address(CTX, Isolate::vm_tag_offset()), RBX); | 237 __ movq(Address(R12, Isolate::vm_tag_offset()), RBX); |
| 271 | 238 |
| 272 // 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 |
| 273 // outgoing pointer parameter to the native arguments structure is passed in | 240 // outgoing pointer parameter to the native arguments structure is passed in |
| 274 // RDI) and align frame before entering the C++ world. | 241 // RDI) and align frame before entering the C++ world. |
| 275 __ subq(RSP, Immediate(sizeof(NativeArguments))); | 242 __ subq(RSP, Immediate(sizeof(NativeArguments))); |
| 276 if (OS::ActivationFrameAlignment() > 1) { | 243 if (OS::ActivationFrameAlignment() > 1) { |
| 277 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 244 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 278 } | 245 } |
| 279 | 246 |
| 280 // Pass NativeArguments structure by value and call native function. | 247 // Pass NativeArguments structure by value and call native function. |
| 281 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. | 248 __ movq(Address(RSP, isolate_offset), R12); // Set isolate in NativeArgs. |
| 282 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 249 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
| 283 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 250 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
| 284 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. | 251 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. |
| 285 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 252 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
| 286 | 253 |
| 287 // Pass the pointer to the NativeArguments. | 254 // Pass the pointer to the NativeArguments. |
| 288 __ movq(CallingConventions::kArg1Reg, RSP); | 255 __ movq(CallingConventions::kArg1Reg, RSP); |
| 289 __ CallCFunction(RBX); | 256 __ CallCFunction(RBX); |
| 290 | 257 |
| 291 // Mark that the isolate is executing Dart code. | 258 // Mark that the isolate is executing Dart code. |
| 292 __ movq(Address(CTX, Isolate::vm_tag_offset()), | 259 __ movq(Address(R12, Isolate::vm_tag_offset()), |
| 293 Immediate(VMTag::kDartTagId)); | 260 Immediate(VMTag::kDartTagId)); |
| 294 | 261 |
| 295 // Reset exit frame information in Isolate structure. | 262 // Reset exit frame information in Isolate structure. |
| 296 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 263 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 297 | |
| 298 // Load Context pointer from Isolate structure into R8. | |
| 299 __ movq(R8, Address(CTX, Isolate::top_context_offset())); | |
| 300 | |
| 301 // Reset Context pointer in Isolate structure. | |
| 302 __ LoadObject(R12, Object::null_object(), PP); | |
| 303 __ movq(Address(CTX, Isolate::top_context_offset()), R12); | |
| 304 | |
| 305 // Cache Context pointer into CTX while executing Dart code. | |
| 306 __ movq(CTX, R8); | |
| 307 | 264 |
| 308 __ LeaveFrame(); | 265 __ LeaveFrame(); |
| 309 __ ret(); | 266 __ ret(); |
| 310 } | 267 } |
| 311 | 268 |
| 312 | 269 |
| 313 // Input parameters: | 270 // Input parameters: |
| 314 // R10: arguments descriptor array. | 271 // R10: arguments descriptor array. |
| 315 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 272 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 316 __ EnterStubFrame(); | 273 __ EnterStubFrame(); |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 // RSI : arguments descriptor array. | 687 // RSI : arguments descriptor array. |
| 731 // RDX : arguments array. | 688 // RDX : arguments array. |
| 732 // RCX : new context containing the current isolate pointer. | 689 // RCX : new context containing the current isolate pointer. |
| 733 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 690 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 734 // Save frame pointer coming in. | 691 // Save frame pointer coming in. |
| 735 __ EnterFrame(0); | 692 __ EnterFrame(0); |
| 736 | 693 |
| 737 const Register kEntryPointReg = CallingConventions::kArg1Reg; | 694 const Register kEntryPointReg = CallingConventions::kArg1Reg; |
| 738 const Register kArgDescReg = CallingConventions::kArg2Reg; | 695 const Register kArgDescReg = CallingConventions::kArg2Reg; |
| 739 const Register kArgsReg = CallingConventions::kArg3Reg; | 696 const Register kArgsReg = CallingConventions::kArg3Reg; |
| 740 const Register kNewContextReg = CallingConventions::kArg4Reg; | |
| 741 | 697 |
| 742 // At this point, the stack looks like: | 698 // At this point, the stack looks like: |
| 743 // | saved RBP | <-- RBP | 699 // | saved RBP | <-- RBP |
| 744 // | saved PC (return to DartEntry::InvokeFunction) | | 700 // | saved PC (return to DartEntry::InvokeFunction) | |
| 745 | 701 |
| 746 const intptr_t kInitialOffset = 1; | 702 const intptr_t kInitialOffset = 1; |
| 747 // Save arguments descriptor array and new context. | 703 // Save arguments descriptor array. |
| 748 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; | 704 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; |
| 749 __ pushq(kArgDescReg); | 705 __ pushq(kArgDescReg); |
| 750 __ pushq(kNewContextReg); | |
| 751 | 706 |
| 752 // Save C++ ABI callee-saved registers. | 707 // Save C++ ABI callee-saved registers. |
| 753 __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters, | 708 __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters, |
| 754 CallingConventions::kCalleeSaveXmmRegisters); | 709 CallingConventions::kCalleeSaveXmmRegisters); |
| 755 | 710 |
| 756 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 711 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
| 757 // could potentially invoke some intrinsic functions which need the PP to be | 712 // could potentially invoke some intrinsic functions which need the PP to be |
| 758 // set up. | 713 // set up. |
| 759 __ LoadPoolPointer(PP); | 714 __ LoadPoolPointer(PP); |
| 760 | 715 |
| 761 // If any additional (or fewer) values are pushed, the offsets in | 716 // If any additional (or fewer) values are pushed, the offsets in |
| 762 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be | 717 // kExitLinkSlotFromEntryFp will need to be changed. |
| 763 // changed. | |
| 764 | |
| 765 // The new Context structure contains a pointer to the current Isolate | |
| 766 // structure. Cache the Context pointer in the CTX register so that it is | |
| 767 // available in generated code and calls to Isolate::Current() need not be | |
| 768 // done. The assumption is that this register will never be clobbered by | |
| 769 // compiled or runtime stub code. | |
| 770 | |
| 771 // Cache the new Context pointer into CTX while executing Dart code. | |
| 772 __ movq(CTX, Address(kNewContextReg, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 773 | |
| 774 const Register kIsolateReg = RBX; | |
| 775 | 718 |
| 776 // Load Isolate pointer into kIsolateReg. | 719 // Load Isolate pointer into kIsolateReg. |
| 720 const Register kIsolateReg = RBX; |
| 777 __ LoadIsolate(kIsolateReg); | 721 __ LoadIsolate(kIsolateReg); |
| 778 | 722 |
| 779 // Save the current VMTag on the stack. | 723 // Save the current VMTag on the stack. |
| 780 __ movq(RAX, Address(kIsolateReg, Isolate::vm_tag_offset())); | 724 __ movq(RAX, Address(kIsolateReg, Isolate::vm_tag_offset())); |
| 781 __ pushq(RAX); | 725 __ pushq(RAX); |
| 782 #if defined(DEBUG) | |
| 783 { | |
| 784 Label ok; | |
| 785 __ leaq(RAX, Address(RBP, kSavedVMTagSlotFromEntryFp * kWordSize)); | |
| 786 __ cmpq(RAX, RSP); | |
| 787 __ j(EQUAL, &ok); | |
| 788 __ Stop("kSavedVMTagSlotFromEntryFp mismatch"); | |
| 789 __ Bind(&ok); | |
| 790 } | |
| 791 #endif | |
| 792 | 726 |
| 793 // Mark that the isolate is executing Dart code. | 727 // Mark that the isolate is executing Dart code. |
| 794 __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()), | 728 __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()), |
| 795 Immediate(VMTag::kDartTagId)); | 729 Immediate(VMTag::kDartTagId)); |
| 796 | 730 |
| 797 // Save the top exit frame info. Use RAX as a temporary register. | 731 // Save the top exit frame info. Use RAX as a temporary register. |
| 798 // StackFrameIterator reads the top exit frame info saved in this frame. | 732 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 799 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the | 733 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the |
| 800 // code below. | 734 // code below. |
| 801 __ movq(RAX, Address(kIsolateReg, Isolate::top_exit_frame_info_offset())); | 735 __ movq(RAX, Address(kIsolateReg, Isolate::top_exit_frame_info_offset())); |
| 802 __ pushq(RAX); | 736 __ pushq(RAX); |
| 803 #if defined(DEBUG) | 737 #if defined(DEBUG) |
| 804 { | 738 { |
| 805 Label ok; | 739 Label ok; |
| 806 __ leaq(RAX, Address(RBP, kExitLinkSlotFromEntryFp * kWordSize)); | 740 __ leaq(RAX, Address(RBP, kExitLinkSlotFromEntryFp * kWordSize)); |
| 807 __ cmpq(RAX, RSP); | 741 __ cmpq(RAX, RSP); |
| 808 __ j(EQUAL, &ok); | 742 __ j(EQUAL, &ok); |
| 809 __ Stop("kExitLinkSlotFromEntryFp mismatch"); | 743 __ Stop("kExitLinkSlotFromEntryFp mismatch"); |
| 810 __ Bind(&ok); | 744 __ Bind(&ok); |
| 811 } | 745 } |
| 812 #endif | 746 #endif |
| 813 | 747 |
| 814 __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()), | 748 __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()), |
| 815 Immediate(0)); | 749 Immediate(0)); |
| 816 | 750 |
| 817 // Save the old Context pointer. Use RAX as a temporary register. | |
| 818 // Note that VisitObjectPointers will find this saved Context pointer during | |
| 819 // GC marking, since it traverses any information between SP and | |
| 820 // FP - kExitLinkSlotFromEntryFp * kWordSize. | |
| 821 // EntryFrame::SavedContext reads the context saved in this frame. | |
| 822 // The constant kSavedContextSlotFromEntryFp must be kept in sync with | |
| 823 // the code below. | |
| 824 __ movq(RAX, Address(kIsolateReg, Isolate::top_context_offset())); | |
| 825 __ pushq(RAX); | |
| 826 #if defined(DEBUG) | |
| 827 { | |
| 828 Label ok; | |
| 829 __ leaq(RAX, Address(RBP, kSavedContextSlotFromEntryFp * kWordSize)); | |
| 830 __ cmpq(RAX, RSP); | |
| 831 __ j(EQUAL, &ok); | |
| 832 __ Stop("kSavedContextSlotFromEntryFp mismatch"); | |
| 833 __ Bind(&ok); | |
| 834 } | |
| 835 #endif | |
| 836 | |
| 837 // Load arguments descriptor array into R10, which is passed to Dart code. | 751 // Load arguments descriptor array into R10, which is passed to Dart code. |
| 838 __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); | 752 __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); |
| 839 | 753 |
| 840 // Push arguments. At this point we only need to preserve kEntryPointReg. | 754 // Push arguments. At this point we only need to preserve kEntryPointReg. |
| 841 ASSERT(kEntryPointReg != RDX); | 755 ASSERT(kEntryPointReg != RDX); |
| 842 | 756 |
| 843 // Load number of arguments into RBX. | 757 // Load number of arguments into RBX. |
| 844 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 758 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 845 __ SmiUntag(RBX); | 759 __ SmiUntag(RBX); |
| 846 | 760 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 865 __ call(kEntryPointReg); // R10 is the arguments descriptor array. | 779 __ call(kEntryPointReg); // R10 is the arguments descriptor array. |
| 866 | 780 |
| 867 // Read the saved arguments descriptor array to obtain the number of passed | 781 // Read the saved arguments descriptor array to obtain the number of passed |
| 868 // arguments. | 782 // arguments. |
| 869 __ movq(kArgDescReg, Address(RBP, kArgumentsDescOffset)); | 783 __ movq(kArgDescReg, Address(RBP, kArgumentsDescOffset)); |
| 870 __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); | 784 __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); |
| 871 __ movq(RDX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 785 __ movq(RDX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 872 // Get rid of arguments pushed on the stack. | 786 // Get rid of arguments pushed on the stack. |
| 873 __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi. | 787 __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi. |
| 874 | 788 |
| 789 // Restore the saved top exit frame info back into the Isolate structure. |
| 875 __ LoadIsolate(kIsolateReg); | 790 __ LoadIsolate(kIsolateReg); |
| 876 // Restore the saved Context pointer into the Isolate structure. | |
| 877 __ popq(Address(kIsolateReg, Isolate::top_context_offset())); | |
| 878 | |
| 879 // Restore the saved top exit frame info back into the Isolate structure. | |
| 880 __ popq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset())); | 791 __ popq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset())); |
| 881 | 792 |
| 882 // Restore the current VMTag from the stack. | 793 // Restore the current VMTag from the stack. |
| 883 __ popq(Address(kIsolateReg, Isolate::vm_tag_offset())); | 794 __ popq(Address(kIsolateReg, Isolate::vm_tag_offset())); |
| 884 | 795 |
| 885 // Restore C++ ABI callee-saved registers. | 796 // Restore C++ ABI callee-saved registers. |
| 886 __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters, | 797 __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters, |
| 887 CallingConventions::kCalleeSaveXmmRegisters); | 798 CallingConventions::kCalleeSaveXmmRegisters); |
| 888 | 799 |
| 889 // Restore the frame pointer. | 800 // Restore the frame pointer. |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 | 1951 |
| 2041 __ movq(left, Address(RSP, 2 * kWordSize)); | 1952 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 2042 __ movq(right, Address(RSP, 1 * kWordSize)); | 1953 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 2043 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 1954 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2044 __ ret(); | 1955 __ ret(); |
| 2045 } | 1956 } |
| 2046 | 1957 |
| 2047 } // namespace dart | 1958 } // namespace dart |
| 2048 | 1959 |
| 2049 #endif // defined TARGET_ARCH_X64 | 1960 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |