OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 491 |
492 | 492 |
493 static int Offset(ExternalReference ref0, ExternalReference ref1) { | 493 static int Offset(ExternalReference ref0, ExternalReference ref1) { |
494 int64_t offset = (ref0.address() - ref1.address()); | 494 int64_t offset = (ref0.address() - ref1.address()); |
495 // Check that fits into int. | 495 // Check that fits into int. |
496 ASSERT(static_cast<int>(offset) == offset); | 496 ASSERT(static_cast<int>(offset) == offset); |
497 return static_cast<int>(offset); | 497 return static_cast<int>(offset); |
498 } | 498 } |
499 | 499 |
500 | 500 |
501 void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) { | 501 void MacroAssembler::PrepareCallApiFunction(int stack_space, |
| 502 int arg_stack_space) { |
502 #ifdef _WIN64 | 503 #ifdef _WIN64 |
503 // We need to prepare a slot for result handle on stack and put | 504 // We need to prepare a slot for result handle on stack and put |
504 // a pointer to it into 1st arg register. | 505 // a pointer to it into 1st arg register. |
505 int register_based_args = argc > 3 ? 3 : argc; | 506 EnterApiExitFrame(stack_space, arg_stack_space + 1); |
506 EnterApiExitFrame(stack_space, argc - register_based_args + 1); | |
507 | 507 |
508 int return_value_slot = (argc > 3 ? argc - 3 + 1 : 4); | |
509 // rcx must be used to pass the pointer to the return value slot. | 508 // rcx must be used to pass the pointer to the return value slot. |
510 lea(rcx, Operand(rsp, return_value_slot * kPointerSize)); | 509 lea(rcx, StackSpaceOperand(arg_stack_space)); |
511 #else | 510 #else |
512 EnterApiExitFrame(stack_space, argc); | 511 EnterApiExitFrame(stack_space, arg_stack_space); |
513 #endif | 512 #endif |
514 } | 513 } |
515 | 514 |
516 | 515 |
517 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( | 516 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( |
518 ApiFunction* function) { | 517 ApiFunction* function) { |
519 Label empty_result; | 518 Label empty_result; |
520 Label prologue; | 519 Label prologue; |
521 Label promote_scheduled_exception; | 520 Label promote_scheduled_exception; |
522 Label delete_allocated_handles; | 521 Label delete_allocated_handles; |
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 if (save_rax) { | 1736 if (save_rax) { |
1738 movq(r14, rax); // Backup rax before we use it. | 1737 movq(r14, rax); // Backup rax before we use it. |
1739 } | 1738 } |
1740 | 1739 |
1741 movq(rax, rbp); | 1740 movq(rax, rbp); |
1742 store_rax(c_entry_fp_address); | 1741 store_rax(c_entry_fp_address); |
1743 movq(rax, rsi); | 1742 movq(rax, rsi); |
1744 store_rax(context_address); | 1743 store_rax(context_address); |
1745 } | 1744 } |
1746 | 1745 |
1747 void MacroAssembler::EnterExitFrameEpilogue(int result_size, | 1746 |
1748 int argc) { | 1747 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space) { |
1749 #ifdef _WIN64 | 1748 #ifdef _WIN64 |
1750 // Reserve space on stack for result and argument structures, if necessary. | 1749 const int kShaddowSpace = 4; |
1751 int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize; | 1750 arg_stack_space += kShaddowSpace; |
1752 // Reserve space for the Arguments object. The Windows 64-bit ABI | |
1753 // requires us to pass this structure as a pointer to its location on | |
1754 // the stack. The structure contains 2 values. | |
1755 int argument_stack_space = argc * kPointerSize; | |
1756 // We also need backing space for 4 parameters, even though | |
1757 // we only pass one or two parameter, and it is in a register. | |
1758 int argument_mirror_space = 4 * kPointerSize; | |
1759 int total_stack_space = | |
1760 argument_mirror_space + argument_stack_space + result_stack_space; | |
1761 subq(rsp, Immediate(total_stack_space)); | |
1762 #endif | 1751 #endif |
| 1752 if (arg_stack_space > 0) { |
| 1753 subq(rsp, Immediate(arg_stack_space * kPointerSize)); |
| 1754 } |
1763 | 1755 |
1764 // Get the required frame alignment for the OS. | 1756 // Get the required frame alignment for the OS. |
1765 static const int kFrameAlignment = OS::ActivationFrameAlignment(); | 1757 static const int kFrameAlignment = OS::ActivationFrameAlignment(); |
1766 if (kFrameAlignment > 0) { | 1758 if (kFrameAlignment > 0) { |
1767 ASSERT(IsPowerOf2(kFrameAlignment)); | 1759 ASSERT(IsPowerOf2(kFrameAlignment)); |
1768 movq(kScratchRegister, Immediate(-kFrameAlignment)); | 1760 movq(kScratchRegister, Immediate(-kFrameAlignment)); |
1769 and_(rsp, kScratchRegister); | 1761 and_(rsp, kScratchRegister); |
1770 } | 1762 } |
1771 | 1763 |
1772 // Patch the saved entry sp. | 1764 // Patch the saved entry sp. |
1773 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); | 1765 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); |
1774 } | 1766 } |
1775 | 1767 |
1776 | 1768 |
1777 void MacroAssembler::EnterExitFrame(int result_size) { | 1769 void MacroAssembler::EnterExitFrame(int arg_stack_space) { |
1778 EnterExitFramePrologue(true); | 1770 EnterExitFramePrologue(true); |
1779 | 1771 |
1780 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, | 1772 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, |
1781 // so it must be retained across the C-call. | 1773 // so it must be retained across the C-call. |
1782 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 1774 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
1783 lea(r12, Operand(rbp, r14, times_pointer_size, offset)); | 1775 lea(r12, Operand(rbp, r14, times_pointer_size, offset)); |
1784 | 1776 |
1785 EnterExitFrameEpilogue(result_size, 2); | 1777 EnterExitFrameEpilogue(arg_stack_space); |
1786 } | 1778 } |
1787 | 1779 |
1788 | 1780 |
1789 void MacroAssembler::EnterApiExitFrame(int stack_space, | 1781 void MacroAssembler::EnterApiExitFrame(int stack_space, |
1790 int argc, | 1782 int arg_stack_space) { |
1791 int result_size) { | |
1792 EnterExitFramePrologue(false); | 1783 EnterExitFramePrologue(false); |
1793 | 1784 |
1794 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, | 1785 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, |
1795 // so it must be retained across the C-call. | 1786 // so it must be retained across the C-call. |
1796 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 1787 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
1797 lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset)); | 1788 lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset)); |
1798 | 1789 |
1799 #ifndef _WIN64 | 1790 EnterExitFrameEpilogue(arg_stack_space); |
1800 ASSERT(argc <= 6); // EnterApiExitFrame supports only register based args. | |
1801 #endif | |
1802 | |
1803 EnterExitFrameEpilogue(result_size, argc); | |
1804 } | 1791 } |
1805 | 1792 |
1806 | 1793 |
1807 void MacroAssembler::LeaveExitFrame(int result_size) { | 1794 void MacroAssembler::LeaveExitFrame(int result_size) { |
1808 // Registers: | 1795 // Registers: |
1809 // r12 : argv | 1796 // r12 : argv |
1810 | 1797 |
1811 // Get the return address from the stack and restore the frame pointer. | 1798 // Get the return address from the stack and restore the frame pointer. |
1812 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 1799 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
1813 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 1800 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 CPU::FlushICache(address_, size_); | 2325 CPU::FlushICache(address_, size_); |
2339 | 2326 |
2340 // Check that the code was patched as expected. | 2327 // Check that the code was patched as expected. |
2341 ASSERT(masm_.pc_ == address_ + size_); | 2328 ASSERT(masm_.pc_ == address_ + size_); |
2342 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2329 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2343 } | 2330 } |
2344 | 2331 |
2345 } } // namespace v8::internal | 2332 } } // namespace v8::internal |
2346 | 2333 |
2347 #endif // V8_TARGET_ARCH_X64 | 2334 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |