| 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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 29 matching lines...) Expand all Loading... |
| 40 // EDX : number of arguments to the call. | 40 // EDX : number of arguments to the call. |
| 41 // Must preserve callee saved registers EDI and EBX. | 41 // Must preserve callee saved registers EDI and EBX. |
| 42 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 42 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 43 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 43 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 44 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 44 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 45 const intptr_t argv_offset = NativeArguments::argv_offset(); | 45 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 46 const intptr_t retval_offset = NativeArguments::retval_offset(); | 46 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 47 | 47 |
| 48 __ EnterFrame(0); | 48 __ EnterFrame(0); |
| 49 | 49 |
| 50 __ LoadIsolate(EAX); | 50 __ LoadIsolate(ESI); |
| 51 | 51 |
| 52 // Save exit frame information to enable stack walking as we are about | 52 // Save exit frame information to enable stack walking as we are about |
| 53 // to transition to Dart VM C++ code. | 53 // to transition to Dart VM C++ code. |
| 54 __ movl(Address(EAX, Isolate::top_exit_frame_info_offset()), ESP); | 54 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP); |
| 55 | |
| 56 #if defined(DEBUG) | |
| 57 if (FLAG_verify_incoming_contexts) { | |
| 58 Label ok; | |
| 59 // Check that the isolate's saved ctx is null. | |
| 60 const Immediate& raw_null = | |
| 61 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 62 __ cmpl(Address(EAX, Isolate::top_context_offset()), raw_null); | |
| 63 __ j(EQUAL, &ok, Assembler::kNearJump); | |
| 64 __ Stop("Found non-null incoming top context: call to runtime stub"); | |
| 65 __ Bind(&ok); | |
| 66 } | |
| 67 #endif | |
| 68 | |
| 69 // Save current Context pointer into Isolate structure. | |
| 70 __ movl(Address(EAX, Isolate::top_context_offset()), CTX); | |
| 71 | |
| 72 // Cache Isolate pointer into CTX while executing runtime code. | |
| 73 __ movl(CTX, EAX); | |
| 74 | 55 |
| 75 #if defined(DEBUG) | 56 #if defined(DEBUG) |
| 76 { Label ok; | 57 { Label ok; |
| 77 // Check that we are always entering from Dart code. | 58 // Check that we are always entering from Dart code. |
| 78 __ movl(EAX, Address(CTX, Isolate::vm_tag_offset())); | 59 __ cmpl(Address(ESI, Isolate::vm_tag_offset()), |
| 79 __ cmpl(EAX, Immediate(VMTag::kDartTagId)); | 60 Immediate(VMTag::kDartTagId)); |
| 80 __ j(EQUAL, &ok, Assembler::kNearJump); | 61 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 81 __ Stop("Not coming from Dart code."); | 62 __ Stop("Not coming from Dart code."); |
| 82 __ Bind(&ok); | 63 __ Bind(&ok); |
| 83 } | 64 } |
| 84 #endif | 65 #endif |
| 85 | 66 |
| 86 // Mark that the isolate is executing VM code. | 67 // Mark that the isolate is executing VM code. |
| 87 __ movl(Address(CTX, Isolate::vm_tag_offset()), ECX); | 68 __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX); |
| 88 | 69 |
| 89 // Reserve space for arguments and align frame before entering C++ world. | 70 // Reserve space for arguments and align frame before entering C++ world. |
| 90 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); | 71 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); |
| 91 if (OS::ActivationFrameAlignment() > 1) { | 72 if (OS::ActivationFrameAlignment() > 1) { |
| 92 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 73 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 93 } | 74 } |
| 94 | 75 |
| 95 // Pass NativeArguments structure by value and call runtime. | 76 // Pass NativeArguments structure by value and call runtime. |
| 96 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs. | 77 __ movl(Address(ESP, isolate_offset), ESI); // Set isolate in NativeArgs. |
| 97 // There are no runtime calls to closures, so we do not need to set the tag | 78 // There are no runtime calls to closures, so we do not need to set the tag |
| 98 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 79 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 99 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 80 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 100 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. | 81 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. |
| 101 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 82 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 102 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. | 83 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. |
| 103 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 84 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 104 __ call(ECX); | 85 __ call(ECX); |
| 105 | 86 |
| 106 // Mark that the isolate is executing Dart code. | 87 // Mark that the isolate is executing Dart code. ESI is callee saved. |
| 107 __ movl(Address(CTX, Isolate::vm_tag_offset()), | 88 __ movl(Address(ESI, Isolate::vm_tag_offset()), |
| 108 Immediate(VMTag::kDartTagId)); | 89 Immediate(VMTag::kDartTagId)); |
| 109 | 90 |
| 110 // Reset exit frame information in Isolate structure. | 91 // Reset exit frame information in Isolate structure. |
| 111 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 92 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 112 | |
| 113 // Load Context pointer from Isolate structure into ECX. | |
| 114 __ movl(ECX, Address(CTX, Isolate::top_context_offset())); | |
| 115 | |
| 116 // Reset Context pointer in Isolate structure. | |
| 117 const Immediate& raw_null = | |
| 118 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 119 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); | |
| 120 | |
| 121 // Cache Context pointer into CTX while executing Dart code. | |
| 122 __ movl(CTX, ECX); | |
| 123 | 93 |
| 124 __ LeaveFrame(); | 94 __ LeaveFrame(); |
| 125 __ ret(); | 95 __ ret(); |
| 126 } | 96 } |
| 127 | 97 |
| 128 | 98 |
| 129 // Print the stop message. | 99 // Print the stop message. |
| 130 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 100 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| 131 OS::Print("Stop message: %s\n", message); | 101 OS::Print("Stop message: %s\n", message); |
| 132 } | 102 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 160 NativeArguments::isolate_offset() + native_args_struct_offset; | 130 NativeArguments::isolate_offset() + native_args_struct_offset; |
| 161 const intptr_t argc_tag_offset = | 131 const intptr_t argc_tag_offset = |
| 162 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 132 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 163 const intptr_t argv_offset = | 133 const intptr_t argv_offset = |
| 164 NativeArguments::argv_offset() + native_args_struct_offset; | 134 NativeArguments::argv_offset() + native_args_struct_offset; |
| 165 const intptr_t retval_offset = | 135 const intptr_t retval_offset = |
| 166 NativeArguments::retval_offset() + native_args_struct_offset; | 136 NativeArguments::retval_offset() + native_args_struct_offset; |
| 167 | 137 |
| 168 __ EnterFrame(0); | 138 __ EnterFrame(0); |
| 169 | 139 |
| 170 __ LoadIsolate(EDI); | 140 __ LoadIsolate(ESI); |
| 171 | 141 |
| 172 // Save exit frame information to enable stack walking as we are about | 142 // Save exit frame information to enable stack walking as we are about |
| 173 // to transition to dart VM code. | 143 // to transition to dart VM code. |
| 174 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), ESP); | 144 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP); |
| 175 | |
| 176 #if defined(DEBUG) | |
| 177 if (FLAG_verify_incoming_contexts) { | |
| 178 Label ok; | |
| 179 // Check that the isolate's saved ctx is null. | |
| 180 const Immediate& raw_null = | |
| 181 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 182 __ cmpl(Address(EDI, Isolate::top_context_offset()), raw_null); | |
| 183 __ j(EQUAL, &ok, Assembler::kNearJump); | |
| 184 __ Stop("Found non-null incoming top context: " | |
| 185 "call to native c function stub"); | |
| 186 __ Bind(&ok); | |
| 187 } | |
| 188 #endif | |
| 189 | |
| 190 // Save current Context pointer into Isolate structure. | |
| 191 __ movl(Address(EDI, Isolate::top_context_offset()), CTX); | |
| 192 | |
| 193 // Cache Isolate pointer into CTX while executing native code. | |
| 194 __ movl(CTX, EDI); | |
| 195 | 145 |
| 196 #if defined(DEBUG) | 146 #if defined(DEBUG) |
| 197 { Label ok; | 147 { Label ok; |
| 198 // Check that we are always entering from Dart code. | 148 // Check that we are always entering from Dart code. |
| 199 __ movl(EDI, Address(CTX, Isolate::vm_tag_offset())); | 149 __ cmpl(Address(ESI, Isolate::vm_tag_offset()), |
| 200 __ cmpl(EDI, Immediate(VMTag::kDartTagId)); | 150 Immediate(VMTag::kDartTagId)); |
| 201 __ j(EQUAL, &ok, Assembler::kNearJump); | 151 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 202 __ Stop("Not coming from Dart code."); | 152 __ Stop("Not coming from Dart code."); |
| 203 __ Bind(&ok); | 153 __ Bind(&ok); |
| 204 } | 154 } |
| 205 #endif | 155 #endif |
| 206 | 156 |
| 207 // Mark that the isolate is executing Native code. | 157 // Mark that the isolate is executing Native code. |
| 208 __ movl(Address(CTX, Isolate::vm_tag_offset()), ECX); | 158 __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX); |
| 209 | 159 |
| 210 // Reserve space for the native arguments structure, the outgoing parameters | 160 // Reserve space for the native arguments structure, the outgoing parameters |
| 211 // (pointer to the native arguments structure, the C function entry point) | 161 // (pointer to the native arguments structure, the C function entry point) |
| 212 // and align frame before entering the C++ world. | 162 // and align frame before entering the C++ world. |
| 213 __ AddImmediate(ESP, | 163 __ AddImmediate(ESP, |
| 214 Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize))); | 164 Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize))); |
| 215 if (OS::ActivationFrameAlignment() > 1) { | 165 if (OS::ActivationFrameAlignment() > 1) { |
| 216 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 166 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 217 } | 167 } |
| 218 | 168 |
| 219 // Pass NativeArguments structure by value and call native function. | 169 // Pass NativeArguments structure by value and call native function. |
| 220 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs. | 170 __ movl(Address(ESP, isolate_offset), ESI); // Set isolate in NativeArgs. |
| 221 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 171 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 222 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 172 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 223 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. | 173 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. |
| 224 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 174 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 225 __ leal(EAX, Address(ESP, 2 * kWordSize)); // Pointer to the NativeArguments. | 175 __ leal(EAX, Address(ESP, 2 * kWordSize)); // Pointer to the NativeArguments. |
| 226 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. | 176 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. |
| 227 | 177 |
| 228 __ movl(Address(ESP, kWordSize), ECX); // Function to call. | 178 __ movl(Address(ESP, kWordSize), ECX); // Function to call. |
| 229 __ call(&NativeEntry::NativeCallWrapperLabel()); | 179 __ call(&NativeEntry::NativeCallWrapperLabel()); |
| 230 | 180 |
| 231 // Mark that the isolate is executing Dart code. | 181 // Mark that the isolate is executing Dart code. ESI is callee saved. |
| 232 __ movl(Address(CTX, Isolate::vm_tag_offset()), | 182 __ movl(Address(ESI, Isolate::vm_tag_offset()), |
| 233 Immediate(VMTag::kDartTagId)); | 183 Immediate(VMTag::kDartTagId)); |
| 234 | 184 |
| 235 // Reset exit frame information in Isolate structure. | 185 // Reset exit frame information in Isolate structure. |
| 236 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 186 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 237 | |
| 238 // Load Context pointer from Isolate structure into EDI. | |
| 239 __ movl(EDI, Address(CTX, Isolate::top_context_offset())); | |
| 240 | |
| 241 // Reset Context pointer in Isolate structure. | |
| 242 const Immediate& raw_null = | |
| 243 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 244 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); | |
| 245 | |
| 246 // Cache Context pointer into CTX while executing Dart code. | |
| 247 __ movl(CTX, EDI); | |
| 248 | 187 |
| 249 __ LeaveFrame(); | 188 __ LeaveFrame(); |
| 250 __ ret(); | 189 __ ret(); |
| 251 } | 190 } |
| 252 | 191 |
| 253 | 192 |
| 254 // Input parameters: | 193 // Input parameters: |
| 255 // ESP : points to return address. | 194 // ESP : points to return address. |
| 256 // ESP + 4 : address of return value. | 195 // ESP + 4 : address of return value. |
| 257 // EAX : address of first argument in argument array. | 196 // EAX : address of first argument in argument array. |
| 258 // ECX : address of the native function to call. | 197 // ECX : address of the native function to call. |
| 259 // EDX : argc_tag including number of arguments and function kind. | 198 // EDX : argc_tag including number of arguments and function kind. |
| 260 // Uses EDI. | 199 // Uses EDI. |
| 261 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 200 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 262 const intptr_t native_args_struct_offset = kWordSize; | 201 const intptr_t native_args_struct_offset = kWordSize; |
| 263 const intptr_t isolate_offset = | 202 const intptr_t isolate_offset = |
| 264 NativeArguments::isolate_offset() + native_args_struct_offset; | 203 NativeArguments::isolate_offset() + native_args_struct_offset; |
| 265 const intptr_t argc_tag_offset = | 204 const intptr_t argc_tag_offset = |
| 266 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 205 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 267 const intptr_t argv_offset = | 206 const intptr_t argv_offset = |
| 268 NativeArguments::argv_offset() + native_args_struct_offset; | 207 NativeArguments::argv_offset() + native_args_struct_offset; |
| 269 const intptr_t retval_offset = | 208 const intptr_t retval_offset = |
| 270 NativeArguments::retval_offset() + native_args_struct_offset; | 209 NativeArguments::retval_offset() + native_args_struct_offset; |
| 271 | 210 |
| 272 __ EnterFrame(0); | 211 __ EnterFrame(0); |
| 273 | 212 |
| 274 __ LoadIsolate(EDI); | 213 __ LoadIsolate(ESI); |
| 275 | 214 |
| 276 // Save exit frame information to enable stack walking as we are about | 215 // Save exit frame information to enable stack walking as we are about |
| 277 // to transition to dart VM code. | 216 // to transition to dart VM code. |
| 278 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), ESP); | 217 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP); |
| 279 | |
| 280 #if defined(DEBUG) | |
| 281 if (FLAG_verify_incoming_contexts) { | |
| 282 Label ok; | |
| 283 // Check that the isolate's saved ctx is null. | |
| 284 const Immediate& raw_null = | |
| 285 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 286 __ cmpl(Address(EDI, Isolate::top_context_offset()), raw_null); | |
| 287 __ j(EQUAL, &ok, Assembler::kNearJump); | |
| 288 __ Stop("Found non-null incoming top context: " | |
| 289 "call to bootstrap c function stub"); | |
| 290 __ Bind(&ok); | |
| 291 } | |
| 292 #endif | |
| 293 | |
| 294 // Save current Context pointer into Isolate structure. | |
| 295 __ movl(Address(EDI, Isolate::top_context_offset()), CTX); | |
| 296 | |
| 297 // Cache Isolate pointer into CTX while executing native code. | |
| 298 __ movl(CTX, EDI); | |
| 299 | 218 |
| 300 #if defined(DEBUG) | 219 #if defined(DEBUG) |
| 301 { Label ok; | 220 { Label ok; |
| 302 // Check that we are always entering from Dart code. | 221 // Check that we are always entering from Dart code. |
| 303 __ movl(EDI, Address(CTX, Isolate::vm_tag_offset())); | 222 __ cmpl(Address(ESI, Isolate::vm_tag_offset()), |
| 304 __ cmpl(EDI, Immediate(VMTag::kDartTagId)); | 223 Immediate(VMTag::kDartTagId)); |
| 305 __ j(EQUAL, &ok, Assembler::kNearJump); | 224 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 306 __ Stop("Not coming from Dart code."); | 225 __ Stop("Not coming from Dart code."); |
| 307 __ Bind(&ok); | 226 __ Bind(&ok); |
| 308 } | 227 } |
| 309 #endif | 228 #endif |
| 310 | 229 |
| 311 // Mark that the isolate is executing Native code. | 230 // Mark that the isolate is executing Native code. |
| 312 __ movl(Address(CTX, Isolate::vm_tag_offset()), ECX); | 231 __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX); |
| 313 | 232 |
| 314 // Reserve space for the native arguments structure, the outgoing parameter | 233 // Reserve space for the native arguments structure, the outgoing parameter |
| 315 // (pointer to the native arguments structure) and align frame before | 234 // (pointer to the native arguments structure) and align frame before |
| 316 // entering the C++ world. | 235 // entering the C++ world. |
| 317 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize)); | 236 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize)); |
| 318 if (OS::ActivationFrameAlignment() > 1) { | 237 if (OS::ActivationFrameAlignment() > 1) { |
| 319 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 238 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 320 } | 239 } |
| 321 | 240 |
| 322 // Pass NativeArguments structure by value and call native function. | 241 // Pass NativeArguments structure by value and call native function. |
| 323 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs. | 242 __ movl(Address(ESP, isolate_offset), ESI); // Set isolate in NativeArgs. |
| 324 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 243 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 325 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 244 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 326 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. | 245 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. |
| 327 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 246 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 328 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. | 247 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. |
| 329 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. | 248 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. |
| 330 __ call(ECX); | 249 __ call(ECX); |
| 331 | 250 |
| 332 // Mark that the isolate is executing Dart code. | 251 // Mark that the isolate is executing Dart code. ESI is callee saved. |
| 333 __ movl(Address(CTX, Isolate::vm_tag_offset()), | 252 __ movl(Address(ESI, Isolate::vm_tag_offset()), |
| 334 Immediate(VMTag::kDartTagId)); | 253 Immediate(VMTag::kDartTagId)); |
| 335 | 254 |
| 336 // Reset exit frame information in Isolate structure. | 255 // Reset exit frame information in Isolate structure. |
| 337 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 256 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 338 | |
| 339 // Load Context pointer from Isolate structure into EDI. | |
| 340 __ movl(EDI, Address(CTX, Isolate::top_context_offset())); | |
| 341 | |
| 342 // Reset Context pointer in Isolate structure. | |
| 343 const Immediate& raw_null = | |
| 344 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 345 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); | |
| 346 | |
| 347 // Cache Context pointer into CTX while executing Dart code. | |
| 348 __ movl(CTX, EDI); | |
| 349 | 257 |
| 350 __ LeaveFrame(); | 258 __ LeaveFrame(); |
| 351 __ ret(); | 259 __ ret(); |
| 352 } | 260 } |
| 353 | 261 |
| 354 | 262 |
| 355 // Input parameters: | 263 // Input parameters: |
| 356 // EDX: arguments descriptor array. | 264 // EDX: arguments descriptor array. |
| 357 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 265 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 358 const Immediate& raw_null = | 266 const Immediate& raw_null = |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 __ jmp(&stub_code->FixAllocateArrayStubTargetLabel()); | 680 __ jmp(&stub_code->FixAllocateArrayStubTargetLabel()); |
| 773 } | 681 } |
| 774 | 682 |
| 775 | 683 |
| 776 // Called when invoking dart code from C++ (VM code). | 684 // Called when invoking dart code from C++ (VM code). |
| 777 // Input parameters: | 685 // Input parameters: |
| 778 // ESP : points to return address. | 686 // ESP : points to return address. |
| 779 // ESP + 4 : entrypoint of the dart function to call. | 687 // ESP + 4 : entrypoint of the dart function to call. |
| 780 // ESP + 8 : arguments descriptor array. | 688 // ESP + 8 : arguments descriptor array. |
| 781 // ESP + 12 : arguments array. | 689 // ESP + 12 : arguments array. |
| 782 // ESP + 16 : new context containing the current isolate pointer. | |
| 783 // Uses EAX, EDX, ECX, EDI as temporary registers. | 690 // Uses EAX, EDX, ECX, EDI as temporary registers. |
| 784 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 691 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 785 const intptr_t kEntryPointOffset = 2 * kWordSize; | 692 const intptr_t kEntryPointOffset = 2 * kWordSize; |
| 786 const intptr_t kArgumentsDescOffset = 3 * kWordSize; | 693 const intptr_t kArgumentsDescOffset = 3 * kWordSize; |
| 787 const intptr_t kArgumentsOffset = 4 * kWordSize; | 694 const intptr_t kArgumentsOffset = 4 * kWordSize; |
| 788 const intptr_t kNewContextOffset = 5 * kWordSize; | |
| 789 | 695 |
| 790 // Save frame pointer coming in. | 696 // Save frame pointer coming in. |
| 791 __ EnterFrame(0); | 697 __ EnterFrame(0); |
| 792 | 698 |
| 793 // Save C++ ABI callee-saved registers. | 699 // Save C++ ABI callee-saved registers. |
| 794 __ pushl(EBX); | 700 __ pushl(EBX); |
| 795 __ pushl(ESI); | 701 __ pushl(ESI); |
| 796 __ pushl(EDI); | 702 __ pushl(EDI); |
| 797 | 703 |
| 798 // The new Context structure contains a pointer to the current Isolate | 704 __ LoadIsolate(ESI); |
| 799 // structure. Cache the Context pointer in the CTX register so that it is | |
| 800 // available in generated code and calls to Isolate::Current() need not be | |
| 801 // done. The assumption is that this register will never be clobbered by | |
| 802 // compiled or runtime stub code. | |
| 803 | |
| 804 // Cache the new Context pointer into CTX while executing dart code. | |
| 805 __ movl(CTX, Address(EBP, kNewContextOffset)); | |
| 806 __ movl(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 807 | |
| 808 __ LoadIsolate(EDI); | |
| 809 | 705 |
| 810 // Save the current VMTag on the stack. | 706 // Save the current VMTag on the stack. |
| 811 ASSERT(kSavedVMTagSlotFromEntryFp == -4); | 707 __ movl(ECX, Address(ESI, Isolate::vm_tag_offset())); |
| 812 __ movl(ECX, Address(EDI, Isolate::vm_tag_offset())); | |
| 813 __ pushl(ECX); | 708 __ pushl(ECX); |
| 814 | 709 |
| 815 // Mark that the isolate is executing Dart code. | 710 // Mark that the isolate is executing Dart code. |
| 816 __ movl(Address(EDI, Isolate::vm_tag_offset()), | 711 __ movl(Address(ESI, Isolate::vm_tag_offset()), |
| 817 Immediate(VMTag::kDartTagId)); | 712 Immediate(VMTag::kDartTagId)); |
| 818 | 713 |
| 819 // Save the top exit frame info. Use EDX as a temporary register. | 714 // Save the top exit frame info. Use EDX as a temporary register. |
| 820 // StackFrameIterator reads the top exit frame info saved in this frame. | 715 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 821 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the | 716 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the |
| 822 // code below. | 717 // code below. |
| 823 ASSERT(kExitLinkSlotFromEntryFp == -5); | 718 ASSERT(kExitLinkSlotFromEntryFp == -5); |
| 824 __ movl(EDX, Address(EDI, Isolate::top_exit_frame_info_offset())); | 719 __ movl(EDX, Address(ESI, Isolate::top_exit_frame_info_offset())); |
| 825 __ pushl(EDX); | 720 __ pushl(EDX); |
| 826 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 721 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 827 | |
| 828 // Save the old Context pointer. Use ECX as a temporary register. | |
| 829 // Note that VisitObjectPointers will find this saved Context pointer during | |
| 830 // GC marking, since it traverses any information between SP and | |
| 831 // FP - kExitLinkSlotFromEntryFp. | |
| 832 // EntryFrame::SavedContext reads the context saved in this frame. | |
| 833 // The constant kSavedContextSlotFromEntryFp must be kept in sync with | |
| 834 // the code below. | |
| 835 ASSERT(kSavedContextSlotFromEntryFp == -6); | |
| 836 __ movl(ECX, Address(EDI, Isolate::top_context_offset())); | |
| 837 __ pushl(ECX); | |
| 838 | |
| 839 // TODO(turnidge): This code should probably be emitted all the time | |
| 840 // on all architectures but I am leaving it under DEBUG/flag for | |
| 841 // now. | |
| 842 #if defined(DEBUG) | |
| 843 if (FLAG_verify_incoming_contexts) { | |
| 844 // Clear Context pointer in Isolate structure. | |
| 845 const Immediate& raw_null = | |
| 846 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 847 __ movl(Address(EDI, Isolate::top_context_offset()), raw_null); | |
| 848 } | |
| 849 #endif | |
| 850 | 722 |
| 851 // Load arguments descriptor array into EDX. | 723 // Load arguments descriptor array into EDX. |
| 852 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); | 724 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); |
| 853 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); | 725 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 854 | 726 |
| 855 // Load number of arguments into EBX. | 727 // Load number of arguments into EBX. |
| 856 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 728 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 857 __ SmiUntag(EBX); | 729 __ SmiUntag(EBX); |
| 858 | 730 |
| 859 // Set up arguments for the dart call. | 731 // Set up arguments for the dart call. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 880 __ call(Address(EBP, kEntryPointOffset)); | 752 __ call(Address(EBP, kEntryPointOffset)); |
| 881 | 753 |
| 882 // Reread the arguments descriptor array to obtain the number of passed | 754 // Reread the arguments descriptor array to obtain the number of passed |
| 883 // arguments. | 755 // arguments. |
| 884 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); | 756 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); |
| 885 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); | 757 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 886 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 758 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 887 // Get rid of arguments pushed on the stack. | 759 // Get rid of arguments pushed on the stack. |
| 888 __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi. | 760 __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi. |
| 889 | 761 |
| 890 // Load Isolate pointer into CTX. | |
| 891 __ LoadIsolate(CTX); | |
| 892 | |
| 893 // Restore the saved Context pointer into the Isolate structure. | |
| 894 __ popl(Address(CTX, Isolate::top_context_offset())); | |
| 895 | |
| 896 // Restore the saved top exit frame info back into the Isolate structure. | 762 // Restore the saved top exit frame info back into the Isolate structure. |
| 897 __ popl(Address(CTX, Isolate::top_exit_frame_info_offset())); | 763 __ LoadIsolate(ESI); |
| 764 __ popl(Address(ESI, Isolate::top_exit_frame_info_offset())); |
| 898 | 765 |
| 899 // Restore the current VMTag from the stack. | 766 // Restore the current VMTag from the stack. |
| 900 __ popl(Address(CTX, Isolate::vm_tag_offset())); | 767 __ popl(Address(ESI, Isolate::vm_tag_offset())); |
| 901 | 768 |
| 902 // Restore C++ ABI callee-saved registers. | 769 // Restore C++ ABI callee-saved registers. |
| 903 __ popl(EDI); | 770 __ popl(EDI); |
| 904 __ popl(ESI); | 771 __ popl(ESI); |
| 905 __ popl(EBX); | 772 __ popl(EBX); |
| 906 | 773 |
| 907 // Restore the frame pointer. | 774 // Restore the frame pointer. |
| 908 __ LeaveFrame(); | 775 __ LeaveFrame(); |
| 909 | 776 |
| 910 __ ret(); | 777 __ ret(); |
| (...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2076 const Register temp = ECX; | 1943 const Register temp = ECX; |
| 2077 __ movl(left, Address(ESP, 2 * kWordSize)); | 1944 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 2078 __ movl(right, Address(ESP, 1 * kWordSize)); | 1945 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 2079 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1946 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2080 __ ret(); | 1947 __ ret(); |
| 2081 } | 1948 } |
| 2082 | 1949 |
| 2083 } // namespace dart | 1950 } // namespace dart |
| 2084 | 1951 |
| 2085 #endif // defined TARGET_ARCH_IA32 | 1952 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |