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 |