Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(897)

Side by Side Diff: runtime/vm/stub_code_x64.cc

Issue 317773002: Fix Win64 build of Dart VM. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stack_frame_x64.h ('k') | runtime/vm/stub_code_x64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/stack_frame_x64.h ('k') | runtime/vm/stub_code_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698