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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 END_LEAF_RUNTIME_ENTRY | 100 END_LEAF_RUNTIME_ENTRY |
101 | 101 |
102 | 102 |
103 // Input parameters: | 103 // Input parameters: |
104 // ESP : points to return address. | 104 // ESP : points to return address. |
105 // EAX : stop message (const char*). | 105 // EAX : stop message (const char*). |
106 // Must preserve all registers, except EAX. | 106 // Must preserve all registers, except EAX. |
107 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 107 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
108 __ EnterCallRuntimeFrame(1 * kWordSize); | 108 __ EnterCallRuntimeFrame(1 * kWordSize); |
109 __ movl(Address(ESP, 0), EAX); | 109 __ movl(Address(ESP, 0), EAX); |
110 __ CallRuntime(kPrintStopMessageRuntimeEntry); | 110 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); |
111 __ LeaveCallRuntimeFrame(); | 111 __ LeaveCallRuntimeFrame(); |
112 __ ret(); | 112 __ ret(); |
113 } | 113 } |
114 | 114 |
115 | 115 |
116 // Input parameters: | 116 // Input parameters: |
117 // ESP : points to return address. | 117 // ESP : points to return address. |
118 // ESP + 4 : address of return value. | 118 // ESP + 4 : address of return value. |
119 // EAX : address of first argument in argument array. | 119 // EAX : address of first argument in argument array. |
120 // ECX : address of the native function to call. | 120 // ECX : address of the native function to call. |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 | 256 |
257 | 257 |
258 // Input parameters: | 258 // Input parameters: |
259 // EDX: arguments descriptor array. | 259 // EDX: arguments descriptor array. |
260 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 260 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
261 const Immediate& raw_null = | 261 const Immediate& raw_null = |
262 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 262 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
263 __ EnterStubFrame(); | 263 __ EnterStubFrame(); |
264 __ pushl(EDX); // Preserve arguments descriptor array. | 264 __ pushl(EDX); // Preserve arguments descriptor array. |
265 __ pushl(raw_null); // Setup space on stack for return value. | 265 __ pushl(raw_null); // Setup space on stack for return value. |
266 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 266 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
267 __ popl(EAX); // Get Code object result. | 267 __ popl(EAX); // Get Code object result. |
268 __ popl(EDX); // Restore arguments descriptor array. | 268 __ popl(EDX); // Restore arguments descriptor array. |
269 // Remove the stub frame as we are about to jump to the dart function. | 269 // Remove the stub frame as we are about to jump to the dart function. |
270 __ LeaveFrame(); | 270 __ LeaveFrame(); |
271 | 271 |
272 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 272 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
273 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 273 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
274 __ jmp(ECX); | 274 __ jmp(ECX); |
275 } | 275 } |
276 | 276 |
277 | 277 |
278 // Called from a static call only when an invalid code has been entered | 278 // Called from a static call only when an invalid code has been entered |
279 // (invalid because its function was optimized or deoptimized). | 279 // (invalid because its function was optimized or deoptimized). |
280 // EDX: arguments descriptor array. | 280 // EDX: arguments descriptor array. |
281 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 281 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
282 const Immediate& raw_null = | 282 const Immediate& raw_null = |
283 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 283 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
284 // Create a stub frame as we are pushing some objects on the stack before | 284 // Create a stub frame as we are pushing some objects on the stack before |
285 // calling into the runtime. | 285 // calling into the runtime. |
286 __ EnterStubFrame(); | 286 __ EnterStubFrame(); |
287 __ pushl(EDX); // Preserve arguments descriptor array. | 287 __ pushl(EDX); // Preserve arguments descriptor array. |
288 __ pushl(raw_null); // Setup space on stack for return value. | 288 __ pushl(raw_null); // Setup space on stack for return value. |
289 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 289 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
290 __ popl(EAX); // Get Code object. | 290 __ popl(EAX); // Get Code object. |
291 __ popl(EDX); // Restore arguments descriptor array. | 291 __ popl(EDX); // Restore arguments descriptor array. |
292 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 292 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
293 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 293 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
294 __ LeaveFrame(); | 294 __ LeaveFrame(); |
295 __ jmp(EAX); | 295 __ jmp(EAX); |
296 __ int3(); | 296 __ int3(); |
297 } | 297 } |
298 | 298 |
299 | 299 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
351 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize))); | 351 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize))); |
352 | 352 |
353 __ pushl(ECX); // Pass IC data object. | 353 __ pushl(ECX); // Pass IC data object. |
354 __ pushl(EDX); // Pass arguments descriptor array. | 354 __ pushl(EDX); // Pass arguments descriptor array. |
355 | 355 |
356 // Pass the call's arguments array. | 356 // Pass the call's arguments array. |
357 __ movl(EDX, EDI); // Smi-tagged arguments array length. | 357 __ movl(EDX, EDI); // Smi-tagged arguments array length. |
358 PushArgumentsArray(assembler); | 358 PushArgumentsArray(assembler); |
359 | 359 |
360 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); | 360 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); |
361 | 361 |
362 // Remove arguments. | 362 // Remove arguments. |
363 __ Drop(4); | 363 __ Drop(4); |
364 __ popl(EAX); // Get result into EAX. | 364 __ popl(EAX); // Get result into EAX. |
365 __ LeaveFrame(); | 365 __ LeaveFrame(); |
366 __ ret(); | 366 __ ret(); |
367 } | 367 } |
368 | 368 |
369 | 369 |
370 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 370 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 intptr_t offset = 0; | 415 intptr_t offset = 0; |
416 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 416 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
417 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 417 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
418 __ movups(Address(ESP, offset), xmm_reg); | 418 __ movups(Address(ESP, offset), xmm_reg); |
419 offset += kFpuRegisterSize; | 419 offset += kFpuRegisterSize; |
420 } | 420 } |
421 | 421 |
422 __ movl(ECX, ESP); // Preserve saved registers block. | 422 __ movl(ECX, ESP); // Preserve saved registers block. |
423 __ ReserveAlignedFrameSpace(1 * kWordSize); | 423 __ ReserveAlignedFrameSpace(1 * kWordSize); |
424 __ movl(Address(ESP, 0), ECX); // Start of register block. | 424 __ movl(Address(ESP, 0), ECX); // Start of register block. |
425 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); | 425 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); |
426 // Result (EAX) is stack-size (FP - SP) in bytes. | 426 // Result (EAX) is stack-size (FP - SP) in bytes. |
427 | 427 |
428 if (preserve_result) { | 428 if (preserve_result) { |
429 // Restore result into EBX temporarily. | 429 // Restore result into EBX temporarily. |
430 __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize)); | 430 __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize)); |
431 } | 431 } |
432 | 432 |
433 __ LeaveFrame(); | 433 __ LeaveFrame(); |
434 __ popl(EDX); // Preserve return address. | 434 __ popl(EDX); // Preserve return address. |
435 __ movl(ESP, EBP); // Discard optimized frame. | 435 __ movl(ESP, EBP); // Discard optimized frame. |
436 __ subl(ESP, EAX); // Reserve space for deoptimized frame. | 436 __ subl(ESP, EAX); // Reserve space for deoptimized frame. |
437 __ pushl(EDX); // Restore return address. | 437 __ pushl(EDX); // Restore return address. |
438 | 438 |
439 // Leaf runtime function DeoptimizeFillFrame expects a Dart frame. | 439 // Leaf runtime function DeoptimizeFillFrame expects a Dart frame. |
440 __ EnterDartFrame(0); | 440 __ EnterDartFrame(0); |
441 if (preserve_result) { | 441 if (preserve_result) { |
442 __ pushl(EBX); // Preserve result as first local. | 442 __ pushl(EBX); // Preserve result as first local. |
443 } | 443 } |
444 __ ReserveAlignedFrameSpace(1 * kWordSize); | 444 __ ReserveAlignedFrameSpace(1 * kWordSize); |
445 __ movl(Address(ESP, 0), EBP); // Pass last FP as parameter on stack. | 445 __ movl(Address(ESP, 0), EBP); // Pass last FP as parameter on stack. |
446 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); | 446 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); |
447 if (preserve_result) { | 447 if (preserve_result) { |
448 // Restore result into EBX. | 448 // Restore result into EBX. |
449 __ movl(EBX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); | 449 __ movl(EBX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); |
450 } | 450 } |
451 // Code above cannot cause GC. | 451 // Code above cannot cause GC. |
452 __ LeaveFrame(); | 452 __ LeaveFrame(); |
453 | 453 |
454 // Frame is fully rewritten at this point and it is safe to perform a GC. | 454 // Frame is fully rewritten at this point and it is safe to perform a GC. |
455 // Materialize any objects that were deferred by FillFrame because they | 455 // Materialize any objects that were deferred by FillFrame because they |
456 // require allocation. | 456 // require allocation. |
457 __ EnterStubFrame(); | 457 __ EnterStubFrame(); |
458 if (preserve_result) { | 458 if (preserve_result) { |
459 __ pushl(EBX); // Preserve result, it will be GC-d here. | 459 __ pushl(EBX); // Preserve result, it will be GC-d here. |
460 } | 460 } |
461 __ pushl(Immediate(Smi::RawValue(0))); // Space for the result. | 461 __ pushl(Immediate(Smi::RawValue(0))); // Space for the result. |
462 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); | 462 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
463 // Result tells stub how many bytes to remove from the expression stack | 463 // Result tells stub how many bytes to remove from the expression stack |
464 // of the bottom-most frame. They were used as materialization arguments. | 464 // of the bottom-most frame. They were used as materialization arguments. |
465 __ popl(EBX); | 465 __ popl(EBX); |
466 __ SmiUntag(EBX); | 466 __ SmiUntag(EBX); |
467 if (preserve_result) { | 467 if (preserve_result) { |
468 __ popl(EAX); // Restore result. | 468 __ popl(EAX); // Restore result. |
469 } | 469 } |
470 __ LeaveFrame(); | 470 __ LeaveFrame(); |
471 | 471 |
472 __ popl(ECX); // Pop return address. | 472 __ popl(ECX); // Pop return address. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 // Preserve IC data and arguments descriptor. | 504 // Preserve IC data and arguments descriptor. |
505 __ pushl(ECX); | 505 __ pushl(ECX); |
506 __ pushl(EDX); | 506 __ pushl(EDX); |
507 | 507 |
508 const Immediate& raw_null = | 508 const Immediate& raw_null = |
509 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); | 509 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); |
510 __ pushl(raw_null); // Space for the result of the runtime call. | 510 __ pushl(raw_null); // Space for the result of the runtime call. |
511 __ pushl(EAX); // Pass receiver. | 511 __ pushl(EAX); // Pass receiver. |
512 __ pushl(ECX); // Pass IC data. | 512 __ pushl(ECX); // Pass IC data. |
513 __ pushl(EDX); // Pass arguments descriptor. | 513 __ pushl(EDX); // Pass arguments descriptor. |
514 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); | 514 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
515 // Discard arguments. | 515 // Discard arguments. |
516 __ popl(EAX); | 516 __ popl(EAX); |
517 __ popl(EAX); | 517 __ popl(EAX); |
518 __ popl(EAX); | 518 __ popl(EAX); |
519 __ popl(EAX); // Return value from the runtime call (instructions). | 519 __ popl(EAX); // Return value from the runtime call (instructions). |
520 __ popl(EDX); // Restore arguments descriptor. | 520 __ popl(EDX); // Restore arguments descriptor. |
521 __ popl(ECX); // Restore IC data. | 521 __ popl(ECX); // Restore IC data. |
522 __ LeaveFrame(); | 522 __ LeaveFrame(); |
523 | 523 |
524 Label lookup; | 524 Label lookup; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 | 655 |
656 // Unable to allocate the array using the fast inline code, just call | 656 // Unable to allocate the array using the fast inline code, just call |
657 // into the runtime. | 657 // into the runtime. |
658 __ Bind(&slow_case); | 658 __ Bind(&slow_case); |
659 // Create a stub frame as we are pushing some objects on the stack before | 659 // Create a stub frame as we are pushing some objects on the stack before |
660 // calling into the runtime. | 660 // calling into the runtime. |
661 __ EnterStubFrame(); | 661 __ EnterStubFrame(); |
662 __ pushl(raw_null); // Setup space on stack for return value. | 662 __ pushl(raw_null); // Setup space on stack for return value. |
663 __ pushl(EDX); // Array length as Smi. | 663 __ pushl(EDX); // Array length as Smi. |
664 __ pushl(ECX); // Element type. | 664 __ pushl(ECX); // Element type. |
665 __ CallRuntime(kAllocateArrayRuntimeEntry); | 665 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
666 __ popl(EAX); // Pop element type argument. | 666 __ popl(EAX); // Pop element type argument. |
667 __ popl(EDX); // Pop array length argument. | 667 __ popl(EDX); // Pop array length argument. |
668 __ popl(EAX); // Pop return value from return slot. | 668 __ popl(EAX); // Pop return value from return slot. |
669 __ LeaveFrame(); | 669 __ LeaveFrame(); |
670 __ ret(); | 670 __ ret(); |
671 } | 671 } |
672 | 672 |
673 | 673 |
674 // Input parameters: | 674 // Input parameters: |
675 // EDX: Arguments descriptor array. | 675 // EDX: Arguments descriptor array. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 __ cmpl(EAX, raw_null); | 712 __ cmpl(EAX, raw_null); |
713 Label function_compiled; | 713 Label function_compiled; |
714 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 714 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
715 | 715 |
716 // Create a stub frame as we are pushing some objects on the stack before | 716 // Create a stub frame as we are pushing some objects on the stack before |
717 // calling into the runtime. | 717 // calling into the runtime. |
718 __ EnterStubFrame(); | 718 __ EnterStubFrame(); |
719 | 719 |
720 __ pushl(EDX); // Preserve arguments descriptor array. | 720 __ pushl(EDX); // Preserve arguments descriptor array. |
721 __ pushl(ECX); // Preserve read-only function object argument. | 721 __ pushl(ECX); // Preserve read-only function object argument. |
722 __ CallRuntime(kCompileFunctionRuntimeEntry); | 722 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
723 __ popl(ECX); // Restore read-only function object argument in ECX. | 723 __ popl(ECX); // Restore read-only function object argument in ECX. |
724 __ popl(EDX); // Restore arguments descriptor array. | 724 __ popl(EDX); // Restore arguments descriptor array. |
725 // Restore EAX. | 725 // Restore EAX. |
726 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); | 726 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); |
727 | 727 |
728 // Remove the stub frame as we are about to jump to the closure function. | 728 // Remove the stub frame as we are about to jump to the closure function. |
729 __ LeaveFrame(); | 729 __ LeaveFrame(); |
730 | 730 |
731 __ Bind(&function_compiled); | 731 __ Bind(&function_compiled); |
732 // EAX: Code. | 732 // EAX: Code. |
(...skipping 15 matching lines...) Expand all Loading... |
748 // Create a stub frame as we are pushing some objects on the stack before | 748 // Create a stub frame as we are pushing some objects on the stack before |
749 // calling into the runtime. | 749 // calling into the runtime. |
750 __ EnterStubFrame(); | 750 __ EnterStubFrame(); |
751 | 751 |
752 __ pushl(raw_null); // Setup space on stack for result from error reporting. | 752 __ pushl(raw_null); // Setup space on stack for result from error reporting. |
753 __ pushl(EDX); // Arguments descriptor. | 753 __ pushl(EDX); // Arguments descriptor. |
754 // Load smi-tagged arguments array length, including the non-closure. | 754 // Load smi-tagged arguments array length, including the non-closure. |
755 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 755 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
756 PushArgumentsArray(assembler); | 756 PushArgumentsArray(assembler); |
757 | 757 |
758 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 758 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); |
759 // Remove arguments. | 759 // Remove arguments. |
760 __ Drop(2); | 760 __ Drop(2); |
761 __ popl(EAX); // Get result into EAX. | 761 __ popl(EAX); // Get result into EAX. |
762 | 762 |
763 // Remove the stub frame as we are about to return. | 763 // Remove the stub frame as we are about to return. |
764 __ LeaveFrame(); | 764 __ LeaveFrame(); |
765 __ ret(); | 765 __ ret(); |
766 } | 766 } |
767 | 767 |
768 | 768 |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 __ ret(); | 997 __ ret(); |
998 | 998 |
999 __ Bind(&slow_case); | 999 __ Bind(&slow_case); |
1000 } | 1000 } |
1001 // Create a stub frame as we are pushing some objects on the stack before | 1001 // Create a stub frame as we are pushing some objects on the stack before |
1002 // calling into the runtime. | 1002 // calling into the runtime. |
1003 __ EnterStubFrame(); | 1003 __ EnterStubFrame(); |
1004 __ pushl(raw_null); // Setup space on stack for return value. | 1004 __ pushl(raw_null); // Setup space on stack for return value. |
1005 __ SmiTag(EDX); | 1005 __ SmiTag(EDX); |
1006 __ pushl(EDX); | 1006 __ pushl(EDX); |
1007 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 1007 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
1008 __ popl(EAX); // Pop number of context variables argument. | 1008 __ popl(EAX); // Pop number of context variables argument. |
1009 __ popl(EAX); // Pop the new context object. | 1009 __ popl(EAX); // Pop the new context object. |
1010 // EAX: new object | 1010 // EAX: new object |
1011 // Restore the frame pointer. | 1011 // Restore the frame pointer. |
1012 __ LeaveFrame(); | 1012 __ LeaveFrame(); |
1013 __ ret(); | 1013 __ ret(); |
1014 } | 1014 } |
1015 | 1015 |
1016 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); | 1016 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
1017 | 1017 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 __ j(EQUAL, &L, Assembler::kNearJump); | 1068 __ j(EQUAL, &L, Assembler::kNearJump); |
1069 __ ret(); | 1069 __ ret(); |
1070 | 1070 |
1071 // Handle overflow: Call the runtime leaf function. | 1071 // Handle overflow: Call the runtime leaf function. |
1072 __ Bind(&L); | 1072 __ Bind(&L); |
1073 // Setup frame, push callee-saved registers. | 1073 // Setup frame, push callee-saved registers. |
1074 | 1074 |
1075 __ EnterCallRuntimeFrame(1 * kWordSize); | 1075 __ EnterCallRuntimeFrame(1 * kWordSize); |
1076 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1076 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
1077 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. | 1077 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. |
1078 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry); | 1078 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
1079 // Restore callee-saved registers, tear down frame. | 1079 // Restore callee-saved registers, tear down frame. |
1080 __ LeaveCallRuntimeFrame(); | 1080 __ LeaveCallRuntimeFrame(); |
1081 __ ret(); | 1081 __ ret(); |
1082 } | 1082 } |
1083 | 1083 |
1084 | 1084 |
1085 // Called for inline allocation of objects. | 1085 // Called for inline allocation of objects. |
1086 // Input parameters: | 1086 // Input parameters: |
1087 // ESP + 8 : type arguments object (only if class is parameterized). | 1087 // ESP + 8 : type arguments object (only if class is parameterized). |
1088 // ESP + 4 : type arguments of instantiator (only if class is parameterized). | 1088 // ESP + 4 : type arguments of instantiator (only if class is parameterized). |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 __ EnterStubFrame(); | 1238 __ EnterStubFrame(); |
1239 __ pushl(raw_null); // Setup space on stack for return value. | 1239 __ pushl(raw_null); // Setup space on stack for return value. |
1240 __ PushObject(cls); // Push class of object to be allocated. | 1240 __ PushObject(cls); // Push class of object to be allocated. |
1241 if (is_cls_parameterized) { | 1241 if (is_cls_parameterized) { |
1242 __ pushl(EAX); // Push type arguments of object to be allocated. | 1242 __ pushl(EAX); // Push type arguments of object to be allocated. |
1243 __ pushl(EDX); // Push type arguments of instantiator. | 1243 __ pushl(EDX); // Push type arguments of instantiator. |
1244 } else { | 1244 } else { |
1245 __ pushl(raw_null); // Push null type arguments. | 1245 __ pushl(raw_null); // Push null type arguments. |
1246 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1246 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
1247 } | 1247 } |
1248 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1248 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. |
1249 __ popl(EAX); // Pop argument (instantiator). | 1249 __ popl(EAX); // Pop argument (instantiator). |
1250 __ popl(EAX); // Pop argument (type arguments of object). | 1250 __ popl(EAX); // Pop argument (type arguments of object). |
1251 __ popl(EAX); // Pop argument (class of object). | 1251 __ popl(EAX); // Pop argument (class of object). |
1252 __ popl(EAX); // Pop result (newly allocated object). | 1252 __ popl(EAX); // Pop result (newly allocated object). |
1253 // EAX: new object | 1253 // EAX: new object |
1254 // Restore the frame pointer. | 1254 // Restore the frame pointer. |
1255 __ LeaveFrame(); | 1255 __ LeaveFrame(); |
1256 __ ret(); | 1256 __ ret(); |
1257 } | 1257 } |
1258 | 1258 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 __ PushObject(func); | 1372 __ PushObject(func); |
1373 if (is_implicit_instance_closure) { | 1373 if (is_implicit_instance_closure) { |
1374 __ pushl(EAX); // Receiver. | 1374 __ pushl(EAX); // Receiver. |
1375 } | 1375 } |
1376 if (has_type_arguments) { | 1376 if (has_type_arguments) { |
1377 __ pushl(ECX); // Push type arguments of closure to be allocated. | 1377 __ pushl(ECX); // Push type arguments of closure to be allocated. |
1378 } else { | 1378 } else { |
1379 __ pushl(raw_null); // Push null type arguments. | 1379 __ pushl(raw_null); // Push null type arguments. |
1380 } | 1380 } |
1381 if (is_implicit_instance_closure) { | 1381 if (is_implicit_instance_closure) { |
1382 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); | 1382 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
1383 __ popl(EAX); // Pop argument (type arguments of object). | 1383 __ popl(EAX); // Pop argument (type arguments of object). |
1384 __ popl(EAX); // Pop receiver. | 1384 __ popl(EAX); // Pop receiver. |
1385 } else { | 1385 } else { |
1386 ASSERT(func.IsNonImplicitClosureFunction()); | 1386 ASSERT(func.IsNonImplicitClosureFunction()); |
1387 __ CallRuntime(kAllocateClosureRuntimeEntry); | 1387 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
1388 __ popl(EAX); // Pop argument (type arguments of object). | 1388 __ popl(EAX); // Pop argument (type arguments of object). |
1389 } | 1389 } |
1390 __ popl(EAX); // Pop function object. | 1390 __ popl(EAX); // Pop function object. |
1391 __ popl(EAX); | 1391 __ popl(EAX); |
1392 // EAX: new object | 1392 // EAX: new object |
1393 // Restore the frame pointer. | 1393 // Restore the frame pointer. |
1394 __ LeaveFrame(); | 1394 __ LeaveFrame(); |
1395 __ ret(); | 1395 __ ret(); |
1396 } | 1396 } |
1397 | 1397 |
(...skipping 18 matching lines...) Expand all Loading... |
1416 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1416 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1417 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | 1417 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
1418 __ pushl(EAX); // Receiver. | 1418 __ pushl(EAX); // Receiver. |
1419 __ pushl(ECX); // IC data array. | 1419 __ pushl(ECX); // IC data array. |
1420 __ pushl(EDX); // Arguments descriptor array. | 1420 __ pushl(EDX); // Arguments descriptor array. |
1421 | 1421 |
1422 __ movl(EDX, EDI); | 1422 __ movl(EDX, EDI); |
1423 // EDX: Smi-tagged arguments array length. | 1423 // EDX: Smi-tagged arguments array length. |
1424 PushArgumentsArray(assembler); | 1424 PushArgumentsArray(assembler); |
1425 | 1425 |
1426 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1426 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); |
1427 | 1427 |
1428 // Remove arguments. | 1428 // Remove arguments. |
1429 __ Drop(4); | 1429 __ Drop(4); |
1430 __ popl(EAX); // Get result into EAX. | 1430 __ popl(EAX); // Get result into EAX. |
1431 | 1431 |
1432 // Remove the stub frame as we are about to return. | 1432 // Remove the stub frame as we are about to return. |
1433 __ LeaveFrame(); | 1433 __ LeaveFrame(); |
1434 __ ret(); | 1434 __ ret(); |
1435 } | 1435 } |
1436 | 1436 |
1437 | 1437 |
1438 // Cannot use function object from ICData as it may be the inlined | 1438 // Cannot use function object from ICData as it may be the inlined |
1439 // function and not the top-scope function. | 1439 // function and not the top-scope function. |
1440 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1440 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
1441 Register ic_reg = ECX; | 1441 Register ic_reg = ECX; |
1442 Register func_reg = EDI; | 1442 Register func_reg = EDI; |
1443 if (FLAG_trace_optimized_ic_calls) { | 1443 if (FLAG_trace_optimized_ic_calls) { |
1444 __ EnterStubFrame(); | 1444 __ EnterStubFrame(); |
1445 __ pushl(func_reg); // Preserve | 1445 __ pushl(func_reg); // Preserve |
1446 __ pushl(ic_reg); // Preserve. | 1446 __ pushl(ic_reg); // Preserve. |
1447 __ pushl(ic_reg); // Argument. | 1447 __ pushl(ic_reg); // Argument. |
1448 __ pushl(func_reg); // Argument. | 1448 __ pushl(func_reg); // Argument. |
1449 __ CallRuntime(kTraceICCallRuntimeEntry); | 1449 __ CallRuntime(kTraceICCallRuntimeEntry, 2); |
1450 __ popl(EAX); // Discard argument; | 1450 __ popl(EAX); // Discard argument; |
1451 __ popl(EAX); // Discard argument; | 1451 __ popl(EAX); // Discard argument; |
1452 __ popl(ic_reg); // Restore. | 1452 __ popl(ic_reg); // Restore. |
1453 __ popl(func_reg); // Restore. | 1453 __ popl(func_reg); // Restore. |
1454 __ LeaveFrame(); | 1454 __ LeaveFrame(); |
1455 } | 1455 } |
1456 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | 1456 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
1457 } | 1457 } |
1458 | 1458 |
1459 | 1459 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1497 | 1497 |
1498 // Check single stepping. | 1498 // Check single stepping. |
1499 Label not_stepping; | 1499 Label not_stepping; |
1500 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1500 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
1501 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1501 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
1502 __ cmpl(EAX, Immediate(0)); | 1502 __ cmpl(EAX, Immediate(0)); |
1503 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1503 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
1504 | 1504 |
1505 __ EnterStubFrame(); | 1505 __ EnterStubFrame(); |
1506 __ pushl(ECX); | 1506 __ pushl(ECX); |
1507 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1507 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1508 __ popl(ECX); | 1508 __ popl(ECX); |
1509 __ LeaveFrame(); | 1509 __ LeaveFrame(); |
1510 __ Bind(¬_stepping); | 1510 __ Bind(¬_stepping); |
1511 | 1511 |
1512 // ECX: IC data object (preserved). | 1512 // ECX: IC data object (preserved). |
1513 // Load arguments descriptor into EDX. | 1513 // Load arguments descriptor into EDX. |
1514 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1514 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
1515 // Loop that checks if there is an IC data match. | 1515 // Loop that checks if there is an IC data match. |
1516 Label loop, update, test, found, get_class_id_as_smi; | 1516 Label loop, update, test, found, get_class_id_as_smi; |
1517 // ECX: IC data object (preserved). | 1517 // ECX: IC data object (preserved). |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 __ EnterStubFrame(); | 1576 __ EnterStubFrame(); |
1577 __ pushl(EDX); // Preserve arguments descriptor array. | 1577 __ pushl(EDX); // Preserve arguments descriptor array. |
1578 __ pushl(ECX); // Preserve IC data object. | 1578 __ pushl(ECX); // Preserve IC data object. |
1579 __ pushl(raw_null); // Setup space on stack for result (target code object). | 1579 __ pushl(raw_null); // Setup space on stack for result (target code object). |
1580 // Push call arguments. | 1580 // Push call arguments. |
1581 for (intptr_t i = 0; i < num_args; i++) { | 1581 for (intptr_t i = 0; i < num_args; i++) { |
1582 __ movl(EBX, Address(EAX, -kWordSize * i)); | 1582 __ movl(EBX, Address(EAX, -kWordSize * i)); |
1583 __ pushl(EBX); | 1583 __ pushl(EBX); |
1584 } | 1584 } |
1585 __ pushl(ECX); // Pass IC data object. | 1585 __ pushl(ECX); // Pass IC data object. |
1586 __ CallRuntime(handle_ic_miss); | 1586 __ CallRuntime(handle_ic_miss, num_args + 1); |
1587 // Remove the call arguments pushed earlier, including the IC data object. | 1587 // Remove the call arguments pushed earlier, including the IC data object. |
1588 for (intptr_t i = 0; i < num_args + 1; i++) { | 1588 for (intptr_t i = 0; i < num_args + 1; i++) { |
1589 __ popl(EAX); | 1589 __ popl(EAX); |
1590 } | 1590 } |
1591 __ popl(EAX); // Pop returned code object into EAX (null if not found). | 1591 __ popl(EAX); // Pop returned code object into EAX (null if not found). |
1592 __ popl(ECX); // Restore IC data array. | 1592 __ popl(ECX); // Restore IC data array. |
1593 __ popl(EDX); // Restore arguments descriptor array. | 1593 __ popl(EDX); // Restore arguments descriptor array. |
1594 __ LeaveFrame(); | 1594 __ LeaveFrame(); |
1595 Label call_target_function; | 1595 Label call_target_function; |
1596 __ cmpl(EAX, raw_null); | 1596 __ cmpl(EAX, raw_null); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 #endif // DEBUG | 1733 #endif // DEBUG |
1734 // Check single stepping. | 1734 // Check single stepping. |
1735 Label not_stepping; | 1735 Label not_stepping; |
1736 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1736 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
1737 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1737 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
1738 __ cmpl(EAX, Immediate(0)); | 1738 __ cmpl(EAX, Immediate(0)); |
1739 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1739 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
1740 | 1740 |
1741 __ EnterStubFrame(); | 1741 __ EnterStubFrame(); |
1742 __ pushl(ECX); | 1742 __ pushl(ECX); |
1743 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1743 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1744 __ popl(ECX); | 1744 __ popl(ECX); |
1745 __ LeaveFrame(); | 1745 __ LeaveFrame(); |
1746 __ Bind(¬_stepping); | 1746 __ Bind(¬_stepping); |
1747 | 1747 |
1748 // ECX: IC data object (preserved). | 1748 // ECX: IC data object (preserved). |
1749 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); | 1749 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); |
1750 // EBX: ic_data_array with entries: target functions and count. | 1750 // EBX: ic_data_array with entries: target functions and count. |
1751 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); | 1751 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); |
1752 // EBX: points directly to the first ic data array element. | 1752 // EBX: points directly to the first ic data array element. |
1753 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1753 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
(...skipping 11 matching lines...) Expand all Loading... |
1765 Label target_is_compiled; | 1765 Label target_is_compiled; |
1766 // Get function and call it, if possible. | 1766 // Get function and call it, if possible. |
1767 __ movl(EDI, Address(EBX, target_offset)); | 1767 __ movl(EDI, Address(EBX, target_offset)); |
1768 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); | 1768 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); |
1769 __ cmpl(EAX, raw_null); | 1769 __ cmpl(EAX, raw_null); |
1770 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); | 1770 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); |
1771 __ EnterStubFrame(); | 1771 __ EnterStubFrame(); |
1772 __ pushl(EDI); // Preserve target function. | 1772 __ pushl(EDI); // Preserve target function. |
1773 __ pushl(ECX); // Preserve IC data object. | 1773 __ pushl(ECX); // Preserve IC data object. |
1774 __ pushl(EDI); // Pass function. | 1774 __ pushl(EDI); // Pass function. |
1775 __ CallRuntime(kCompileFunctionRuntimeEntry); | 1775 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
1776 __ popl(EAX); // Discard argument. | 1776 __ popl(EAX); // Discard argument. |
1777 __ popl(ECX); // Restore IC data object. | 1777 __ popl(ECX); // Restore IC data object. |
1778 __ popl(EDI); // Restore target function. | 1778 __ popl(EDI); // Restore target function. |
1779 __ LeaveFrame(); | 1779 __ LeaveFrame(); |
1780 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); | 1780 __ movl(EAX, FieldAddress(EDI, Function::code_offset())); |
1781 | 1781 |
1782 __ Bind(&target_is_compiled); | 1782 __ Bind(&target_is_compiled); |
1783 // EAX: Target code. | 1783 // EAX: Target code. |
1784 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 1784 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
1785 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1785 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
(...skipping 14 matching lines...) Expand all Loading... |
1800 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1800 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
1801 __ EnterStubFrame(); | 1801 __ EnterStubFrame(); |
1802 // Save runtime args. | 1802 // Save runtime args. |
1803 __ pushl(ECX); | 1803 __ pushl(ECX); |
1804 __ pushl(EDX); | 1804 __ pushl(EDX); |
1805 // Room for result. Debugger stub returns address of the | 1805 // Room for result. Debugger stub returns address of the |
1806 // unpatched runtime stub. | 1806 // unpatched runtime stub. |
1807 const Immediate& raw_null = | 1807 const Immediate& raw_null = |
1808 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1808 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1809 __ pushl(raw_null); // Room for result. | 1809 __ pushl(raw_null); // Room for result. |
1810 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry); | 1810 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1811 __ popl(EAX); // Address of original stub. | 1811 __ popl(EAX); // Address of original stub. |
1812 __ popl(EDX); // Restore arguments. | 1812 __ popl(EDX); // Restore arguments. |
1813 __ popl(ECX); | 1813 __ popl(ECX); |
1814 __ LeaveFrame(); | 1814 __ LeaveFrame(); |
1815 __ jmp(EAX); // Jump to original stub. | 1815 __ jmp(EAX); // Jump to original stub. |
1816 } | 1816 } |
1817 | 1817 |
1818 | 1818 |
1819 // ECX: ICData (unoptimized static call). | 1819 // ECX: ICData (unoptimized static call). |
1820 // TOS(0): return address (Dart code). | 1820 // TOS(0): return address (Dart code). |
1821 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1821 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1822 // Create a stub frame as we are pushing some objects on the stack before | 1822 // Create a stub frame as we are pushing some objects on the stack before |
1823 // calling into the runtime. | 1823 // calling into the runtime. |
1824 __ EnterStubFrame(); | 1824 __ EnterStubFrame(); |
1825 __ pushl(ECX); // Preserve ICData for unoptimized call. | 1825 __ pushl(ECX); // Preserve ICData for unoptimized call. |
1826 const Immediate& raw_null = | 1826 const Immediate& raw_null = |
1827 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1827 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1828 __ pushl(raw_null); // Room for result. | 1828 __ pushl(raw_null); // Room for result. |
1829 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1829 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); |
1830 __ popl(EAX); // Code object. | 1830 __ popl(EAX); // Code object. |
1831 __ popl(ECX); // Restore ICData. | 1831 __ popl(ECX); // Restore ICData. |
1832 __ LeaveFrame(); | 1832 __ LeaveFrame(); |
1833 | 1833 |
1834 // Load arguments descriptor into EDX. | 1834 // Load arguments descriptor into EDX. |
1835 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1835 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
1836 // Now call the static function. The breakpoint handler function | 1836 // Now call the static function. The breakpoint handler function |
1837 // ensures that the call target is compiled. | 1837 // ensures that the call target is compiled. |
1838 // Note that we can't just jump to the CallStatic function stub | 1838 // Note that we can't just jump to the CallStatic function stub |
1839 // here since that stub would patch the call site with the | 1839 // here since that stub would patch the call site with the |
1840 // static function address. | 1840 // static function address. |
1841 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 1841 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
1842 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1842 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
1843 __ jmp(ECX); | 1843 __ jmp(ECX); |
1844 } | 1844 } |
1845 | 1845 |
1846 | 1846 |
1847 // TOS(0): return address (Dart code). | 1847 // TOS(0): return address (Dart code). |
1848 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1848 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1849 // Create a stub frame as we are pushing some objects on the stack before | 1849 // Create a stub frame as we are pushing some objects on the stack before |
1850 // calling into the runtime. | 1850 // calling into the runtime. |
1851 __ EnterStubFrame(); | 1851 __ EnterStubFrame(); |
1852 __ pushl(EAX); | 1852 __ pushl(EAX); |
1853 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1853 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); |
1854 __ popl(EAX); | 1854 __ popl(EAX); |
1855 __ LeaveFrame(); | 1855 __ LeaveFrame(); |
1856 | 1856 |
1857 // Instead of returning to the patched Dart function, emulate the | 1857 // Instead of returning to the patched Dart function, emulate the |
1858 // smashed return code pattern and return to the function's caller. | 1858 // smashed return code pattern and return to the function's caller. |
1859 __ popl(ECX); // Discard return address to patched dart code. | 1859 __ popl(ECX); // Discard return address to patched dart code. |
1860 // Execute function epilog code that was smashed in the Dart code. | 1860 // Execute function epilog code that was smashed in the Dart code. |
1861 __ LeaveFrame(); | 1861 __ LeaveFrame(); |
1862 __ ret(); | 1862 __ ret(); |
1863 } | 1863 } |
1864 | 1864 |
1865 | 1865 |
1866 // ECX: Inline cache data array. | 1866 // ECX: Inline cache data array. |
1867 // TOS(0): return address (Dart code). | 1867 // TOS(0): return address (Dart code). |
1868 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1868 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
1869 // Create a stub frame as we are pushing some objects on the stack before | 1869 // Create a stub frame as we are pushing some objects on the stack before |
1870 // calling into the runtime. | 1870 // calling into the runtime. |
1871 __ EnterStubFrame(); | 1871 __ EnterStubFrame(); |
1872 __ pushl(ECX); | 1872 __ pushl(ECX); |
1873 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1873 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
1874 __ popl(ECX); | 1874 __ popl(ECX); |
1875 __ LeaveFrame(); | 1875 __ LeaveFrame(); |
1876 | 1876 |
1877 // Find out which dispatch stub to call. | 1877 // Find out which dispatch stub to call. |
1878 Label test_two, test_three, test_four; | 1878 Label test_two, test_three, test_four; |
1879 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); | 1879 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); |
1880 __ cmpl(EBX, Immediate(1)); | 1880 __ cmpl(EBX, Immediate(1)); |
1881 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); | 1881 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); |
1882 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); | 1882 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); |
1883 __ Bind(&test_two); | 1883 __ Bind(&test_two); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2116 __ Bind(&update_ic_data); | 2116 __ Bind(&update_ic_data); |
2117 | 2117 |
2118 // ECX: ICData | 2118 // ECX: ICData |
2119 __ movl(EAX, Address(ESP, 1 * kWordSize)); | 2119 __ movl(EAX, Address(ESP, 1 * kWordSize)); |
2120 __ movl(EDI, Address(ESP, 2 * kWordSize)); | 2120 __ movl(EDI, Address(ESP, 2 * kWordSize)); |
2121 __ EnterStubFrame(); | 2121 __ EnterStubFrame(); |
2122 __ pushl(EDI); // arg 0 | 2122 __ pushl(EDI); // arg 0 |
2123 __ pushl(EAX); // arg 1 | 2123 __ pushl(EAX); // arg 1 |
2124 __ PushObject(Symbols::EqualOperator()); // Target's name. | 2124 __ PushObject(Symbols::EqualOperator()); // Target's name. |
2125 __ pushl(ECX); // ICData | 2125 __ pushl(ECX); // ICData |
2126 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); | 2126 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); |
2127 __ Drop(4); | 2127 __ Drop(4); |
2128 __ LeaveFrame(); | 2128 __ LeaveFrame(); |
2129 | 2129 |
2130 __ jmp(&compute_result, Assembler::kNearJump); | 2130 __ jmp(&compute_result, Assembler::kNearJump); |
2131 } | 2131 } |
2132 | 2132 |
2133 | 2133 |
2134 // Calls to the runtime to optimize the given function. | 2134 // Calls to the runtime to optimize the given function. |
2135 // EDI: function to be reoptimized. | 2135 // EDI: function to be reoptimized. |
2136 // EDX: argument descriptor (preserved). | 2136 // EDX: argument descriptor (preserved). |
2137 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2137 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
2138 const Immediate& raw_null = | 2138 const Immediate& raw_null = |
2139 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 2139 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
2140 __ EnterStubFrame(); | 2140 __ EnterStubFrame(); |
2141 __ pushl(EDX); | 2141 __ pushl(EDX); |
2142 __ pushl(raw_null); // Setup space on stack for return value. | 2142 __ pushl(raw_null); // Setup space on stack for return value. |
2143 __ pushl(EDI); | 2143 __ pushl(EDI); |
2144 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2144 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
2145 __ popl(EAX); // Discard argument. | 2145 __ popl(EAX); // Discard argument. |
2146 __ popl(EAX); // Get Code object | 2146 __ popl(EAX); // Get Code object |
2147 __ popl(EDX); // Restore argument descriptor. | 2147 __ popl(EDX); // Restore argument descriptor. |
2148 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 2148 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
2149 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 2149 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
2150 __ LeaveFrame(); | 2150 __ LeaveFrame(); |
2151 __ jmp(EAX); | 2151 __ jmp(EAX); |
2152 __ int3(); | 2152 __ int3(); |
2153 } | 2153 } |
2154 | 2154 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 | 2204 |
2205 __ Bind(&check_bigint); | 2205 __ Bind(&check_bigint); |
2206 __ CompareClassId(left, kBigintCid, temp); | 2206 __ CompareClassId(left, kBigintCid, temp); |
2207 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); | 2207 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
2208 __ CompareClassId(right, kBigintCid, temp); | 2208 __ CompareClassId(right, kBigintCid, temp); |
2209 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 2209 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
2210 __ EnterFrame(0); | 2210 __ EnterFrame(0); |
2211 __ ReserveAlignedFrameSpace(2 * kWordSize); | 2211 __ ReserveAlignedFrameSpace(2 * kWordSize); |
2212 __ movl(Address(ESP, 1 * kWordSize), left); | 2212 __ movl(Address(ESP, 1 * kWordSize), left); |
2213 __ movl(Address(ESP, 0 * kWordSize), right); | 2213 __ movl(Address(ESP, 0 * kWordSize), right); |
2214 __ CallRuntime(kBigintCompareRuntimeEntry); | 2214 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
2215 // Result in EAX, 0 means equal. | 2215 // Result in EAX, 0 means equal. |
2216 __ LeaveFrame(); | 2216 __ LeaveFrame(); |
2217 __ cmpl(EAX, Immediate(0)); | 2217 __ cmpl(EAX, Immediate(0)); |
2218 __ jmp(&done); | 2218 __ jmp(&done); |
2219 | 2219 |
2220 __ Bind(&reference_compare); | 2220 __ Bind(&reference_compare); |
2221 __ cmpl(left, right); | 2221 __ cmpl(left, right); |
2222 __ Bind(&done); | 2222 __ Bind(&done); |
2223 } | 2223 } |
2224 | 2224 |
2225 | 2225 |
2226 // Called only from unoptimized code. All relevant registers have been saved. | 2226 // Called only from unoptimized code. All relevant registers have been saved. |
2227 // TOS + 0: return address | 2227 // TOS + 0: return address |
2228 // TOS + 1: right argument. | 2228 // TOS + 1: right argument. |
2229 // TOS + 2: left argument. | 2229 // TOS + 2: left argument. |
2230 // Returns ZF set. | 2230 // Returns ZF set. |
2231 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2231 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
2232 Assembler* assembler) { | 2232 Assembler* assembler) { |
2233 // Check single stepping. | 2233 // Check single stepping. |
2234 Label not_stepping; | 2234 Label not_stepping; |
2235 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 2235 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
2236 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 2236 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
2237 __ cmpl(EAX, Immediate(0)); | 2237 __ cmpl(EAX, Immediate(0)); |
2238 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 2238 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
2239 | 2239 |
2240 __ EnterStubFrame(); | 2240 __ EnterStubFrame(); |
2241 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 2241 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
2242 __ LeaveFrame(); | 2242 __ LeaveFrame(); |
2243 __ Bind(¬_stepping); | 2243 __ Bind(¬_stepping); |
2244 | 2244 |
2245 const Register left = EAX; | 2245 const Register left = EAX; |
2246 const Register right = EDX; | 2246 const Register right = EDX; |
2247 const Register temp = ECX; | 2247 const Register temp = ECX; |
2248 __ movl(left, Address(ESP, 2 * kWordSize)); | 2248 __ movl(left, Address(ESP, 2 * kWordSize)); |
2249 __ movl(right, Address(ESP, 1 * kWordSize)); | 2249 __ movl(right, Address(ESP, 1 * kWordSize)); |
2250 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2250 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2251 __ ret(); | 2251 __ ret(); |
(...skipping 20 matching lines...) Expand all Loading... |
2272 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2272 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2273 __ popl(temp); | 2273 __ popl(temp); |
2274 __ popl(right); | 2274 __ popl(right); |
2275 __ popl(left); | 2275 __ popl(left); |
2276 __ ret(); | 2276 __ ret(); |
2277 } | 2277 } |
2278 | 2278 |
2279 } // namespace dart | 2279 } // namespace dart |
2280 | 2280 |
2281 #endif // defined TARGET_ARCH_IA32 | 2281 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |