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/assembler_macros.h" | |
10 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
11 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
12 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
13 #include "vm/instructions.h" | 12 #include "vm/instructions.h" |
14 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
15 #include "vm/pages.h" | 14 #include "vm/pages.h" |
16 #include "vm/resolver.h" | 15 #include "vm/resolver.h" |
17 #include "vm/scavenger.h" | 16 #include "vm/scavenger.h" |
18 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
19 | 18 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 __ LeaveFrame(); | 180 __ LeaveFrame(); |
182 __ ret(); | 181 __ ret(); |
183 } | 182 } |
184 | 183 |
185 | 184 |
186 // Input parameters: | 185 // Input parameters: |
187 // EDX: arguments descriptor array. | 186 // EDX: arguments descriptor array. |
188 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 187 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
189 const Immediate& raw_null = | 188 const Immediate& raw_null = |
190 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 189 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
191 AssemblerMacros::EnterStubFrame(assembler); | 190 __ EnterStubFrame(); |
192 __ pushl(EDX); // Preserve arguments descriptor array. | 191 __ pushl(EDX); // Preserve arguments descriptor array. |
193 __ pushl(raw_null); // Setup space on stack for return value. | 192 __ pushl(raw_null); // Setup space on stack for return value. |
194 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 193 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
195 __ popl(EAX); // Get Code object result. | 194 __ popl(EAX); // Get Code object result. |
196 __ popl(EDX); // Restore arguments descriptor array. | 195 __ popl(EDX); // Restore arguments descriptor array. |
197 // Remove the stub frame as we are about to jump to the dart function. | 196 // Remove the stub frame as we are about to jump to the dart function. |
198 __ LeaveFrame(); | 197 __ LeaveFrame(); |
199 | 198 |
200 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 199 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
201 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 200 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
202 __ jmp(ECX); | 201 __ jmp(ECX); |
203 } | 202 } |
204 | 203 |
205 | 204 |
206 // Called from a static call only when an invalid code has been entered | 205 // Called from a static call only when an invalid code has been entered |
207 // (invalid because its function was optimized or deoptimized). | 206 // (invalid because its function was optimized or deoptimized). |
208 // EDX: arguments descriptor array. | 207 // EDX: arguments descriptor array. |
209 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 208 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
210 const Immediate& raw_null = | 209 const Immediate& raw_null = |
211 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 210 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
212 // Create a stub frame as we are pushing some objects on the stack before | 211 // Create a stub frame as we are pushing some objects on the stack before |
213 // calling into the runtime. | 212 // calling into the runtime. |
214 AssemblerMacros::EnterStubFrame(assembler); | 213 __ EnterStubFrame(); |
215 __ pushl(EDX); // Preserve arguments descriptor array. | 214 __ pushl(EDX); // Preserve arguments descriptor array. |
216 __ pushl(raw_null); // Setup space on stack for return value. | 215 __ pushl(raw_null); // Setup space on stack for return value. |
217 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 216 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
218 __ popl(EAX); // Get Code object. | 217 __ popl(EAX); // Get Code object. |
219 __ popl(EDX); // Restore arguments descriptor array. | 218 __ popl(EDX); // Restore arguments descriptor array. |
220 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 219 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
221 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 220 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
222 __ LeaveFrame(); | 221 __ LeaveFrame(); |
223 __ jmp(EAX); | 222 __ jmp(EAX); |
224 __ int3(); | 223 __ int3(); |
(...skipping 30 matching lines...) Expand all Loading... |
255 | 254 |
256 | 255 |
257 // Input parameters: | 256 // Input parameters: |
258 // ECX: ic-data. | 257 // ECX: ic-data. |
259 // EDX: arguments descriptor array. | 258 // EDX: arguments descriptor array. |
260 // Note: The receiver object is the first argument to the function being | 259 // Note: The receiver object is the first argument to the function being |
261 // called, the stub accesses the receiver from this location directly | 260 // called, the stub accesses the receiver from this location directly |
262 // when trying to resolve the call. | 261 // when trying to resolve the call. |
263 // Uses EDI. | 262 // Uses EDI. |
264 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 263 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
265 AssemblerMacros::EnterStubFrame(assembler); | 264 __ EnterStubFrame(); |
266 | 265 |
267 const Immediate& raw_null = | 266 const Immediate& raw_null = |
268 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 267 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
269 __ pushl(raw_null); // Space for the return value. | 268 __ pushl(raw_null); // Space for the return value. |
270 | 269 |
271 // Push the receiver as an argument. Load the smi-tagged argument | 270 // Push the receiver as an argument. Load the smi-tagged argument |
272 // count into EDI to index the receiver in the stack. There are | 271 // count into EDI to index the receiver in the stack. There are |
273 // three words (null, stub's pc marker, saved fp) above the return | 272 // three words (null, stub's pc marker, saved fp) above the return |
274 // address. | 273 // address. |
275 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 274 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 // Restore result into EBX. | 384 // Restore result into EBX. |
386 __ movl(EBX, Address(EBP, -1 * kWordSize)); | 385 __ movl(EBX, Address(EBP, -1 * kWordSize)); |
387 } | 386 } |
388 // Code above cannot cause GC. | 387 // Code above cannot cause GC. |
389 __ LeaveFrame(); | 388 __ LeaveFrame(); |
390 __ movl(EBP, EAX); | 389 __ movl(EBP, EAX); |
391 | 390 |
392 // Frame is fully rewritten at this point and it is safe to perform a GC. | 391 // Frame is fully rewritten at this point and it is safe to perform a GC. |
393 // Materialize any objects that were deferred by FillFrame because they | 392 // Materialize any objects that were deferred by FillFrame because they |
394 // require allocation. | 393 // require allocation. |
395 AssemblerMacros::EnterStubFrame(assembler); | 394 __ EnterStubFrame(); |
396 if (preserve_eax) { | 395 if (preserve_eax) { |
397 __ pushl(EBX); // Preserve result, it will be GC-d here. | 396 __ pushl(EBX); // Preserve result, it will be GC-d here. |
398 } | 397 } |
399 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); | 398 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); |
400 if (preserve_eax) { | 399 if (preserve_eax) { |
401 __ popl(EAX); // Restore result. | 400 __ popl(EAX); // Restore result. |
402 } | 401 } |
403 __ LeaveFrame(); | 402 __ LeaveFrame(); |
404 __ ret(); | 403 __ ret(); |
405 } | 404 } |
(...skipping 10 matching lines...) Expand all Loading... |
416 GenerateDeoptimizationSequence(assembler, true); // Preserve EAX. | 415 GenerateDeoptimizationSequence(assembler, true); // Preserve EAX. |
417 } | 416 } |
418 | 417 |
419 | 418 |
420 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 419 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
421 GenerateDeoptimizationSequence(assembler, false); // Don't preserve EAX. | 420 GenerateDeoptimizationSequence(assembler, false); // Don't preserve EAX. |
422 } | 421 } |
423 | 422 |
424 | 423 |
425 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 424 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
426 AssemblerMacros::EnterStubFrame(assembler); | 425 __ EnterStubFrame(); |
427 // Load the receiver into EAX. The argument count in the arguments | 426 // Load the receiver into EAX. The argument count in the arguments |
428 // descriptor in EDX is a smi. | 427 // descriptor in EDX is a smi. |
429 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 428 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
430 // Two words (saved fp, stub's pc marker) in the stack above the return | 429 // Two words (saved fp, stub's pc marker) in the stack above the return |
431 // address. | 430 // address. |
432 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize)); | 431 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize)); |
433 // Preserve IC data and arguments descriptor. | 432 // Preserve IC data and arguments descriptor. |
434 __ pushl(ECX); | 433 __ pushl(ECX); |
435 __ pushl(EDX); | 434 __ pushl(EDX); |
436 | 435 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 // EAX: new object. | 579 // EAX: new object. |
581 // EDX: Array length as Smi (preserved for the caller.) | 580 // EDX: Array length as Smi (preserved for the caller.) |
582 __ ret(); | 581 __ ret(); |
583 } | 582 } |
584 | 583 |
585 // Unable to allocate the array using the fast inline code, just call | 584 // Unable to allocate the array using the fast inline code, just call |
586 // into the runtime. | 585 // into the runtime. |
587 __ Bind(&slow_case); | 586 __ Bind(&slow_case); |
588 // Create a stub frame as we are pushing some objects on the stack before | 587 // Create a stub frame as we are pushing some objects on the stack before |
589 // calling into the runtime. | 588 // calling into the runtime. |
590 AssemblerMacros::EnterStubFrame(assembler); | 589 __ EnterStubFrame(); |
591 __ pushl(raw_null); // Setup space on stack for return value. | 590 __ pushl(raw_null); // Setup space on stack for return value. |
592 __ pushl(EDX); // Array length as Smi. | 591 __ pushl(EDX); // Array length as Smi. |
593 __ pushl(ECX); // Element type. | 592 __ pushl(ECX); // Element type. |
594 __ CallRuntime(kAllocateArrayRuntimeEntry); | 593 __ CallRuntime(kAllocateArrayRuntimeEntry); |
595 __ popl(EAX); // Pop element type argument. | 594 __ popl(EAX); // Pop element type argument. |
596 __ popl(EDX); // Pop array length argument. | 595 __ popl(EDX); // Pop array length argument. |
597 __ popl(EAX); // Pop return value from return slot. | 596 __ popl(EAX); // Pop return value from return slot. |
598 __ LeaveFrame(); | 597 __ LeaveFrame(); |
599 __ ret(); | 598 __ ret(); |
600 } | 599 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); | 636 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); |
638 | 637 |
639 // Load closure function code in EAX. | 638 // Load closure function code in EAX. |
640 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); | 639 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); |
641 __ cmpl(EAX, raw_null); | 640 __ cmpl(EAX, raw_null); |
642 Label function_compiled; | 641 Label function_compiled; |
643 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 642 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
644 | 643 |
645 // Create a stub frame as we are pushing some objects on the stack before | 644 // Create a stub frame as we are pushing some objects on the stack before |
646 // calling into the runtime. | 645 // calling into the runtime. |
647 AssemblerMacros::EnterStubFrame(assembler); | 646 __ EnterStubFrame(); |
648 | 647 |
649 __ pushl(EDX); // Preserve arguments descriptor array. | 648 __ pushl(EDX); // Preserve arguments descriptor array. |
650 __ pushl(ECX); // Preserve read-only function object argument. | 649 __ pushl(ECX); // Preserve read-only function object argument. |
651 __ CallRuntime(kCompileFunctionRuntimeEntry); | 650 __ CallRuntime(kCompileFunctionRuntimeEntry); |
652 __ popl(ECX); // Restore read-only function object argument in ECX. | 651 __ popl(ECX); // Restore read-only function object argument in ECX. |
653 __ popl(EDX); // Restore arguments descriptor array. | 652 __ popl(EDX); // Restore arguments descriptor array. |
654 // Restore EAX. | 653 // Restore EAX. |
655 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); | 654 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); |
656 | 655 |
657 // Remove the stub frame as we are about to jump to the closure function. | 656 // Remove the stub frame as we are about to jump to the closure function. |
(...skipping 11 matching lines...) Expand all Loading... |
669 __ Bind(¬_closure); | 668 __ Bind(¬_closure); |
670 // Call runtime to attempt to resolve and invoke a call method on a | 669 // Call runtime to attempt to resolve and invoke a call method on a |
671 // non-closure object, passing the non-closure object and its arguments array, | 670 // non-closure object, passing the non-closure object and its arguments array, |
672 // returning here. | 671 // returning here. |
673 // If no call method exists, throw a NoSuchMethodError. | 672 // If no call method exists, throw a NoSuchMethodError. |
674 // EDI: non-closure object. | 673 // EDI: non-closure object. |
675 // EDX: arguments descriptor array. | 674 // EDX: arguments descriptor array. |
676 | 675 |
677 // Create a stub frame as we are pushing some objects on the stack before | 676 // Create a stub frame as we are pushing some objects on the stack before |
678 // calling into the runtime. | 677 // calling into the runtime. |
679 AssemblerMacros::EnterStubFrame(assembler); | 678 __ EnterStubFrame(); |
680 | 679 |
681 __ pushl(raw_null); // Setup space on stack for result from error reporting. | 680 __ pushl(raw_null); // Setup space on stack for result from error reporting. |
682 __ pushl(EDX); // Arguments descriptor. | 681 __ pushl(EDX); // Arguments descriptor. |
683 // Load smi-tagged arguments array length, including the non-closure. | 682 // Load smi-tagged arguments array length, including the non-closure. |
684 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 683 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
685 // See stack layout below explaining "wordSize * 5" offset. | 684 // See stack layout below explaining "wordSize * 5" offset. |
686 PushArgumentsArray(assembler, (kWordSize * 5)); | 685 PushArgumentsArray(assembler, (kWordSize * 5)); |
687 | 686 |
688 // Stack: | 687 // Stack: |
689 // TOS + 0: Argument array. | 688 // TOS + 0: Argument array. |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 } | 930 } |
932 | 931 |
933 // Done allocating and initializing the context. | 932 // Done allocating and initializing the context. |
934 // EAX: new object. | 933 // EAX: new object. |
935 __ ret(); | 934 __ ret(); |
936 | 935 |
937 __ Bind(&slow_case); | 936 __ Bind(&slow_case); |
938 } | 937 } |
939 // Create a stub frame as we are pushing some objects on the stack before | 938 // Create a stub frame as we are pushing some objects on the stack before |
940 // calling into the runtime. | 939 // calling into the runtime. |
941 AssemblerMacros::EnterStubFrame(assembler); | 940 __ EnterStubFrame(); |
942 __ pushl(raw_null); // Setup space on stack for return value. | 941 __ pushl(raw_null); // Setup space on stack for return value. |
943 __ SmiTag(EDX); | 942 __ SmiTag(EDX); |
944 __ pushl(EDX); | 943 __ pushl(EDX); |
945 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 944 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. |
946 __ popl(EAX); // Pop number of context variables argument. | 945 __ popl(EAX); // Pop number of context variables argument. |
947 __ popl(EAX); // Pop the new context object. | 946 __ popl(EAX); // Pop the new context object. |
948 // EAX: new object | 947 // EAX: new object |
949 // Restore the frame pointer. | 948 // Restore the frame pointer. |
950 __ LeaveFrame(); | 949 __ LeaveFrame(); |
951 __ ret(); | 950 __ ret(); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 __ ret(); | 1154 __ ret(); |
1156 | 1155 |
1157 __ Bind(&slow_case); | 1156 __ Bind(&slow_case); |
1158 } | 1157 } |
1159 if (is_cls_parameterized) { | 1158 if (is_cls_parameterized) { |
1160 __ movl(EAX, Address(ESP, kObjectTypeArgumentsOffset)); | 1159 __ movl(EAX, Address(ESP, kObjectTypeArgumentsOffset)); |
1161 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); | 1160 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); |
1162 } | 1161 } |
1163 // Create a stub frame as we are pushing some objects on the stack before | 1162 // Create a stub frame as we are pushing some objects on the stack before |
1164 // calling into the runtime. | 1163 // calling into the runtime. |
1165 AssemblerMacros::EnterStubFrame(assembler); | 1164 __ EnterStubFrame(); |
1166 __ pushl(raw_null); // Setup space on stack for return value. | 1165 __ pushl(raw_null); // Setup space on stack for return value. |
1167 __ PushObject(cls); // Push class of object to be allocated. | 1166 __ PushObject(cls); // Push class of object to be allocated. |
1168 if (is_cls_parameterized) { | 1167 if (is_cls_parameterized) { |
1169 __ pushl(EAX); // Push type arguments of object to be allocated. | 1168 __ pushl(EAX); // Push type arguments of object to be allocated. |
1170 __ pushl(EDX); // Push type arguments of instantiator. | 1169 __ pushl(EDX); // Push type arguments of instantiator. |
1171 } else { | 1170 } else { |
1172 __ pushl(raw_null); // Push null type arguments. | 1171 __ pushl(raw_null); // Push null type arguments. |
1173 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1172 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
1174 } | 1173 } |
1175 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1174 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1295 __ Bind(&slow_case); | 1294 __ Bind(&slow_case); |
1296 } | 1295 } |
1297 if (has_type_arguments) { | 1296 if (has_type_arguments) { |
1298 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); | 1297 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); |
1299 } | 1298 } |
1300 if (is_implicit_instance_closure) { | 1299 if (is_implicit_instance_closure) { |
1301 __ movl(EAX, Address(ESP, kReceiverOffset)); | 1300 __ movl(EAX, Address(ESP, kReceiverOffset)); |
1302 } | 1301 } |
1303 // Create a stub frame as we are pushing some objects on the stack before | 1302 // Create a stub frame as we are pushing some objects on the stack before |
1304 // calling into the runtime. | 1303 // calling into the runtime. |
1305 AssemblerMacros::EnterStubFrame(assembler); | 1304 __ EnterStubFrame(); |
1306 __ pushl(raw_null); // Setup space on stack for return value. | 1305 __ pushl(raw_null); // Setup space on stack for return value. |
1307 __ PushObject(func); | 1306 __ PushObject(func); |
1308 if (is_implicit_static_closure) { | 1307 if (is_implicit_static_closure) { |
1309 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); | 1308 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); |
1310 } else { | 1309 } else { |
1311 if (is_implicit_instance_closure) { | 1310 if (is_implicit_instance_closure) { |
1312 __ pushl(EAX); // Receiver. | 1311 __ pushl(EAX); // Receiver. |
1313 } | 1312 } |
1314 if (has_type_arguments) { | 1313 if (has_type_arguments) { |
1315 __ pushl(ECX); // Push type arguments of closure to be allocated. | 1314 __ pushl(ECX); // Push type arguments of closure to be allocated. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1348 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
1350 // The target function was not found, so invoke method | 1349 // The target function was not found, so invoke method |
1351 // "dynamic noSuchMethod(InvocationMirror invocation)". | 1350 // "dynamic noSuchMethod(InvocationMirror invocation)". |
1352 const Immediate& raw_null = | 1351 const Immediate& raw_null = |
1353 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1352 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1354 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1353 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1355 __ movl(EAX, Address(EBP, EDI, TIMES_2, kWordSize)); // Get receiver. | 1354 __ movl(EAX, Address(EBP, EDI, TIMES_2, kWordSize)); // Get receiver. |
1356 | 1355 |
1357 // Create a stub frame as we are pushing some objects on the stack before | 1356 // Create a stub frame as we are pushing some objects on the stack before |
1358 // calling into the runtime. | 1357 // calling into the runtime. |
1359 AssemblerMacros::EnterStubFrame(assembler); | 1358 __ EnterStubFrame(); |
1360 | 1359 |
1361 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | 1360 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
1362 __ pushl(EAX); // Receiver. | 1361 __ pushl(EAX); // Receiver. |
1363 __ pushl(ECX); // IC data array. | 1362 __ pushl(ECX); // IC data array. |
1364 __ pushl(EDX); // Arguments descriptor array. | 1363 __ pushl(EDX); // Arguments descriptor array. |
1365 | 1364 |
1366 __ movl(EDX, EDI); | 1365 __ movl(EDX, EDI); |
1367 // See stack layout below explaining "wordSize * 10" offset. | 1366 // See stack layout below explaining "wordSize * 10" offset. |
1368 PushArgumentsArray(assembler, (kWordSize * 10)); | 1367 PushArgumentsArray(assembler, (kWordSize * 10)); |
1369 | 1368 |
(...skipping 23 matching lines...) Expand all Loading... |
1393 __ LeaveFrame(); | 1392 __ LeaveFrame(); |
1394 __ ret(); | 1393 __ ret(); |
1395 } | 1394 } |
1396 | 1395 |
1397 | 1396 |
1398 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1397 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
1399 Register argdesc_reg = EDX; | 1398 Register argdesc_reg = EDX; |
1400 Register ic_reg = ECX; | 1399 Register ic_reg = ECX; |
1401 Register func_reg = EDI; | 1400 Register func_reg = EDI; |
1402 if (FLAG_trace_optimized_ic_calls) { | 1401 if (FLAG_trace_optimized_ic_calls) { |
1403 AssemblerMacros::EnterStubFrame(assembler); | 1402 __ EnterStubFrame(); |
1404 __ pushl(func_reg); // Preserve | 1403 __ pushl(func_reg); // Preserve |
1405 __ pushl(argdesc_reg); // Preserve. | 1404 __ pushl(argdesc_reg); // Preserve. |
1406 __ pushl(ic_reg); // Preserve. | 1405 __ pushl(ic_reg); // Preserve. |
1407 __ pushl(ic_reg); // Argument. | 1406 __ pushl(ic_reg); // Argument. |
1408 __ pushl(func_reg); // Argument. | 1407 __ pushl(func_reg); // Argument. |
1409 __ CallRuntime(kTraceICCallRuntimeEntry); | 1408 __ CallRuntime(kTraceICCallRuntimeEntry); |
1410 __ popl(EAX); // Discard argument; | 1409 __ popl(EAX); // Discard argument; |
1411 __ popl(EAX); // Discard argument; | 1410 __ popl(EAX); // Discard argument; |
1412 __ popl(ic_reg); // Restore. | 1411 __ popl(ic_reg); // Restore. |
1413 __ popl(argdesc_reg); // Restore. | 1412 __ popl(argdesc_reg); // Restore. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 | 1533 |
1535 // IC miss. | 1534 // IC miss. |
1536 const Immediate& raw_null = | 1535 const Immediate& raw_null = |
1537 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1536 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1538 // Compute address of arguments (first read number of arguments from | 1537 // Compute address of arguments (first read number of arguments from |
1539 // arguments descriptor array and then compute address on the stack). | 1538 // arguments descriptor array and then compute address on the stack). |
1540 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1539 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1541 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. | 1540 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. |
1542 // Create a stub frame as we are pushing some objects on the stack before | 1541 // Create a stub frame as we are pushing some objects on the stack before |
1543 // calling into the runtime. | 1542 // calling into the runtime. |
1544 AssemblerMacros::EnterStubFrame(assembler); | 1543 __ EnterStubFrame(); |
1545 __ pushl(EDX); // Preserve arguments descriptor array. | 1544 __ pushl(EDX); // Preserve arguments descriptor array. |
1546 __ pushl(ECX); // Preserve IC data object. | 1545 __ pushl(ECX); // Preserve IC data object. |
1547 __ pushl(raw_null); // Setup space on stack for result (target code object). | 1546 __ pushl(raw_null); // Setup space on stack for result (target code object). |
1548 // Push call arguments. | 1547 // Push call arguments. |
1549 for (intptr_t i = 0; i < num_args; i++) { | 1548 for (intptr_t i = 0; i < num_args; i++) { |
1550 __ movl(EBX, Address(EAX, -kWordSize * i)); | 1549 __ movl(EBX, Address(EAX, -kWordSize * i)); |
1551 __ pushl(EBX); | 1550 __ pushl(EBX); |
1552 } | 1551 } |
1553 __ pushl(ECX); // Pass IC data object. | 1552 __ pushl(ECX); // Pass IC data object. |
1554 __ pushl(EDX); // Pass arguments descriptor array. | 1553 __ pushl(EDX); // Pass arguments descriptor array. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1686 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1685 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
1687 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1686 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1688 } | 1687 } |
1689 | 1688 |
1690 | 1689 |
1691 // EDX: Arguments descriptor array. | 1690 // EDX: Arguments descriptor array. |
1692 // TOS(0): return address (Dart code). | 1691 // TOS(0): return address (Dart code). |
1693 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1692 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1694 // Create a stub frame as we are pushing some objects on the stack before | 1693 // Create a stub frame as we are pushing some objects on the stack before |
1695 // calling into the runtime. | 1694 // calling into the runtime. |
1696 AssemblerMacros::EnterStubFrame(assembler); | 1695 __ EnterStubFrame(); |
1697 __ pushl(EDX); // Preserve arguments descriptor. | 1696 __ pushl(EDX); // Preserve arguments descriptor. |
1698 const Immediate& raw_null = | 1697 const Immediate& raw_null = |
1699 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1698 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1700 __ pushl(raw_null); // Room for result. | 1699 __ pushl(raw_null); // Room for result. |
1701 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1700 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
1702 __ popl(EAX); // Code object. | 1701 __ popl(EAX); // Code object. |
1703 __ popl(EDX); // Restore arguments descriptor. | 1702 __ popl(EDX); // Restore arguments descriptor. |
1704 __ LeaveFrame(); | 1703 __ LeaveFrame(); |
1705 | 1704 |
1706 // Now call the static function. The breakpoint handler function | 1705 // Now call the static function. The breakpoint handler function |
1707 // ensures that the call target is compiled. | 1706 // ensures that the call target is compiled. |
1708 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 1707 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
1709 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1708 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
1710 __ jmp(ECX); | 1709 __ jmp(ECX); |
1711 } | 1710 } |
1712 | 1711 |
1713 | 1712 |
1714 // TOS(0): return address (Dart code). | 1713 // TOS(0): return address (Dart code). |
1715 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1714 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1716 // Create a stub frame as we are pushing some objects on the stack before | 1715 // Create a stub frame as we are pushing some objects on the stack before |
1717 // calling into the runtime. | 1716 // calling into the runtime. |
1718 AssemblerMacros::EnterStubFrame(assembler); | 1717 __ EnterStubFrame(); |
1719 __ pushl(EAX); | 1718 __ pushl(EAX); |
1720 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1719 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); |
1721 __ popl(EAX); | 1720 __ popl(EAX); |
1722 __ LeaveFrame(); | 1721 __ LeaveFrame(); |
1723 | 1722 |
1724 // Instead of returning to the patched Dart function, emulate the | 1723 // Instead of returning to the patched Dart function, emulate the |
1725 // smashed return code pattern and return to the function's caller. | 1724 // smashed return code pattern and return to the function's caller. |
1726 __ popl(ECX); // Discard return address to patched dart code. | 1725 __ popl(ECX); // Discard return address to patched dart code. |
1727 // Execute function epilog code that was smashed in the Dart code. | 1726 // Execute function epilog code that was smashed in the Dart code. |
1728 __ LeaveFrame(); | 1727 __ LeaveFrame(); |
1729 __ ret(); | 1728 __ ret(); |
1730 } | 1729 } |
1731 | 1730 |
1732 | 1731 |
1733 // ECX: Inline cache data array. | 1732 // ECX: Inline cache data array. |
1734 // EDX: Arguments descriptor array. | 1733 // EDX: Arguments descriptor array. |
1735 // TOS(0): return address (Dart code). | 1734 // TOS(0): return address (Dart code). |
1736 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1735 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
1737 // Create a stub frame as we are pushing some objects on the stack before | 1736 // Create a stub frame as we are pushing some objects on the stack before |
1738 // calling into the runtime. | 1737 // calling into the runtime. |
1739 AssemblerMacros::EnterStubFrame(assembler); | 1738 __ EnterStubFrame(); |
1740 __ pushl(ECX); | 1739 __ pushl(ECX); |
1741 __ pushl(EDX); | 1740 __ pushl(EDX); |
1742 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1741 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); |
1743 __ popl(EDX); | 1742 __ popl(EDX); |
1744 __ popl(ECX); | 1743 __ popl(ECX); |
1745 __ LeaveFrame(); | 1744 __ LeaveFrame(); |
1746 | 1745 |
1747 // Find out which dispatch stub to call. | 1746 // Find out which dispatch stub to call. |
1748 Label test_two, test_three, test_four; | 1747 Label test_two, test_three, test_four; |
1749 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); | 1748 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1998 __ Bind(¬_smi); | 1997 __ Bind(¬_smi); |
1999 __ LoadClassId(EAX, EAX); | 1998 __ LoadClassId(EAX, EAX); |
2000 __ SmiTag(EAX); | 1999 __ SmiTag(EAX); |
2001 __ ret(); | 2000 __ ret(); |
2002 | 2001 |
2003 __ Bind(&update_ic_data); | 2002 __ Bind(&update_ic_data); |
2004 | 2003 |
2005 // ECX: ICData | 2004 // ECX: ICData |
2006 __ movl(EAX, Address(ESP, 1 * kWordSize)); | 2005 __ movl(EAX, Address(ESP, 1 * kWordSize)); |
2007 __ movl(EDI, Address(ESP, 2 * kWordSize)); | 2006 __ movl(EDI, Address(ESP, 2 * kWordSize)); |
2008 AssemblerMacros::EnterStubFrame(assembler); | 2007 __ EnterStubFrame(); |
2009 __ pushl(EDI); // arg 0 | 2008 __ pushl(EDI); // arg 0 |
2010 __ pushl(EAX); // arg 1 | 2009 __ pushl(EAX); // arg 1 |
2011 __ PushObject(Symbols::EqualOperator()); // Target's name. | 2010 __ PushObject(Symbols::EqualOperator()); // Target's name. |
2012 __ pushl(ECX); // ICData | 2011 __ pushl(ECX); // ICData |
2013 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); | 2012 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); |
2014 __ Drop(4); | 2013 __ Drop(4); |
2015 __ LeaveFrame(); | 2014 __ LeaveFrame(); |
2016 | 2015 |
2017 __ jmp(&compute_result, Assembler::kNearJump); | 2016 __ jmp(&compute_result, Assembler::kNearJump); |
2018 } | 2017 } |
2019 | 2018 |
2020 | 2019 |
2021 // Calls to runtime to ooptimized give function | 2020 // Calls to runtime to ooptimized give function |
2022 // EDI: function to be reoptimized. | 2021 // EDI: function to be reoptimized. |
2023 // EDX: argument descriptor (preserved). | 2022 // EDX: argument descriptor (preserved). |
2024 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2023 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
2025 const Immediate& raw_null = | 2024 const Immediate& raw_null = |
2026 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 2025 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
2027 AssemblerMacros::EnterStubFrame(assembler); | 2026 __ EnterStubFrame(); |
2028 __ pushl(EDX); | 2027 __ pushl(EDX); |
2029 __ pushl(raw_null); // Setup space on stack for return value. | 2028 __ pushl(raw_null); // Setup space on stack for return value. |
2030 __ pushl(EDI); | 2029 __ pushl(EDI); |
2031 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2030 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
2032 __ popl(EAX); // Discard argument. | 2031 __ popl(EAX); // Discard argument. |
2033 __ popl(EAX); // Get Code object | 2032 __ popl(EAX); // Get Code object |
2034 __ popl(EDX); // Restore argument descriptor. | 2033 __ popl(EDX); // Restore argument descriptor. |
2035 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 2034 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
2036 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 2035 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
2037 __ LeaveFrame(); | 2036 __ LeaveFrame(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 __ Bind(&done); | 2120 __ Bind(&done); |
2122 __ popl(temp); | 2121 __ popl(temp); |
2123 __ popl(right); | 2122 __ popl(right); |
2124 __ popl(left); | 2123 __ popl(left); |
2125 __ ret(); | 2124 __ ret(); |
2126 } | 2125 } |
2127 | 2126 |
2128 } // namespace dart | 2127 } // namespace dart |
2129 | 2128 |
2130 #endif // defined TARGET_ARCH_IA32 | 2129 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |