| 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 |