| 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 30 matching lines...) Expand all Loading... |
| 41 // EDX : number of arguments to the call. | 41 // EDX : number of arguments to the call. |
| 42 // Must preserve callee saved registers EDI and EBX. | 42 // Must preserve callee saved registers EDI and EBX. |
| 43 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 43 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 44 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 44 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
| 45 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 45 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 46 const intptr_t argv_offset = NativeArguments::argv_offset(); | 46 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 47 const intptr_t retval_offset = NativeArguments::retval_offset(); | 47 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 48 | 48 |
| 49 __ EnterFrame(0); | 49 __ EnterFrame(0); |
| 50 | 50 |
| 51 __ LoadIsolate(ESI); | 51 __ LoadIsolate(EDI); |
| 52 | 52 |
| 53 // Save exit frame information to enable stack walking as we are about | 53 // Save exit frame information to enable stack walking as we are about |
| 54 // to transition to Dart VM C++ code. | 54 // to transition to Dart VM C++ code. |
| 55 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), EBP); | 55 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), EBP); |
| 56 | 56 |
| 57 #if defined(DEBUG) | 57 #if defined(DEBUG) |
| 58 { Label ok; | 58 { Label ok; |
| 59 // Check that we are always entering from Dart code. | 59 // Check that we are always entering from Dart code. |
| 60 __ cmpl(Address(ESI, Isolate::vm_tag_offset()), | 60 __ cmpl(Address(EDI, Isolate::vm_tag_offset()), |
| 61 Immediate(VMTag::kDartTagId)); | 61 Immediate(VMTag::kDartTagId)); |
| 62 __ j(EQUAL, &ok, Assembler::kNearJump); | 62 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 63 __ Stop("Not coming from Dart code."); | 63 __ Stop("Not coming from Dart code."); |
| 64 __ Bind(&ok); | 64 __ Bind(&ok); |
| 65 } | 65 } |
| 66 #endif | 66 #endif |
| 67 | 67 |
| 68 // Mark that the isolate is executing VM code. | 68 // Mark that the isolate is executing VM code. |
| 69 __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX); | 69 __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX); |
| 70 | 70 |
| 71 // Reserve space for arguments and align frame before entering C++ world. | 71 // Reserve space for arguments and align frame before entering C++ world. |
| 72 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); | 72 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); |
| 73 if (OS::ActivationFrameAlignment() > 1) { | 73 if (OS::ActivationFrameAlignment() > 1) { |
| 74 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 74 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Pass NativeArguments structure by value and call runtime. | 77 // Pass NativeArguments structure by value and call runtime. |
| 78 __ movl(Address(ESP, isolate_offset), ESI); // Set isolate in NativeArgs. | 78 __ movl(Address(ESP, isolate_offset), EDI); // Set isolate in NativeArgs. |
| 79 // There are no runtime calls to closures, so we do not need to set the tag | 79 // There are no runtime calls to closures, so we do not need to set the tag |
| 80 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 80 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 81 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 81 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 82 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. | 82 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. |
| 83 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 83 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 84 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. | 84 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. |
| 85 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 85 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 86 __ call(ECX); | 86 __ call(ECX); |
| 87 | 87 |
| 88 // Mark that the isolate is executing Dart code. ESI is callee saved. | 88 // Mark that the isolate is executing Dart code. EDI is callee saved. |
| 89 __ movl(Address(ESI, Isolate::vm_tag_offset()), | 89 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| 90 Immediate(VMTag::kDartTagId)); | 90 Immediate(VMTag::kDartTagId)); |
| 91 | 91 |
| 92 // Reset exit frame information in Isolate structure. | 92 // Reset exit frame information in Isolate structure. |
| 93 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 93 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 94 | 94 |
| 95 __ LeaveFrame(); | 95 __ LeaveFrame(); |
| 96 __ ret(); | 96 __ ret(); |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 // Print the stop message. | 100 // Print the stop message. |
| 101 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 101 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| 102 OS::Print("Stop message: %s\n", message); | 102 OS::Print("Stop message: %s\n", message); |
| 103 } | 103 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 131 NativeArguments::isolate_offset() + native_args_struct_offset; | 131 NativeArguments::isolate_offset() + native_args_struct_offset; |
| 132 const intptr_t argc_tag_offset = | 132 const intptr_t argc_tag_offset = |
| 133 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 133 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 134 const intptr_t argv_offset = | 134 const intptr_t argv_offset = |
| 135 NativeArguments::argv_offset() + native_args_struct_offset; | 135 NativeArguments::argv_offset() + native_args_struct_offset; |
| 136 const intptr_t retval_offset = | 136 const intptr_t retval_offset = |
| 137 NativeArguments::retval_offset() + native_args_struct_offset; | 137 NativeArguments::retval_offset() + native_args_struct_offset; |
| 138 | 138 |
| 139 __ EnterFrame(0); | 139 __ EnterFrame(0); |
| 140 | 140 |
| 141 __ LoadIsolate(ESI); | 141 __ LoadIsolate(EDI); |
| 142 | 142 |
| 143 // Save exit frame information to enable stack walking as we are about | 143 // Save exit frame information to enable stack walking as we are about |
| 144 // to transition to dart VM code. | 144 // to transition to dart VM code. |
| 145 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), EBP); | 145 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), EBP); |
| 146 | 146 |
| 147 #if defined(DEBUG) | 147 #if defined(DEBUG) |
| 148 { Label ok; | 148 { Label ok; |
| 149 // Check that we are always entering from Dart code. | 149 // Check that we are always entering from Dart code. |
| 150 __ cmpl(Address(ESI, Isolate::vm_tag_offset()), | 150 __ cmpl(Address(EDI, Isolate::vm_tag_offset()), |
| 151 Immediate(VMTag::kDartTagId)); | 151 Immediate(VMTag::kDartTagId)); |
| 152 __ j(EQUAL, &ok, Assembler::kNearJump); | 152 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 153 __ Stop("Not coming from Dart code."); | 153 __ Stop("Not coming from Dart code."); |
| 154 __ Bind(&ok); | 154 __ Bind(&ok); |
| 155 } | 155 } |
| 156 #endif | 156 #endif |
| 157 | 157 |
| 158 // Mark that the isolate is executing Native code. | 158 // Mark that the isolate is executing Native code. |
| 159 __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX); | 159 __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX); |
| 160 | 160 |
| 161 // Reserve space for the native arguments structure, the outgoing parameters | 161 // Reserve space for the native arguments structure, the outgoing parameters |
| 162 // (pointer to the native arguments structure, the C function entry point) | 162 // (pointer to the native arguments structure, the C function entry point) |
| 163 // and align frame before entering the C++ world. | 163 // and align frame before entering the C++ world. |
| 164 __ AddImmediate(ESP, | 164 __ AddImmediate(ESP, |
| 165 Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize))); | 165 Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize))); |
| 166 if (OS::ActivationFrameAlignment() > 1) { | 166 if (OS::ActivationFrameAlignment() > 1) { |
| 167 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 167 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 168 } | 168 } |
| 169 | 169 |
| 170 // Pass NativeArguments structure by value and call native function. | 170 // Pass NativeArguments structure by value and call native function. |
| 171 __ movl(Address(ESP, isolate_offset), ESI); // Set isolate in NativeArgs. | 171 __ movl(Address(ESP, isolate_offset), EDI); // Set isolate in NativeArgs. |
| 172 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 172 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 173 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 173 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 174 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. | 174 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. |
| 175 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 175 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 176 __ leal(EAX, Address(ESP, 2 * kWordSize)); // Pointer to the NativeArguments. | 176 __ leal(EAX, Address(ESP, 2 * kWordSize)); // Pointer to the NativeArguments. |
| 177 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. | 177 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. |
| 178 | 178 |
| 179 __ movl(Address(ESP, kWordSize), ECX); // Function to call. | 179 __ movl(Address(ESP, kWordSize), ECX); // Function to call. |
| 180 __ call(&NativeEntry::NativeCallWrapperLabel()); | 180 __ call(&NativeEntry::NativeCallWrapperLabel()); |
| 181 | 181 |
| 182 // Mark that the isolate is executing Dart code. ESI is callee saved. | 182 // Mark that the isolate is executing Dart code. EDI is callee saved. |
| 183 __ movl(Address(ESI, Isolate::vm_tag_offset()), | 183 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| 184 Immediate(VMTag::kDartTagId)); | 184 Immediate(VMTag::kDartTagId)); |
| 185 | 185 |
| 186 // Reset exit frame information in Isolate structure. | 186 // Reset exit frame information in Isolate structure. |
| 187 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 187 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 188 | 188 |
| 189 __ LeaveFrame(); | 189 __ LeaveFrame(); |
| 190 __ ret(); | 190 __ ret(); |
| 191 } | 191 } |
| 192 | 192 |
| 193 | 193 |
| 194 // Input parameters: | 194 // Input parameters: |
| 195 // ESP : points to return address. | 195 // ESP : points to return address. |
| 196 // ESP + 4 : address of return value. | 196 // ESP + 4 : address of return value. |
| 197 // EAX : address of first argument in argument array. | 197 // EAX : address of first argument in argument array. |
| 198 // ECX : address of the native function to call. | 198 // ECX : address of the native function to call. |
| 199 // EDX : argc_tag including number of arguments and function kind. | 199 // EDX : argc_tag including number of arguments and function kind. |
| 200 // Uses EDI. | 200 // Uses EDI. |
| 201 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 201 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 202 const intptr_t native_args_struct_offset = kWordSize; | 202 const intptr_t native_args_struct_offset = kWordSize; |
| 203 const intptr_t isolate_offset = | 203 const intptr_t isolate_offset = |
| 204 NativeArguments::isolate_offset() + native_args_struct_offset; | 204 NativeArguments::isolate_offset() + native_args_struct_offset; |
| 205 const intptr_t argc_tag_offset = | 205 const intptr_t argc_tag_offset = |
| 206 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 206 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 207 const intptr_t argv_offset = | 207 const intptr_t argv_offset = |
| 208 NativeArguments::argv_offset() + native_args_struct_offset; | 208 NativeArguments::argv_offset() + native_args_struct_offset; |
| 209 const intptr_t retval_offset = | 209 const intptr_t retval_offset = |
| 210 NativeArguments::retval_offset() + native_args_struct_offset; | 210 NativeArguments::retval_offset() + native_args_struct_offset; |
| 211 | 211 |
| 212 __ EnterFrame(0); | 212 __ EnterFrame(0); |
| 213 | 213 |
| 214 __ LoadIsolate(ESI); | 214 __ LoadIsolate(EDI); |
| 215 | 215 |
| 216 // Save exit frame information to enable stack walking as we are about | 216 // Save exit frame information to enable stack walking as we are about |
| 217 // to transition to dart VM code. | 217 // to transition to dart VM code. |
| 218 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), EBP); | 218 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), EBP); |
| 219 | 219 |
| 220 #if defined(DEBUG) | 220 #if defined(DEBUG) |
| 221 { Label ok; | 221 { Label ok; |
| 222 // Check that we are always entering from Dart code. | 222 // Check that we are always entering from Dart code. |
| 223 __ cmpl(Address(ESI, Isolate::vm_tag_offset()), | 223 __ cmpl(Address(EDI, Isolate::vm_tag_offset()), |
| 224 Immediate(VMTag::kDartTagId)); | 224 Immediate(VMTag::kDartTagId)); |
| 225 __ j(EQUAL, &ok, Assembler::kNearJump); | 225 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 226 __ Stop("Not coming from Dart code."); | 226 __ Stop("Not coming from Dart code."); |
| 227 __ Bind(&ok); | 227 __ Bind(&ok); |
| 228 } | 228 } |
| 229 #endif | 229 #endif |
| 230 | 230 |
| 231 // Mark that the isolate is executing Native code. | 231 // Mark that the isolate is executing Native code. |
| 232 __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX); | 232 __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX); |
| 233 | 233 |
| 234 // Reserve space for the native arguments structure, the outgoing parameter | 234 // Reserve space for the native arguments structure, the outgoing parameter |
| 235 // (pointer to the native arguments structure) and align frame before | 235 // (pointer to the native arguments structure) and align frame before |
| 236 // entering the C++ world. | 236 // entering the C++ world. |
| 237 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize)); | 237 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize)); |
| 238 if (OS::ActivationFrameAlignment() > 1) { | 238 if (OS::ActivationFrameAlignment() > 1) { |
| 239 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 239 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 240 } | 240 } |
| 241 | 241 |
| 242 // Pass NativeArguments structure by value and call native function. | 242 // Pass NativeArguments structure by value and call native function. |
| 243 __ movl(Address(ESP, isolate_offset), ESI); // Set isolate in NativeArgs. | 243 __ movl(Address(ESP, isolate_offset), EDI); // Set isolate in NativeArgs. |
| 244 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 244 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 245 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 245 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 246 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. | 246 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. |
| 247 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 247 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 248 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. | 248 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. |
| 249 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. | 249 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. |
| 250 __ call(ECX); | 250 __ call(ECX); |
| 251 | 251 |
| 252 // Mark that the isolate is executing Dart code. ESI is callee saved. | 252 // Mark that the isolate is executing Dart code. EDI is callee saved. |
| 253 __ movl(Address(ESI, Isolate::vm_tag_offset()), | 253 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| 254 Immediate(VMTag::kDartTagId)); | 254 Immediate(VMTag::kDartTagId)); |
| 255 | 255 |
| 256 // Reset exit frame information in Isolate structure. | 256 // Reset exit frame information in Isolate structure. |
| 257 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 257 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 258 | 258 |
| 259 __ LeaveFrame(); | 259 __ LeaveFrame(); |
| 260 __ ret(); | 260 __ ret(); |
| 261 } | 261 } |
| 262 | 262 |
| 263 | 263 |
| 264 // Input parameters: | 264 // Input parameters: |
| 265 // EDX: arguments descriptor array. | 265 // EDX: arguments descriptor array. |
| 266 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 266 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 267 const Immediate& raw_null = | 267 const Immediate& raw_null = |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 __ jmp(&stub_code->FixAllocateArrayStubTargetLabel()); | 683 __ jmp(&stub_code->FixAllocateArrayStubTargetLabel()); |
| 684 } | 684 } |
| 685 | 685 |
| 686 | 686 |
| 687 // Called when invoking dart code from C++ (VM code). | 687 // Called when invoking dart code from C++ (VM code). |
| 688 // Input parameters: | 688 // Input parameters: |
| 689 // ESP : points to return address. | 689 // ESP : points to return address. |
| 690 // ESP + 4 : entrypoint of the dart function to call. | 690 // ESP + 4 : entrypoint of the dart function to call. |
| 691 // ESP + 8 : arguments descriptor array. | 691 // ESP + 8 : arguments descriptor array. |
| 692 // ESP + 12 : arguments array. | 692 // ESP + 12 : arguments array. |
| 693 // ESP + 16 : current thread. |
| 693 // Uses EAX, EDX, ECX, EDI as temporary registers. | 694 // Uses EAX, EDX, ECX, EDI as temporary registers. |
| 694 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 695 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 695 const intptr_t kEntryPointOffset = 2 * kWordSize; | 696 const intptr_t kEntryPointOffset = 2 * kWordSize; |
| 696 const intptr_t kArgumentsDescOffset = 3 * kWordSize; | 697 const intptr_t kArgumentsDescOffset = 3 * kWordSize; |
| 697 const intptr_t kArgumentsOffset = 4 * kWordSize; | 698 const intptr_t kArgumentsOffset = 4 * kWordSize; |
| 699 const intptr_t kThreadOffset = 5 * kWordSize; |
| 698 | 700 |
| 699 // Save frame pointer coming in. | 701 // Save frame pointer coming in. |
| 700 __ EnterFrame(0); | 702 __ EnterFrame(0); |
| 701 | 703 |
| 702 // Save C++ ABI callee-saved registers. | 704 // Save C++ ABI callee-saved registers. |
| 703 __ pushl(EBX); | 705 __ pushl(EBX); |
| 704 __ pushl(ESI); | 706 __ pushl(ESI); |
| 705 __ pushl(EDI); | 707 __ pushl(EDI); |
| 706 | 708 |
| 707 __ LoadIsolate(ESI); | 709 // Set up THR, which caches the current thread in Dart code. |
| 710 __ movl(THR, Address(EBP, kThreadOffset)); |
| 711 __ LoadIsolate(EDI); |
| 708 | 712 |
| 709 // Save the current VMTag on the stack. | 713 // Save the current VMTag on the stack. |
| 710 __ movl(ECX, Address(ESI, Isolate::vm_tag_offset())); | 714 __ movl(ECX, Address(EDI, Isolate::vm_tag_offset())); |
| 711 __ pushl(ECX); | 715 __ pushl(ECX); |
| 712 | 716 |
| 713 // Mark that the isolate is executing Dart code. | 717 // Mark that the isolate is executing Dart code. |
| 714 __ movl(Address(ESI, Isolate::vm_tag_offset()), | 718 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| 715 Immediate(VMTag::kDartTagId)); | 719 Immediate(VMTag::kDartTagId)); |
| 716 | 720 |
| 717 // Save top resource and top exit frame info. Use EDX as a temporary register. | 721 // Save top resource and top exit frame info. Use EDX as a temporary register. |
| 718 // StackFrameIterator reads the top exit frame info saved in this frame. | 722 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 719 __ movl(EDX, Address(ESI, Isolate::top_resource_offset())); | 723 __ movl(EDX, Address(EDI, Isolate::top_resource_offset())); |
| 720 __ pushl(EDX); | 724 __ pushl(EDX); |
| 721 __ movl(Address(ESI, Isolate::top_resource_offset()), Immediate(0)); | 725 __ movl(Address(EDI, Isolate::top_resource_offset()), Immediate(0)); |
| 722 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the | 726 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the |
| 723 // code below. | 727 // code below. |
| 724 ASSERT(kExitLinkSlotFromEntryFp == -6); | 728 ASSERT(kExitLinkSlotFromEntryFp == -6); |
| 725 __ movl(EDX, Address(ESI, Isolate::top_exit_frame_info_offset())); | 729 __ movl(EDX, Address(EDI, Isolate::top_exit_frame_info_offset())); |
| 726 __ pushl(EDX); | 730 __ pushl(EDX); |
| 727 __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 731 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 728 | 732 |
| 729 // Load arguments descriptor array into EDX. | 733 // Load arguments descriptor array into EDX. |
| 730 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); | 734 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); |
| 731 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); | 735 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 732 | 736 |
| 733 // Load number of arguments into EBX. | 737 // Load number of arguments into EBX. |
| 734 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 738 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 735 __ SmiUntag(EBX); | 739 __ SmiUntag(EBX); |
| 736 | 740 |
| 737 // Set up arguments for the dart call. | 741 // Set up arguments for the dart call. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 760 // Reread the arguments descriptor array to obtain the number of passed | 764 // Reread the arguments descriptor array to obtain the number of passed |
| 761 // arguments. | 765 // arguments. |
| 762 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); | 766 __ movl(EDX, Address(EBP, kArgumentsDescOffset)); |
| 763 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); | 767 __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 764 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 768 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 765 // Get rid of arguments pushed on the stack. | 769 // Get rid of arguments pushed on the stack. |
| 766 __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi. | 770 __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi. |
| 767 | 771 |
| 768 // Restore the saved top exit frame info and top resource back into the | 772 // Restore the saved top exit frame info and top resource back into the |
| 769 // Isolate structure. | 773 // Isolate structure. |
| 770 __ LoadIsolate(ESI); | 774 __ LoadIsolate(EDI); |
| 771 __ popl(Address(ESI, Isolate::top_exit_frame_info_offset())); | 775 __ popl(Address(EDI, Isolate::top_exit_frame_info_offset())); |
| 772 __ popl(Address(ESI, Isolate::top_resource_offset())); | 776 __ popl(Address(EDI, Isolate::top_resource_offset())); |
| 773 | 777 |
| 774 // Restore the current VMTag from the stack. | 778 // Restore the current VMTag from the stack. |
| 775 __ popl(Address(ESI, Isolate::vm_tag_offset())); | 779 __ popl(Address(EDI, Isolate::vm_tag_offset())); |
| 776 | 780 |
| 777 // Restore C++ ABI callee-saved registers. | 781 // Restore C++ ABI callee-saved registers. |
| 778 __ popl(EDI); | 782 __ popl(EDI); |
| 779 __ popl(ESI); | 783 __ popl(ESI); |
| 780 __ popl(EBX); | 784 __ popl(EBX); |
| 781 | 785 |
| 782 // Restore the frame pointer. | 786 // Restore the frame pointer. |
| 783 __ LeaveFrame(); | 787 __ LeaveFrame(); |
| 784 | 788 |
| 785 __ ret(); | 789 __ ret(); |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 __ cmpb(Address::Absolute(single_step_address), Immediate(0)); | 1317 __ cmpb(Address::Absolute(single_step_address), Immediate(0)); |
| 1314 __ j(NOT_EQUAL, &stepping); | 1318 __ j(NOT_EQUAL, &stepping); |
| 1315 __ Bind(&done_stepping); | 1319 __ Bind(&done_stepping); |
| 1316 } | 1320 } |
| 1317 __ Comment("Range feedback collection"); | 1321 __ Comment("Range feedback collection"); |
| 1318 Label not_smi_or_overflow; | 1322 Label not_smi_or_overflow; |
| 1319 if (range_collection_mode == kCollectRanges) { | 1323 if (range_collection_mode == kCollectRanges) { |
| 1320 ASSERT((num_args == 1) || (num_args == 2)); | 1324 ASSERT((num_args == 1) || (num_args == 2)); |
| 1321 if (num_args == 2) { | 1325 if (num_args == 2) { |
| 1322 __ movl(EAX, Address(ESP, + 2 * kWordSize)); | 1326 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
| 1323 __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, ESI, ¬_smi_or_overflow); | 1327 __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, EDX, ¬_smi_or_overflow); |
| 1324 } | 1328 } |
| 1325 | 1329 |
| 1326 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 1330 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 1327 __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, ESI, | 1331 __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, EDX, |
| 1328 ¬_smi_or_overflow); | 1332 ¬_smi_or_overflow); |
| 1329 } | 1333 } |
| 1330 if (kind != Token::kILLEGAL) { | 1334 if (kind != Token::kILLEGAL) { |
| 1331 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); | 1335 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); |
| 1332 } | 1336 } |
| 1333 __ Bind(¬_smi_or_overflow); | 1337 __ Bind(¬_smi_or_overflow); |
| 1334 | 1338 |
| 1335 __ Comment("Extract ICData initial values and receiver cid"); | 1339 __ Comment("Extract ICData initial values and receiver cid"); |
| 1336 // ECX: IC data object (preserved). | 1340 // ECX: IC data object (preserved). |
| 1337 // Load arguments descriptor into EDX. | 1341 // Load arguments descriptor into EDX. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 __ StoreIntoSmiField(Address(EBX, count_offset), EDI); | 1440 __ StoreIntoSmiField(Address(EBX, count_offset), EDI); |
| 1437 } | 1441 } |
| 1438 | 1442 |
| 1439 __ movl(EAX, Address(EBX, target_offset)); | 1443 __ movl(EAX, Address(EBX, target_offset)); |
| 1440 __ Bind(&call_target_function); | 1444 __ Bind(&call_target_function); |
| 1441 __ Comment("Call target"); | 1445 __ Comment("Call target"); |
| 1442 // EAX: Target function. | 1446 // EAX: Target function. |
| 1443 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); | 1447 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); |
| 1444 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1448 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1445 if (range_collection_mode == kCollectRanges) { | 1449 if (range_collection_mode == kCollectRanges) { |
| 1446 __ movl(EDI, Address(ESP, + 1 * kWordSize)); | |
| 1447 if (num_args == 2) { | |
| 1448 __ movl(ESI, Address(ESP, + 2 * kWordSize)); | |
| 1449 } | |
| 1450 __ EnterStubFrame(); | 1450 __ EnterStubFrame(); |
| 1451 __ pushl(ECX); | 1451 __ pushl(ECX); |
| 1452 if (num_args == 2) { | 1452 const intptr_t arg_offset_words = num_args + |
| 1453 __ pushl(ESI); | 1453 Assembler::kEnterStubFramePushedWords + |
| 1454 1; // ECX |
| 1455 for (intptr_t i = 0; i < num_args; i++) { |
| 1456 __ movl(EDI, Address(ESP, arg_offset_words * kWordSize)); |
| 1457 __ pushl(EDI); |
| 1454 } | 1458 } |
| 1455 __ pushl(EDI); | |
| 1456 __ call(EBX); | 1459 __ call(EBX); |
| 1457 | 1460 |
| 1458 __ movl(ECX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); | 1461 __ movl(ECX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); |
| 1459 Label done; | 1462 Label done; |
| 1460 __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, ESI, &done); | 1463 __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, EDX, &done); |
| 1461 __ Bind(&done); | 1464 __ Bind(&done); |
| 1462 __ LeaveFrame(); | 1465 __ LeaveFrame(); |
| 1463 __ ret(); | 1466 __ ret(); |
| 1464 } else { | 1467 } else { |
| 1465 __ jmp(EBX); | 1468 __ jmp(EBX); |
| 1466 } | 1469 } |
| 1467 | 1470 |
| 1468 if (FLAG_support_debugger) { | 1471 if (FLAG_support_debugger) { |
| 1469 __ Bind(&stepping); | 1472 __ Bind(&stepping); |
| 1470 __ EnterStubFrame(); | 1473 __ EnterStubFrame(); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1913 // No Result. | 1916 // No Result. |
| 1914 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1917 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
| 1915 ASSERT(kExceptionObjectReg == EAX); | 1918 ASSERT(kExceptionObjectReg == EAX); |
| 1916 ASSERT(kStackTraceObjectReg == EDX); | 1919 ASSERT(kStackTraceObjectReg == EDX); |
| 1917 __ movl(EDI, Address(ESP, 6 * kWordSize)); // Load target isolate. | 1920 __ movl(EDI, Address(ESP, 6 * kWordSize)); // Load target isolate. |
| 1918 __ movl(kStackTraceObjectReg, Address(ESP, 5 * kWordSize)); | 1921 __ movl(kStackTraceObjectReg, Address(ESP, 5 * kWordSize)); |
| 1919 __ movl(kExceptionObjectReg, Address(ESP, 4 * kWordSize)); | 1922 __ movl(kExceptionObjectReg, Address(ESP, 4 * kWordSize)); |
| 1920 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. | 1923 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. |
| 1921 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. | 1924 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. |
| 1922 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. | 1925 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. |
| 1926 // TODO(koda): Pass thread instead of isolate. |
| 1927 __ movl(THR, Address(EDI, Isolate::mutator_thread_offset())); |
| 1923 // Set tag. | 1928 // Set tag. |
| 1924 __ movl(Address(EDI, Isolate::vm_tag_offset()), | 1929 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| 1925 Immediate(VMTag::kDartTagId)); | 1930 Immediate(VMTag::kDartTagId)); |
| 1926 // Clear top exit frame. | 1931 // Clear top exit frame. |
| 1927 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 1932 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 1928 __ jmp(EBX); // Jump to the exception handler code. | 1933 __ jmp(EBX); // Jump to the exception handler code. |
| 1929 } | 1934 } |
| 1930 | 1935 |
| 1931 | 1936 |
| 1932 // Calls to the runtime to optimize the given function. | 1937 // Calls to the runtime to optimize the given function. |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2122 // EBX: entry point. | 2127 // EBX: entry point. |
| 2123 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2128 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2124 EmitMegamorphicLookup(assembler, EDI, EBX, EBX); | 2129 EmitMegamorphicLookup(assembler, EDI, EBX, EBX); |
| 2125 __ ret(); | 2130 __ ret(); |
| 2126 } | 2131 } |
| 2127 | 2132 |
| 2128 | 2133 |
| 2129 } // namespace dart | 2134 } // namespace dart |
| 2130 | 2135 |
| 2131 #endif // defined TARGET_ARCH_IA32 | 2136 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |