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 |