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_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 | 81 |
82 // Pass NativeArguments structure by value and call runtime. | 82 // Pass NativeArguments structure by value and call runtime. |
83 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. | 83 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. |
84 // There are no runtime calls to closures, so we do not need to set the tag | 84 // There are no runtime calls to closures, so we do not need to set the tag |
85 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 85 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
86 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 86 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
87 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv. | 87 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv. |
88 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 88 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
89 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. | 89 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. |
90 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 90 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
91 __ call(RBX); | 91 #if defined(_WIN64) |
| 92 ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit); |
| 93 __ movq(CallingConventions::kArg1Reg, RSP); |
| 94 #endif |
| 95 __ CallCFunction(RBX); |
92 | 96 |
93 // Mark that the isolate is executing Dart code. | 97 // Mark that the isolate is executing Dart code. |
94 __ movq(Address(CTX, Isolate::vm_tag_offset()), | 98 __ movq(Address(CTX, Isolate::vm_tag_offset()), |
95 Immediate(VMTag::kScriptTagId)); | 99 Immediate(VMTag::kScriptTagId)); |
96 | 100 |
97 // Reset exit frame information in Isolate structure. | 101 // Reset exit frame information in Isolate structure. |
98 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 102 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
99 | 103 |
100 // Load Context pointer from Isolate structure into RBX. | 104 // Load Context pointer from Isolate structure into RBX. |
101 __ movq(RBX, Address(CTX, Isolate::top_context_offset())); | 105 __ movq(RBX, Address(CTX, Isolate::top_context_offset())); |
(...skipping 17 matching lines...) Expand all Loading... |
119 END_LEAF_RUNTIME_ENTRY | 123 END_LEAF_RUNTIME_ENTRY |
120 | 124 |
121 | 125 |
122 // Input parameters: | 126 // Input parameters: |
123 // RSP : points to return address. | 127 // RSP : points to return address. |
124 // RDI : stop message (const char*). | 128 // RDI : stop message (const char*). |
125 // Must preserve all registers. | 129 // Must preserve all registers. |
126 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 130 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
127 __ EnterCallRuntimeFrame(0); | 131 __ EnterCallRuntimeFrame(0); |
128 // Call the runtime leaf function. RDI already contains the parameter. | 132 // Call the runtime leaf function. RDI already contains the parameter. |
| 133 #if defined(_WIN64) |
| 134 __ movq(CallingConventions::kArg1Reg, RDI); |
| 135 #endif |
129 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); | 136 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); |
130 __ LeaveCallRuntimeFrame(); | 137 __ LeaveCallRuntimeFrame(); |
131 __ ret(); | 138 __ ret(); |
132 } | 139 } |
133 | 140 |
134 | 141 |
135 // Input parameters: | 142 // Input parameters: |
136 // RSP : points to return address. | 143 // RSP : points to return address. |
137 // RSP + 8 : address of return value. | 144 // RSP + 8 : address of return value. |
138 // RAX : address of first argument in argument array. | 145 // RAX : address of first argument in argument array. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 if (OS::ActivationFrameAlignment() > 1) { | 192 if (OS::ActivationFrameAlignment() > 1) { |
186 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 193 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
187 } | 194 } |
188 | 195 |
189 // Pass NativeArguments structure by value and call native function. | 196 // Pass NativeArguments structure by value and call native function. |
190 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. | 197 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. |
191 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 198 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
192 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 199 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
193 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. | 200 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. |
194 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 201 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
195 __ movq(RDI, RSP); // Pass the pointer to the NativeArguments. | 202 |
| 203 // Pass the pointer to the NativeArguments. |
| 204 __ movq(CallingConventions::kArg1Reg, RSP); |
196 | 205 |
197 // Call native function (setsup scope if not leaf function). | 206 // Call native function (setsup scope if not leaf function). |
198 Label leaf_call; | 207 Label leaf_call; |
199 Label done; | 208 Label done; |
200 __ testq(R10, Immediate(NativeArguments::AutoSetupScopeMask())); | 209 __ testq(R10, Immediate(NativeArguments::AutoSetupScopeMask())); |
201 __ j(ZERO, &leaf_call); | 210 __ j(ZERO, &leaf_call); |
202 __ movq(RSI, RBX); // Pass pointer to function entrypoint. | 211 // Pass pointer to function entrypoint. |
203 __ call(&NativeEntry::NativeCallWrapperLabel()); | 212 __ movq(CallingConventions::kArg2Reg, RBX); |
| 213 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); |
204 __ jmp(&done); | 214 __ jmp(&done); |
205 __ Bind(&leaf_call); | 215 __ Bind(&leaf_call); |
206 __ call(RBX); | 216 __ CallCFunction(RBX); |
207 __ Bind(&done); | 217 __ Bind(&done); |
208 | 218 |
209 // Mark that the isolate is executing Dart code. | 219 // Mark that the isolate is executing Dart code. |
210 __ movq(Address(CTX, Isolate::vm_tag_offset()), | 220 __ movq(Address(CTX, Isolate::vm_tag_offset()), |
211 Immediate(VMTag::kScriptTagId)); | 221 Immediate(VMTag::kScriptTagId)); |
212 | 222 |
213 // Reset exit frame information in Isolate structure. | 223 // Reset exit frame information in Isolate structure. |
214 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 224 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
215 | 225 |
216 // Load Context pointer from Isolate structure into R8. | 226 // Load Context pointer from Isolate structure into R8. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 if (OS::ActivationFrameAlignment() > 1) { | 291 if (OS::ActivationFrameAlignment() > 1) { |
282 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 292 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
283 } | 293 } |
284 | 294 |
285 // Pass NativeArguments structure by value and call native function. | 295 // Pass NativeArguments structure by value and call native function. |
286 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. | 296 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs. |
287 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 297 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
288 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 298 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
289 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. | 299 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. |
290 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 300 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
291 __ movq(RDI, RSP); // Pass the pointer to the NativeArguments. | 301 |
292 __ call(RBX); | 302 // Pass the pointer to the NativeArguments. |
| 303 __ movq(CallingConventions::kArg1Reg, RSP); |
| 304 __ CallCFunction(RBX); |
293 | 305 |
294 // Mark that the isolate is executing Dart code. | 306 // Mark that the isolate is executing Dart code. |
295 __ movq(Address(CTX, Isolate::vm_tag_offset()), | 307 __ movq(Address(CTX, Isolate::vm_tag_offset()), |
296 Immediate(VMTag::kScriptTagId)); | 308 Immediate(VMTag::kScriptTagId)); |
297 | 309 |
298 // Reset exit frame information in Isolate structure. | 310 // Reset exit frame information in Isolate structure. |
299 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 311 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
300 | 312 |
301 // Load Context pointer from Isolate structure into R8. | 313 // Load Context pointer from Isolate structure into R8. |
302 __ movq(R8, Address(CTX, Isolate::top_context_offset())); | 314 __ movq(R8, Address(CTX, Isolate::top_context_offset())); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 __ pushq(static_cast<Register>(i)); | 443 __ pushq(static_cast<Register>(i)); |
432 } | 444 } |
433 __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); | 445 __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); |
434 intptr_t offset = 0; | 446 intptr_t offset = 0; |
435 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 447 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
436 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 448 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
437 __ movups(Address(RSP, offset), xmm_reg); | 449 __ movups(Address(RSP, offset), xmm_reg); |
438 offset += kFpuRegisterSize; | 450 offset += kFpuRegisterSize; |
439 } | 451 } |
440 | 452 |
441 __ movq(RDI, RSP); // Pass address of saved registers block. | 453 // Pass address of saved registers block. |
442 __ ReserveAlignedFrameSpace(0); | 454 __ movq(CallingConventions::kArg1Reg, RSP); |
| 455 __ ReserveAlignedFrameSpace(0); // Ensure stack is aligned before the call. |
443 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); | 456 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); |
444 // Result (RAX) is stack-size (FP - SP) in bytes. | 457 // Result (RAX) is stack-size (FP - SP) in bytes. |
445 | 458 |
446 if (preserve_result) { | 459 if (preserve_result) { |
447 // Restore result into RBX temporarily. | 460 // Restore result into RBX temporarily. |
448 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize)); | 461 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize)); |
449 } | 462 } |
450 | 463 |
451 // There is a Dart Frame on the stack. We must restore PP and leave frame. | 464 // There is a Dart Frame on the stack. We must restore PP and leave frame. |
452 __ LeaveDartFrame(); | 465 __ LeaveDartFrame(); |
453 | 466 |
454 __ popq(RCX); // Preserve return address. | 467 __ popq(RCX); // Preserve return address. |
455 __ movq(RSP, RBP); // Discard optimized frame. | 468 __ movq(RSP, RBP); // Discard optimized frame. |
456 __ subq(RSP, RAX); // Reserve space for deoptimized frame. | 469 __ subq(RSP, RAX); // Reserve space for deoptimized frame. |
457 __ pushq(RCX); // Restore return address. | 470 __ pushq(RCX); // Restore return address. |
458 | 471 |
459 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there | 472 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
460 // is no need to set the correct PC marker or load PP, since they get patched. | 473 // is no need to set the correct PC marker or load PP, since they get patched. |
461 __ EnterFrame(0); | 474 __ EnterFrame(0); |
462 __ pushq(Immediate(0)); | 475 __ pushq(Immediate(0)); |
463 __ pushq(PP); | 476 __ pushq(PP); |
464 | 477 |
465 if (preserve_result) { | 478 if (preserve_result) { |
466 __ pushq(RBX); // Preserve result as first local. | 479 __ pushq(RBX); // Preserve result as first local. |
467 } | 480 } |
468 __ ReserveAlignedFrameSpace(0); | 481 __ ReserveAlignedFrameSpace(0); |
469 __ movq(RDI, RBP); // Pass last FP as parameter in RDI. | 482 // Pass last FP as a parameter. |
| 483 __ movq(CallingConventions::kArg1Reg, RBP); |
470 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); | 484 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); |
471 if (preserve_result) { | 485 if (preserve_result) { |
472 // Restore result into RBX. | 486 // Restore result into RBX. |
473 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); | 487 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); |
474 } | 488 } |
475 // Code above cannot cause GC. | 489 // Code above cannot cause GC. |
476 // There is a Dart Frame on the stack. We must restore PP and leave frame. | 490 // There is a Dart Frame on the stack. We must restore PP and leave frame. |
477 __ LeaveDartFrame(); | 491 __ LeaveDartFrame(); |
478 | 492 |
479 // Frame is fully rewritten at this point and it is safe to perform a GC. | 493 // Frame is fully rewritten at this point and it is safe to perform a GC. |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 // Input parameters: | 692 // Input parameters: |
679 // RSP : points to return address. | 693 // RSP : points to return address. |
680 // RDI : entrypoint of the Dart function to call. | 694 // RDI : entrypoint of the Dart function to call. |
681 // RSI : arguments descriptor array. | 695 // RSI : arguments descriptor array. |
682 // RDX : arguments array. | 696 // RDX : arguments array. |
683 // RCX : new context containing the current isolate pointer. | 697 // RCX : new context containing the current isolate pointer. |
684 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 698 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
685 // Save frame pointer coming in. | 699 // Save frame pointer coming in. |
686 __ EnterFrame(0); | 700 __ EnterFrame(0); |
687 | 701 |
| 702 const Register kEntryPointReg = CallingConventions::kArg1Reg; |
| 703 const Register kArgDescReg = CallingConventions::kArg2Reg; |
| 704 const Register kArgsReg = CallingConventions::kArg3Reg; |
| 705 const Register kNewContextReg = CallingConventions::kArg4Reg; |
| 706 |
688 // At this point, the stack looks like: | 707 // At this point, the stack looks like: |
689 // | saved RBP | <-- RBP | 708 // | saved RBP | <-- RBP |
690 // | saved PC (return to DartEntry::InvokeFunction) | | 709 // | saved PC (return to DartEntry::InvokeFunction) | |
691 | 710 |
692 const intptr_t kInitialOffset = 1; | 711 const intptr_t kInitialOffset = 1; |
693 // Save arguments descriptor array and new context. | 712 // Save arguments descriptor array and new context. |
694 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; | 713 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; |
695 __ pushq(RSI); | 714 __ pushq(kArgDescReg); |
696 const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize; | 715 const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize; |
697 __ pushq(RCX); | 716 __ pushq(kNewContextReg); |
698 | 717 |
699 // Save C++ ABI callee-saved registers. | 718 // Save C++ ABI callee-saved registers. |
700 __ pushq(RBX); | 719 __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters, |
701 __ pushq(R12); | 720 CallingConventions::kCalleeSaveXmmRegisters); |
702 __ pushq(R13); | |
703 __ pushq(R14); | |
704 __ pushq(R15); | |
705 | 721 |
706 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 722 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
707 // could potentially invoke some intrinsic functions which need the PP to be | 723 // could potentially invoke some intrinsic functions which need the PP to be |
708 // set up. | 724 // set up. |
709 __ LoadPoolPointer(PP); | 725 __ LoadPoolPointer(PP); |
710 | 726 |
711 // If any additional (or fewer) values are pushed, the offsets in | 727 // If any additional (or fewer) values are pushed, the offsets in |
712 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be | 728 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be |
713 // changed. | 729 // changed. |
714 | 730 |
715 // The new Context structure contains a pointer to the current Isolate | 731 // The new Context structure contains a pointer to the current Isolate |
716 // structure. Cache the Context pointer in the CTX register so that it is | 732 // structure. Cache the Context pointer in the CTX register so that it is |
717 // available in generated code and calls to Isolate::Current() need not be | 733 // available in generated code and calls to Isolate::Current() need not be |
718 // done. The assumption is that this register will never be clobbered by | 734 // done. The assumption is that this register will never be clobbered by |
719 // compiled or runtime stub code. | 735 // compiled or runtime stub code. |
720 | 736 |
721 // Cache the new Context pointer into CTX while executing Dart code. | 737 // Cache the new Context pointer into CTX while executing Dart code. |
722 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle)); | 738 __ movq(CTX, Address(kNewContextReg, VMHandles::kOffsetOfRawPtrInHandle)); |
| 739 |
| 740 const Register kIsolateReg = RBX; |
723 | 741 |
724 // Load Isolate pointer from Context structure into R8. | 742 // Load Isolate pointer from Context structure into R8. |
725 __ movq(R8, FieldAddress(CTX, Context::isolate_offset())); | 743 __ movq(kIsolateReg, FieldAddress(CTX, Context::isolate_offset())); |
726 | 744 |
727 // Save the current VMTag on the stack. | 745 // Save the current VMTag on the stack. |
728 ASSERT(kSavedVMTagSlotFromEntryFp == -8); | 746 __ movq(RAX, Address(kIsolateReg, Isolate::vm_tag_offset())); |
729 __ movq(RAX, Address(R8, Isolate::vm_tag_offset())); | |
730 __ pushq(RAX); | 747 __ pushq(RAX); |
| 748 #if defined(DEBUG) |
| 749 { |
| 750 Label ok; |
| 751 __ leaq(RAX, Address(RBP, kSavedVMTagSlotFromEntryFp * kWordSize)); |
| 752 __ cmpq(RAX, RSP); |
| 753 __ j(EQUAL, &ok); |
| 754 __ Stop("kSavedVMTagSlotFromEntryFp mismatch"); |
| 755 __ Bind(&ok); |
| 756 } |
| 757 #endif |
731 | 758 |
732 // Mark that the isolate is executing Dart code. | 759 // Mark that the isolate is executing Dart code. |
733 __ movq(Address(R8, Isolate::vm_tag_offset()), | 760 __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()), |
734 Immediate(VMTag::kScriptTagId)); | 761 Immediate(VMTag::kScriptTagId)); |
735 | 762 |
736 // Save the top exit frame info. Use RAX as a temporary register. | 763 // Save the top exit frame info. Use RAX as a temporary register. |
737 // StackFrameIterator reads the top exit frame info saved in this frame. | 764 // StackFrameIterator reads the top exit frame info saved in this frame. |
738 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the | 765 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the |
739 // code below. | 766 // code below. |
740 ASSERT(kExitLinkSlotFromEntryFp == -9); | 767 __ movq(RAX, Address(kIsolateReg, Isolate::top_exit_frame_info_offset())); |
741 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset())); | |
742 __ pushq(RAX); | 768 __ pushq(RAX); |
743 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 769 #if defined(DEBUG) |
| 770 { |
| 771 Label ok; |
| 772 __ leaq(RAX, Address(RBP, kExitLinkSlotFromEntryFp * kWordSize)); |
| 773 __ cmpq(RAX, RSP); |
| 774 __ j(EQUAL, &ok); |
| 775 __ Stop("kExitLinkSlotFromEntryFp mismatch"); |
| 776 __ Bind(&ok); |
| 777 } |
| 778 #endif |
| 779 |
| 780 __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()), |
| 781 Immediate(0)); |
744 | 782 |
745 // Save the old Context pointer. Use RAX as a temporary register. | 783 // Save the old Context pointer. Use RAX as a temporary register. |
746 // Note that VisitObjectPointers will find this saved Context pointer during | 784 // Note that VisitObjectPointers will find this saved Context pointer during |
747 // GC marking, since it traverses any information between SP and | 785 // GC marking, since it traverses any information between SP and |
748 // FP - kExitLinkSlotFromEntryFp * kWordSize. | 786 // FP - kExitLinkSlotFromEntryFp * kWordSize. |
749 // EntryFrame::SavedContext reads the context saved in this frame. | 787 // EntryFrame::SavedContext reads the context saved in this frame. |
750 // The constant kSavedContextSlotFromEntryFp must be kept in sync with | 788 // The constant kSavedContextSlotFromEntryFp must be kept in sync with |
751 // the code below. | 789 // the code below. |
752 ASSERT(kSavedContextSlotFromEntryFp == -10); | 790 __ movq(RAX, Address(kIsolateReg, Isolate::top_context_offset())); |
753 __ movq(RAX, Address(R8, Isolate::top_context_offset())); | |
754 __ pushq(RAX); | 791 __ pushq(RAX); |
| 792 #if defined(DEBUG) |
| 793 { |
| 794 Label ok; |
| 795 __ leaq(RAX, Address(RBP, kSavedContextSlotFromEntryFp * kWordSize)); |
| 796 __ cmpq(RAX, RSP); |
| 797 __ j(EQUAL, &ok); |
| 798 __ Stop("kSavedContextSlotFromEntryFp mismatch"); |
| 799 __ Bind(&ok); |
| 800 } |
| 801 #endif |
755 | 802 |
756 // Load arguments descriptor array into R10, which is passed to Dart code. | 803 // Load arguments descriptor array into R10, which is passed to Dart code. |
757 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle)); | 804 __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); |
| 805 |
| 806 // Push arguments. At this point we only need to preserve kEntryPointReg. |
| 807 ASSERT(kEntryPointReg != RDX); |
758 | 808 |
759 // Load number of arguments into RBX. | 809 // Load number of arguments into RBX. |
760 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 810 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
761 __ SmiUntag(RBX); | 811 __ SmiUntag(RBX); |
762 | 812 |
763 // Compute address of 'arguments array' data area into RDX. | 813 // Compute address of 'arguments array' data area into RDX. |
764 __ movq(RDX, Address(RDX, VMHandles::kOffsetOfRawPtrInHandle)); | 814 __ movq(RDX, Address(kArgsReg, VMHandles::kOffsetOfRawPtrInHandle)); |
765 __ leaq(RDX, FieldAddress(RDX, Array::data_offset())); | 815 __ leaq(RDX, FieldAddress(RDX, Array::data_offset())); |
766 | 816 |
767 // Set up arguments for the Dart call. | 817 // Set up arguments for the Dart call. |
768 Label push_arguments; | 818 Label push_arguments; |
769 Label done_push_arguments; | 819 Label done_push_arguments; |
770 __ testq(RBX, RBX); // check if there are arguments. | 820 __ testq(RBX, RBX); // check if there are arguments. |
771 __ j(ZERO, &done_push_arguments, Assembler::kNearJump); | 821 __ j(ZERO, &done_push_arguments, Assembler::kNearJump); |
772 __ movq(RAX, Immediate(0)); | 822 __ movq(RAX, Immediate(0)); |
773 __ Bind(&push_arguments); | 823 __ Bind(&push_arguments); |
774 __ movq(RCX, Address(RDX, RAX, TIMES_8, 0)); // RDX is start of arguments. | 824 __ pushq(Address(RDX, RAX, TIMES_8, 0)); |
775 __ pushq(RCX); | |
776 __ incq(RAX); | 825 __ incq(RAX); |
777 __ cmpq(RAX, RBX); | 826 __ cmpq(RAX, RBX); |
778 __ j(LESS, &push_arguments, Assembler::kNearJump); | 827 __ j(LESS, &push_arguments, Assembler::kNearJump); |
779 __ Bind(&done_push_arguments); | 828 __ Bind(&done_push_arguments); |
780 | 829 |
781 // Call the Dart code entrypoint. | 830 // Call the Dart code entrypoint. |
782 __ call(RDI); // R10 is the arguments descriptor array. | 831 __ call(kEntryPointReg); // R10 is the arguments descriptor array. |
783 | 832 |
784 // Read the saved new Context pointer. | 833 // Restore CTX from the saved context handle. |
785 __ movq(CTX, Address(RBP, kNewContextOffset)); | 834 __ movq(CTX, Address(RBP, kNewContextOffset)); |
786 __ movq(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | 835 __ movq(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
787 | 836 |
788 // Read the saved arguments descriptor array to obtain the number of passed | 837 // Read the saved arguments descriptor array to obtain the number of passed |
789 // arguments. | 838 // arguments. |
790 __ movq(RSI, Address(RBP, kArgumentsDescOffset)); | 839 __ movq(kArgDescReg, Address(RBP, kArgumentsDescOffset)); |
791 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle)); | 840 __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); |
792 __ movq(RDX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 841 __ movq(RDX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
793 // Get rid of arguments pushed on the stack. | 842 // Get rid of arguments pushed on the stack. |
794 __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi. | 843 __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi. |
795 | 844 |
796 // Load Isolate pointer from Context structure into CTX. Drop Context. | 845 // Load Isolate pointer from Context structure into CTX. Drop Context. |
797 __ movq(CTX, FieldAddress(CTX, Context::isolate_offset())); | 846 __ movq(kIsolateReg, FieldAddress(CTX, Context::isolate_offset())); |
798 | 847 |
799 // Restore the saved Context pointer into the Isolate structure. | 848 // Restore the saved Context pointer into the Isolate structure. |
800 // Uses RCX as a temporary register for this. | 849 __ popq(RDX); |
801 __ popq(RCX); | 850 __ movq(Address(kIsolateReg, Isolate::top_context_offset()), RDX); |
802 __ movq(Address(CTX, Isolate::top_context_offset()), RCX); | |
803 | 851 |
804 // Restore the saved top exit frame info back into the Isolate structure. | 852 // Restore the saved top exit frame info back into the Isolate structure. |
805 // Uses RDX as a temporary register for this. | |
806 __ popq(RDX); | 853 __ popq(RDX); |
807 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX); | 854 __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()), RDX); |
808 | 855 |
809 // Restore the current VMTag from the stack. | 856 // Restore the current VMTag from the stack. |
810 __ popq(RDX); | 857 __ popq(RDX); |
811 __ movq(Address(CTX, Isolate::vm_tag_offset()), RDX); | 858 __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()), RDX); |
812 | 859 |
813 // Restore C++ ABI callee-saved registers. | 860 // Restore C++ ABI callee-saved registers. |
814 __ popq(R15); | 861 __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters, |
815 __ popq(R14); | 862 CallingConventions::kCalleeSaveXmmRegisters); |
816 __ popq(R13); | |
817 __ popq(R12); | |
818 __ popq(RBX); | |
819 | 863 |
820 // Restore the frame pointer. | 864 // Restore the frame pointer. |
821 __ LeaveFrame(); | 865 __ LeaveFrame(); |
822 | 866 |
823 __ ret(); | 867 __ ret(); |
824 } | 868 } |
825 | 869 |
826 | 870 |
827 // Called for inline allocation of contexts. | 871 // Called for inline allocation of contexts. |
828 // Input: | 872 // Input: |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 // Restore values. | 1042 // Restore values. |
999 __ popq(RCX); | 1043 __ popq(RCX); |
1000 __ popq(RDX); | 1044 __ popq(RDX); |
1001 __ j(EQUAL, &L, Assembler::kNearJump); | 1045 __ j(EQUAL, &L, Assembler::kNearJump); |
1002 __ ret(); | 1046 __ ret(); |
1003 | 1047 |
1004 // Handle overflow: Call the runtime leaf function. | 1048 // Handle overflow: Call the runtime leaf function. |
1005 __ Bind(&L); | 1049 __ Bind(&L); |
1006 // Setup frame, push callee-saved registers. | 1050 // Setup frame, push callee-saved registers. |
1007 __ EnterCallRuntimeFrame(0); | 1051 __ EnterCallRuntimeFrame(0); |
1008 __ movq(RDI, FieldAddress(CTX, Context::isolate_offset())); | 1052 __ movq(CallingConventions::kArg1Reg, |
| 1053 FieldAddress(CTX, Context::isolate_offset())); |
1009 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); | 1054 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
1010 __ LeaveCallRuntimeFrame(); | 1055 __ LeaveCallRuntimeFrame(); |
1011 __ ret(); | 1056 __ ret(); |
1012 } | 1057 } |
1013 | 1058 |
1014 | 1059 |
1015 // Called for inline allocation of objects. | 1060 // Called for inline allocation of objects. |
1016 // Input parameters: | 1061 // Input parameters: |
1017 // RSP + 8 : type arguments object (only if class is parameterized). | 1062 // RSP + 8 : type arguments object (only if class is parameterized). |
1018 // RSP : points to return address. | 1063 // RSP : points to return address. |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 // TOS + 0: return address | 1705 // TOS + 0: return address |
1661 // Result in RAX. | 1706 // Result in RAX. |
1662 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { | 1707 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { |
1663 __ leaq(RAX, Address(RSP, kWordSize)); | 1708 __ leaq(RAX, Address(RSP, kWordSize)); |
1664 __ ret(); | 1709 __ ret(); |
1665 } | 1710 } |
1666 | 1711 |
1667 | 1712 |
1668 // Jump to the exception or error handler. | 1713 // Jump to the exception or error handler. |
1669 // TOS + 0: return address | 1714 // TOS + 0: return address |
1670 // RDI: program counter | 1715 // Arg1: program counter |
1671 // RSI: stack pointer | 1716 // Arg2: stack pointer |
1672 // RDX: frame_pointer | 1717 // Arg3: frame_pointer |
1673 // RCX: exception object | 1718 // Arg4: exception object |
1674 // R8: stacktrace object | 1719 // Arg5: stacktrace object |
1675 // No Result. | 1720 // No Result. |
1676 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1721 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
1677 ASSERT(kExceptionObjectReg == RAX); | 1722 ASSERT(kExceptionObjectReg == RAX); |
1678 ASSERT(kStackTraceObjectReg == RDX); | 1723 ASSERT(kStackTraceObjectReg == RDX); |
1679 __ movq(RBP, RDX); // target frame pointer. | 1724 ASSERT(CallingConventions::kArg4Reg != kStackTraceObjectReg); |
1680 __ movq(kStackTraceObjectReg, R8); // stacktrace object. | 1725 ASSERT(CallingConventions::kArg1Reg != kStackTraceObjectReg); |
1681 __ movq(kExceptionObjectReg, RCX); // exception object. | 1726 |
1682 __ movq(RSP, RSI); // target stack_pointer. | 1727 #if defined(_WIN64) |
1683 __ jmp(RDI); // Jump to the exception handler code. | 1728 Register stacktrace_reg = RBX; |
| 1729 __ movq(stacktrace_reg, Address(RSP, 5 * kWordSize)); |
| 1730 #else |
| 1731 Register stacktrace_reg = CallingConventions::kArg5Reg; |
| 1732 #endif |
| 1733 |
| 1734 __ movq(RBP, CallingConventions::kArg3Reg); |
| 1735 __ movq(RSP, CallingConventions::kArg2Reg); |
| 1736 __ movq(kStackTraceObjectReg, stacktrace_reg); |
| 1737 __ movq(kExceptionObjectReg, CallingConventions::kArg4Reg); |
| 1738 __ jmp(CallingConventions::kArg1Reg); // Jump to the exception handler code. |
1684 } | 1739 } |
1685 | 1740 |
1686 | 1741 |
1687 // Calls to the runtime to optimize the given function. | 1742 // Calls to the runtime to optimize the given function. |
1688 // RDI: function to be reoptimized. | 1743 // RDI: function to be reoptimized. |
1689 // R10: argument descriptor (preserved). | 1744 // R10: argument descriptor (preserved). |
1690 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1745 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
1691 __ EnterStubFrame(); | 1746 __ EnterStubFrame(); |
1692 __ LoadObject(R12, Object::null_object(), PP); | 1747 __ LoadObject(R12, Object::null_object(), PP); |
1693 __ pushq(R10); | 1748 __ pushq(R10); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1749 __ cmpq(left, FieldAddress(right, Mint::value_offset())); | 1804 __ cmpq(left, FieldAddress(right, Mint::value_offset())); |
1750 __ jmp(&done, Assembler::kNearJump); | 1805 __ jmp(&done, Assembler::kNearJump); |
1751 | 1806 |
1752 __ Bind(&check_bigint); | 1807 __ Bind(&check_bigint); |
1753 __ CompareClassId(left, kBigintCid); | 1808 __ CompareClassId(left, kBigintCid); |
1754 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); | 1809 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
1755 __ CompareClassId(right, kBigintCid); | 1810 __ CompareClassId(right, kBigintCid); |
1756 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 1811 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
1757 __ EnterFrame(0); | 1812 __ EnterFrame(0); |
1758 __ ReserveAlignedFrameSpace(0); | 1813 __ ReserveAlignedFrameSpace(0); |
1759 __ movq(RDI, left); | 1814 __ movq(CallingConventions::kArg1Reg, left); |
1760 __ movq(RSI, right); | 1815 __ movq(CallingConventions::kArg2Reg, right); |
1761 __ CallRuntime(kBigintCompareRuntimeEntry, 2); | 1816 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
1762 // Result in RAX, 0 means equal. | 1817 // Result in RAX, 0 means equal. |
1763 __ LeaveFrame(); | 1818 __ LeaveFrame(); |
1764 __ cmpq(RAX, Immediate(0)); | 1819 __ cmpq(RAX, Immediate(0)); |
1765 __ jmp(&done); | 1820 __ jmp(&done); |
1766 | 1821 |
1767 __ Bind(&reference_compare); | 1822 __ Bind(&reference_compare); |
1768 __ cmpq(left, right); | 1823 __ cmpq(left, right); |
1769 __ Bind(&done); | 1824 __ Bind(&done); |
1770 } | 1825 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 | 1867 |
1813 __ movq(left, Address(RSP, 2 * kWordSize)); | 1868 __ movq(left, Address(RSP, 2 * kWordSize)); |
1814 __ movq(right, Address(RSP, 1 * kWordSize)); | 1869 __ movq(right, Address(RSP, 1 * kWordSize)); |
1815 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 1870 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
1816 __ ret(); | 1871 __ ret(); |
1817 } | 1872 } |
1818 | 1873 |
1819 } // namespace dart | 1874 } // namespace dart |
1820 | 1875 |
1821 #endif // defined TARGET_ARCH_X64 | 1876 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |