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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0)); | 241 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0)); |
242 | 242 |
243 __ LeaveFrame(); | 243 __ LeaveFrame(); |
244 __ ret(); | 244 __ ret(); |
245 } | 245 } |
246 | 246 |
247 | 247 |
248 // Input parameters: | 248 // Input parameters: |
249 // EDX: arguments descriptor array. | 249 // EDX: arguments descriptor array. |
250 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 250 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
251 const Immediate& raw_null = | |
252 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
253 __ EnterStubFrame(); | 251 __ EnterStubFrame(); |
254 __ pushl(EDX); // Preserve arguments descriptor array. | 252 __ pushl(EDX); // Preserve arguments descriptor array. |
255 __ pushl(raw_null); // Setup space on stack for return value. | 253 __ pushl(Immediate(0)); // Setup space on stack for return value. |
256 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 254 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
257 __ popl(EAX); // Get Code object result. | 255 __ popl(EAX); // Get Code object result. |
258 __ popl(EDX); // Restore arguments descriptor array. | 256 __ popl(EDX); // Restore arguments descriptor array. |
259 // Remove the stub frame as we are about to jump to the dart function. | 257 // Remove the stub frame as we are about to jump to the dart function. |
260 __ LeaveFrame(); | 258 __ LeaveFrame(); |
261 | 259 |
262 __ movl(ECX, FieldAddress(EAX, Code::entry_point_offset())); | 260 __ movl(ECX, FieldAddress(EAX, Code::entry_point_offset())); |
263 __ jmp(ECX); | 261 __ jmp(ECX); |
264 } | 262 } |
265 | 263 |
266 | 264 |
267 // Called from a static call only when an invalid code has been entered | 265 // Called from a static call only when an invalid code has been entered |
268 // (invalid because its function was optimized or deoptimized). | 266 // (invalid because its function was optimized or deoptimized). |
269 // EDX: arguments descriptor array. | 267 // EDX: arguments descriptor array. |
270 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 268 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
271 const Immediate& raw_null = | |
272 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
273 // Create a stub frame as we are pushing some objects on the stack before | 269 // Create a stub frame as we are pushing some objects on the stack before |
274 // calling into the runtime. | 270 // calling into the runtime. |
275 __ EnterStubFrame(); | 271 __ EnterStubFrame(); |
276 __ pushl(EDX); // Preserve arguments descriptor array. | 272 __ pushl(EDX); // Preserve arguments descriptor array. |
277 __ pushl(raw_null); // Setup space on stack for return value. | 273 __ pushl(Immediate(0)); // Setup space on stack for return value. |
278 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 274 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
279 __ popl(EAX); // Get Code object. | 275 __ popl(EAX); // Get Code object. |
280 __ popl(EDX); // Restore arguments descriptor array. | 276 __ popl(EDX); // Restore arguments descriptor array. |
281 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); | 277 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); |
282 __ LeaveFrame(); | 278 __ LeaveFrame(); |
283 __ jmp(EAX); | 279 __ jmp(EAX); |
284 __ int3(); | 280 __ int3(); |
285 } | 281 } |
286 | 282 |
287 | 283 |
288 // Called from object allocate instruction when the allocation stub has been | 284 // Called from object allocate instruction when the allocation stub has been |
289 // disabled. | 285 // disabled. |
290 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 286 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
291 const Immediate& raw_null = | |
292 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
293 __ EnterStubFrame(); | 287 __ EnterStubFrame(); |
294 __ pushl(raw_null); // Setup space on stack for return value. | 288 __ pushl(Immediate(0)); // Setup space on stack for return value. |
295 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 289 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
296 __ popl(EAX); // Get Code object. | 290 __ popl(EAX); // Get Code object. |
297 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); | 291 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); |
298 __ LeaveFrame(); | 292 __ LeaveFrame(); |
299 __ jmp(EAX); | 293 __ jmp(EAX); |
300 __ int3(); | 294 __ int3(); |
301 } | 295 } |
302 | 296 |
303 | 297 |
304 // Input parameters: | 298 // Input parameters: |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 // miss-handler may return null. | 463 // miss-handler may return null. |
470 const Immediate& raw_null = | 464 const Immediate& raw_null = |
471 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 465 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
472 __ cmpl(EAX, raw_null); | 466 __ cmpl(EAX, raw_null); |
473 __ j(NOT_EQUAL, call_target_function); | 467 __ j(NOT_EQUAL, call_target_function); |
474 __ EnterStubFrame(); | 468 __ EnterStubFrame(); |
475 // Load the receiver. | 469 // Load the receiver. |
476 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 470 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
477 __ movl(EAX, Address( | 471 __ movl(EAX, Address( |
478 EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); | 472 EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); |
479 __ pushl(raw_null); // Setup space on stack for result. | 473 __ pushl(Immediate(0)); // Setup space on stack for result. |
480 __ pushl(EAX); // Receiver. | 474 __ pushl(EAX); // Receiver. |
481 __ pushl(ECX); // ICData/MegamorphicCache. | 475 __ pushl(ECX); // ICData/MegamorphicCache. |
482 __ pushl(EDX); // Arguments descriptor array. | 476 __ pushl(EDX); // Arguments descriptor array. |
483 __ movl(EDX, EDI); | 477 __ movl(EDX, EDI); |
484 // EDX: Smi-tagged arguments array length. | 478 // EDX: Smi-tagged arguments array length. |
485 PushArgumentsArray(assembler); | 479 PushArgumentsArray(assembler); |
486 const intptr_t kNumArgs = 4; | 480 const intptr_t kNumArgs = 4; |
487 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 481 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); |
488 __ Drop(4); | 482 __ Drop(4); |
489 __ popl(EAX); // Return value. | 483 __ popl(EAX); // Return value. |
490 __ LeaveFrame(); | 484 __ LeaveFrame(); |
491 __ ret(); | 485 __ ret(); |
492 } | 486 } |
493 | 487 |
494 | 488 |
495 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 489 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
496 __ EnterStubFrame(); | 490 __ EnterStubFrame(); |
497 // Load the receiver into EAX. The argument count in the arguments | 491 // Load the receiver into EAX. The argument count in the arguments |
498 // descriptor in EDX is a smi. | 492 // descriptor in EDX is a smi. |
499 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 493 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
500 // Two words (saved fp, stub's pc marker) in the stack above the return | 494 // Two words (saved fp, stub's pc marker) in the stack above the return |
501 // address. | 495 // address. |
502 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize)); | 496 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize)); |
503 // Preserve IC data and arguments descriptor. | 497 // Preserve IC data and arguments descriptor. |
504 __ pushl(ECX); | 498 __ pushl(ECX); |
505 __ pushl(EDX); | 499 __ pushl(EDX); |
506 | 500 |
507 const Immediate& raw_null = | 501 __ pushl(Immediate(0)); // Space for the result of the runtime call. |
508 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); | |
509 __ pushl(raw_null); // Space for the result of the runtime call. | |
510 __ pushl(EAX); // Pass receiver. | 502 __ pushl(EAX); // Pass receiver. |
511 __ pushl(ECX); // Pass IC data. | 503 __ pushl(ECX); // Pass IC data. |
512 __ pushl(EDX); // Pass arguments descriptor. | 504 __ pushl(EDX); // Pass arguments descriptor. |
513 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 505 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
514 // Discard arguments. | 506 // Discard arguments. |
515 __ popl(EAX); | 507 __ popl(EAX); |
516 __ popl(EAX); | 508 __ popl(EAX); |
517 __ popl(EAX); | 509 __ popl(EAX); |
518 __ popl(EAX); // Return value from the runtime call (function). | 510 __ popl(EAX); // Return value from the runtime call (function). |
519 __ popl(EDX); // Restore arguments descriptor. | 511 __ popl(EDX); // Restore arguments descriptor. |
(...skipping 12 matching lines...) Expand all Loading... |
532 | 524 |
533 | 525 |
534 // Called for inline allocation of arrays. | 526 // Called for inline allocation of arrays. |
535 // Input parameters: | 527 // Input parameters: |
536 // EDX : Array length as Smi (must be preserved). | 528 // EDX : Array length as Smi (must be preserved). |
537 // ECX : array element type (either NULL or an instantiated type). | 529 // ECX : array element type (either NULL or an instantiated type). |
538 // Uses EAX, EBX, ECX, EDI as temporary registers. | 530 // Uses EAX, EBX, ECX, EDI as temporary registers. |
539 // The newly allocated object is returned in EAX. | 531 // The newly allocated object is returned in EAX. |
540 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 532 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
541 Label slow_case; | 533 Label slow_case; |
542 const Immediate& raw_null = | |
543 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
544 // Compute the size to be allocated, it is based on the array length | 534 // Compute the size to be allocated, it is based on the array length |
545 // and is computed as: | 535 // and is computed as: |
546 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 536 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
547 // Assert that length is a Smi. | 537 // Assert that length is a Smi. |
548 __ testl(EDX, Immediate(kSmiTagMask)); | 538 __ testl(EDX, Immediate(kSmiTagMask)); |
549 | 539 |
550 if (FLAG_use_slow_path) { | 540 if (FLAG_use_slow_path) { |
551 __ jmp(&slow_case); | 541 __ jmp(&slow_case); |
552 } else { | 542 } else { |
553 __ j(NOT_ZERO, &slow_case); | 543 __ j(NOT_ZERO, &slow_case); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 __ jmp(&init_loop, Assembler::kNearJump); | 644 __ jmp(&init_loop, Assembler::kNearJump); |
655 __ Bind(&done); | 645 __ Bind(&done); |
656 __ ret(); // returns the newly allocated object in EAX. | 646 __ ret(); // returns the newly allocated object in EAX. |
657 | 647 |
658 // Unable to allocate the array using the fast inline code, just call | 648 // Unable to allocate the array using the fast inline code, just call |
659 // into the runtime. | 649 // into the runtime. |
660 __ Bind(&slow_case); | 650 __ Bind(&slow_case); |
661 // Create a stub frame as we are pushing some objects on the stack before | 651 // Create a stub frame as we are pushing some objects on the stack before |
662 // calling into the runtime. | 652 // calling into the runtime. |
663 __ EnterStubFrame(); | 653 __ EnterStubFrame(); |
664 __ pushl(raw_null); // Setup space on stack for return value. | 654 __ pushl(Immediate(0)); // Setup space on stack for return value. |
665 __ pushl(EDX); // Array length as Smi. | 655 __ pushl(EDX); // Array length as Smi. |
666 __ pushl(ECX); // Element type. | 656 __ pushl(ECX); // Element type. |
667 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 657 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
668 __ popl(EAX); // Pop element type argument. | 658 __ popl(EAX); // Pop element type argument. |
669 __ popl(EDX); // Pop array length argument (preserved). | 659 __ popl(EDX); // Pop array length argument (preserved). |
670 __ popl(EAX); // Pop return value from return slot. | 660 __ popl(EAX); // Pop return value from return slot. |
671 __ LeaveFrame(); | 661 __ LeaveFrame(); |
672 __ ret(); | 662 __ ret(); |
673 } | 663 } |
674 | 664 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 } | 772 } |
783 | 773 |
784 | 774 |
785 // Called for inline allocation of contexts. | 775 // Called for inline allocation of contexts. |
786 // Input: | 776 // Input: |
787 // EDX: number of context variables. | 777 // EDX: number of context variables. |
788 // Output: | 778 // Output: |
789 // EAX: new allocated RawContext object. | 779 // EAX: new allocated RawContext object. |
790 // EBX and EDX are destroyed. | 780 // EBX and EDX are destroyed. |
791 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 781 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
792 const Immediate& raw_null = | |
793 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
794 if (FLAG_inline_alloc) { | 782 if (FLAG_inline_alloc) { |
795 Label slow_case; | 783 Label slow_case; |
796 // First compute the rounded instance size. | 784 // First compute the rounded instance size. |
797 // EDX: number of context variables. | 785 // EDX: number of context variables. |
798 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 786 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
799 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 787 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
800 __ andl(EBX, Immediate(-kObjectAlignment)); | 788 __ andl(EBX, Immediate(-kObjectAlignment)); |
801 | 789 |
802 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, | 790 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, |
803 EAX, | 791 EAX, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 | 886 |
899 // Done allocating and initializing the context. | 887 // Done allocating and initializing the context. |
900 // EAX: new object. | 888 // EAX: new object. |
901 __ ret(); | 889 __ ret(); |
902 | 890 |
903 __ Bind(&slow_case); | 891 __ Bind(&slow_case); |
904 } | 892 } |
905 // Create a stub frame as we are pushing some objects on the stack before | 893 // Create a stub frame as we are pushing some objects on the stack before |
906 // calling into the runtime. | 894 // calling into the runtime. |
907 __ EnterStubFrame(); | 895 __ EnterStubFrame(); |
908 __ pushl(raw_null); // Setup space on stack for return value. | 896 __ pushl(Immediate(0)); // Setup space on stack for return value. |
909 __ SmiTag(EDX); | 897 __ SmiTag(EDX); |
910 __ pushl(EDX); | 898 __ pushl(EDX); |
911 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. | 899 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
912 __ popl(EAX); // Pop number of context variables argument. | 900 __ popl(EAX); // Pop number of context variables argument. |
913 __ popl(EAX); // Pop the new context object. | 901 __ popl(EAX); // Pop the new context object. |
914 // EAX: new object | 902 // EAX: new object |
915 // Restore the frame pointer. | 903 // Restore the frame pointer. |
916 __ LeaveFrame(); | 904 __ LeaveFrame(); |
917 __ ret(); | 905 __ ret(); |
918 } | 906 } |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 // ESP + 4 : address of last argument. | 1114 // ESP + 4 : address of last argument. |
1127 // EDX : arguments descriptor array. | 1115 // EDX : arguments descriptor array. |
1128 // Uses EAX, EBX, EDI as temporary registers. | 1116 // Uses EAX, EBX, EDI as temporary registers. |
1129 void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) { | 1117 void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) { |
1130 __ EnterStubFrame(); | 1118 __ EnterStubFrame(); |
1131 | 1119 |
1132 // Load the receiver. | 1120 // Load the receiver. |
1133 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1121 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1134 __ movl(EAX, Address(EBP, EDI, TIMES_2, kParamEndSlotFromFp * kWordSize)); | 1122 __ movl(EAX, Address(EBP, EDI, TIMES_2, kParamEndSlotFromFp * kWordSize)); |
1135 | 1123 |
1136 const Immediate& raw_null = | 1124 __ pushl(Immediate(0)); // Setup space on stack for result from noSuchMethod. |
1137 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1138 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | |
1139 __ pushl(EAX); // Receiver. | 1125 __ pushl(EAX); // Receiver. |
1140 __ pushl(EDX); // Arguments descriptor array. | 1126 __ pushl(EDX); // Arguments descriptor array. |
1141 | 1127 |
1142 __ movl(EDX, EDI); | 1128 __ movl(EDX, EDI); |
1143 // EDX: Smi-tagged arguments array length. | 1129 // EDX: Smi-tagged arguments array length. |
1144 PushArgumentsArray(assembler); | 1130 PushArgumentsArray(assembler); |
1145 | 1131 |
1146 const intptr_t kNumArgs = 3; | 1132 const intptr_t kNumArgs = 3; |
1147 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); | 1133 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); |
1148 // noSuchMethod on closures always throws an error, so it will never return. | 1134 // noSuchMethod on closures always throws an error, so it will never return. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 | 1347 |
1362 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; | 1348 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; |
1363 __ addl(EBX, Immediate(entry_size)); // Next entry. | 1349 __ addl(EBX, Immediate(entry_size)); // Next entry. |
1364 __ movl(EDI, Address(EBX, 0)); // Next class ID. | 1350 __ movl(EDI, Address(EBX, 0)); // Next class ID. |
1365 | 1351 |
1366 __ Bind(&test); | 1352 __ Bind(&test); |
1367 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? | 1353 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
1368 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1354 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1369 | 1355 |
1370 __ Comment("IC miss"); | 1356 __ Comment("IC miss"); |
1371 const Immediate& raw_null = | |
1372 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1373 // Compute address of arguments (first read number of arguments from | 1357 // Compute address of arguments (first read number of arguments from |
1374 // arguments descriptor array and then compute address on the stack). | 1358 // arguments descriptor array and then compute address on the stack). |
1375 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1359 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1376 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. | 1360 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. |
1377 // Create a stub frame as we are pushing some objects on the stack before | 1361 // Create a stub frame as we are pushing some objects on the stack before |
1378 // calling into the runtime. | 1362 // calling into the runtime. |
1379 __ EnterStubFrame(); | 1363 __ EnterStubFrame(); |
1380 __ pushl(EDX); // Preserve arguments descriptor array. | 1364 __ pushl(EDX); // Preserve arguments descriptor array. |
1381 __ pushl(ECX); // Preserve IC data object. | 1365 __ pushl(ECX); // Preserve IC data object. |
1382 __ pushl(raw_null); // Setup space on stack for result (target code object). | 1366 __ pushl(Immediate(0)); // Result slot. |
1383 // Push call arguments. | 1367 // Push call arguments. |
1384 for (intptr_t i = 0; i < num_args; i++) { | 1368 for (intptr_t i = 0; i < num_args; i++) { |
1385 __ movl(EBX, Address(EAX, -kWordSize * i)); | 1369 __ movl(EBX, Address(EAX, -kWordSize * i)); |
1386 __ pushl(EBX); | 1370 __ pushl(EBX); |
1387 } | 1371 } |
1388 __ pushl(ECX); // Pass IC data object. | 1372 __ pushl(ECX); // Pass IC data object. |
1389 __ CallRuntime(handle_ic_miss, num_args + 1); | 1373 __ CallRuntime(handle_ic_miss, num_args + 1); |
1390 // Remove the call arguments pushed earlier, including the IC data object. | 1374 // Remove the call arguments pushed earlier, including the IC data object. |
1391 for (intptr_t i = 0; i < num_args + 1; i++) { | 1375 for (intptr_t i = 0; i < num_args + 1; i++) { |
1392 __ popl(EAX); | 1376 __ popl(EAX); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1617 } | 1601 } |
1618 | 1602 |
1619 | 1603 |
1620 // ECX: Contains an ICData. | 1604 // ECX: Contains an ICData. |
1621 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1605 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
1622 __ EnterStubFrame(); | 1606 __ EnterStubFrame(); |
1623 // Save IC data. | 1607 // Save IC data. |
1624 __ pushl(ECX); | 1608 __ pushl(ECX); |
1625 // Room for result. Debugger stub returns address of the | 1609 // Room for result. Debugger stub returns address of the |
1626 // unpatched runtime stub. | 1610 // unpatched runtime stub. |
1627 const Immediate& raw_null = | 1611 __ pushl(Immediate(0)); // Room for result. |
1628 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1629 __ pushl(raw_null); // Room for result. | |
1630 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1612 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1631 __ popl(EAX); // Code of original stub. | 1613 __ popl(EAX); // Code of original stub. |
1632 __ popl(ECX); // Restore IC data. | 1614 __ popl(ECX); // Restore IC data. |
1633 __ LeaveFrame(); | 1615 __ LeaveFrame(); |
1634 // Jump to original stub. | 1616 // Jump to original stub. |
1635 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); | 1617 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); |
1636 __ jmp(EAX); | 1618 __ jmp(EAX); |
1637 } | 1619 } |
1638 | 1620 |
1639 | 1621 |
1640 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { | 1622 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { |
1641 __ EnterStubFrame(); | 1623 __ EnterStubFrame(); |
1642 // Room for result. Debugger stub returns address of the | 1624 // Room for result. Debugger stub returns address of the |
1643 // unpatched runtime stub. | 1625 // unpatched runtime stub. |
1644 const Immediate& raw_null = | 1626 __ pushl(Immediate(0)); // Room for result. |
1645 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1646 __ pushl(raw_null); // Room for result. | |
1647 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1627 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1648 __ popl(EAX); // Code of the original stub | 1628 __ popl(EAX); // Code of the original stub |
1649 __ LeaveFrame(); | 1629 __ LeaveFrame(); |
1650 // Jump to original stub. | 1630 // Jump to original stub. |
1651 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); | 1631 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); |
1652 __ jmp(EAX); | 1632 __ jmp(EAX); |
1653 } | 1633 } |
1654 | 1634 |
1655 | 1635 |
1656 // Called only from unoptimized code. | 1636 // Called only from unoptimized code. |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 // Clear top exit frame. | 1800 // Clear top exit frame. |
1821 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0)); | 1801 __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0)); |
1822 __ jmp(EBX); // Jump to the exception handler code. | 1802 __ jmp(EBX); // Jump to the exception handler code. |
1823 } | 1803 } |
1824 | 1804 |
1825 | 1805 |
1826 // Calls to the runtime to optimize the given function. | 1806 // Calls to the runtime to optimize the given function. |
1827 // EBX: function to be reoptimized. | 1807 // EBX: function to be reoptimized. |
1828 // EDX: argument descriptor (preserved). | 1808 // EDX: argument descriptor (preserved). |
1829 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1809 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
1830 const Immediate& raw_null = | |
1831 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1832 __ EnterStubFrame(); | 1810 __ EnterStubFrame(); |
1833 __ pushl(EDX); | 1811 __ pushl(EDX); |
1834 __ pushl(raw_null); // Setup space on stack for return value. | 1812 __ pushl(Immediate(0)); // Setup space on stack for return value. |
1835 __ pushl(EBX); | 1813 __ pushl(EBX); |
1836 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1814 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
1837 __ popl(EAX); // Discard argument. | 1815 __ popl(EAX); // Discard argument. |
1838 __ popl(EAX); // Get Code object | 1816 __ popl(EAX); // Get Code object |
1839 __ popl(EDX); // Restore argument descriptor. | 1817 __ popl(EDX); // Restore argument descriptor. |
1840 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); | 1818 __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset())); |
1841 __ LeaveFrame(); | 1819 __ LeaveFrame(); |
1842 __ jmp(EAX); | 1820 __ jmp(EAX); |
1843 __ int3(); | 1821 __ int3(); |
1844 } | 1822 } |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 } | 2037 } |
2060 | 2038 |
2061 | 2039 |
2062 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2040 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
2063 __ int3(); | 2041 __ int3(); |
2064 } | 2042 } |
2065 | 2043 |
2066 } // namespace dart | 2044 } // namespace dart |
2067 | 2045 |
2068 #endif // defined TARGET_ARCH_IA32 | 2046 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |