OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1780 if (FLAG_debug_code) { | 1780 if (FLAG_debug_code) { |
1781 Move(kScratchRegister, Smi::FromInt(type)); | 1781 Move(kScratchRegister, Smi::FromInt(type)); |
1782 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); | 1782 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); |
1783 Check(equal, "stack frame types must match"); | 1783 Check(equal, "stack frame types must match"); |
1784 } | 1784 } |
1785 movq(rsp, rbp); | 1785 movq(rsp, rbp); |
1786 pop(rbp); | 1786 pop(rbp); |
1787 } | 1787 } |
1788 | 1788 |
1789 | 1789 |
1790 void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) { | 1790 void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) { |
| 1791 ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG); |
| 1792 |
1791 // Setup the frame structure on the stack. | 1793 // Setup the frame structure on the stack. |
1792 // All constants are relative to the frame pointer of the exit frame. | 1794 // All constants are relative to the frame pointer of the exit frame. |
1793 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); | 1795 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); |
1794 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); | 1796 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); |
1795 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); | 1797 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); |
1796 push(rbp); | 1798 push(rbp); |
1797 movq(rbp, rsp); | 1799 movq(rbp, rsp); |
1798 | 1800 |
1799 // Reserve room for entry stack pointer and push the debug marker. | 1801 // Reserve room for entry stack pointer and push the debug marker. |
1800 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 1802 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); |
1801 push(Immediate(0)); // saved entry sp, patched before call | 1803 push(Immediate(0)); // saved entry sp, patched before call |
1802 if (mode == ExitFrame::MODE_DEBUG) { | 1804 push(Immediate(type == StackFrame::EXIT_DEBUG ? 1 : 0)); |
1803 push(Immediate(0)); | |
1804 } else { | |
1805 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | |
1806 push(kScratchRegister); | |
1807 } | |
1808 | 1805 |
1809 // Save the frame pointer and the context in top. | 1806 // Save the frame pointer and the context in top. |
1810 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | 1807 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); |
1811 ExternalReference context_address(Top::k_context_address); | 1808 ExternalReference context_address(Top::k_context_address); |
1812 movq(r14, rax); // Backup rax before we use it. | 1809 movq(r14, rax); // Backup rax before we use it. |
1813 | 1810 |
1814 movq(rax, rbp); | 1811 movq(rax, rbp); |
1815 store_rax(c_entry_fp_address); | 1812 store_rax(c_entry_fp_address); |
1816 movq(rax, rsi); | 1813 movq(rax, rsi); |
1817 store_rax(context_address); | 1814 store_rax(context_address); |
1818 | 1815 |
1819 // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame, | 1816 // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame, |
1820 // so it must be retained across the C-call. | 1817 // so it must be retained across the C-call. |
1821 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 1818 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
1822 lea(r15, Operand(rbp, r14, times_pointer_size, offset)); | 1819 lea(r15, Operand(rbp, r14, times_pointer_size, offset)); |
1823 | 1820 |
1824 #ifdef ENABLE_DEBUGGER_SUPPORT | 1821 #ifdef ENABLE_DEBUGGER_SUPPORT |
1825 // Save the state of all registers to the stack from the memory | 1822 // Save the state of all registers to the stack from the memory |
1826 // location. This is needed to allow nested break points. | 1823 // location. This is needed to allow nested break points. |
1827 if (mode == ExitFrame::MODE_DEBUG) { | 1824 if (type == StackFrame::EXIT_DEBUG) { |
1828 // TODO(1243899): This should be symmetric to | 1825 // TODO(1243899): This should be symmetric to |
1829 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed | 1826 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed |
1830 // correct here, but computed for the other call. Very error | 1827 // correct here, but computed for the other call. Very error |
1831 // prone! FIX THIS. Actually there are deeper problems with | 1828 // prone! FIX THIS. Actually there are deeper problems with |
1832 // register saving than this asymmetry (see the bug report | 1829 // register saving than this asymmetry (see the bug report |
1833 // associated with this issue). | 1830 // associated with this issue). |
1834 PushRegistersFromMemory(kJSCallerSaved); | 1831 PushRegistersFromMemory(kJSCallerSaved); |
1835 } | 1832 } |
1836 #endif | 1833 #endif |
1837 | 1834 |
(...skipping 18 matching lines...) Expand all Loading... |
1856 ASSERT(IsPowerOf2(kFrameAlignment)); | 1853 ASSERT(IsPowerOf2(kFrameAlignment)); |
1857 movq(kScratchRegister, Immediate(-kFrameAlignment)); | 1854 movq(kScratchRegister, Immediate(-kFrameAlignment)); |
1858 and_(rsp, kScratchRegister); | 1855 and_(rsp, kScratchRegister); |
1859 } | 1856 } |
1860 | 1857 |
1861 // Patch the saved entry sp. | 1858 // Patch the saved entry sp. |
1862 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); | 1859 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); |
1863 } | 1860 } |
1864 | 1861 |
1865 | 1862 |
1866 void MacroAssembler::LeaveExitFrame(ExitFrame::Mode mode, int result_size) { | 1863 void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) { |
1867 // Registers: | 1864 // Registers: |
1868 // r15 : argv | 1865 // r15 : argv |
1869 #ifdef ENABLE_DEBUGGER_SUPPORT | 1866 #ifdef ENABLE_DEBUGGER_SUPPORT |
1870 // Restore the memory copy of the registers by digging them out from | 1867 // Restore the memory copy of the registers by digging them out from |
1871 // the stack. This is needed to allow nested break points. | 1868 // the stack. This is needed to allow nested break points. |
1872 if (mode == ExitFrame::MODE_DEBUG) { | 1869 if (type == StackFrame::EXIT_DEBUG) { |
1873 // It's okay to clobber register rbx below because we don't need | 1870 // It's okay to clobber register rbx below because we don't need |
1874 // the function pointer after this. | 1871 // the function pointer after this. |
1875 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | 1872 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; |
1876 int kOffset = ExitFrameConstants::kCodeOffset - kCallerSavedSize; | 1873 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; |
1877 lea(rbx, Operand(rbp, kOffset)); | 1874 lea(rbx, Operand(rbp, kOffset)); |
1878 CopyRegistersFromStackToMemory(rbx, rcx, kJSCallerSaved); | 1875 CopyRegistersFromStackToMemory(rbx, rcx, kJSCallerSaved); |
1879 } | 1876 } |
1880 #endif | 1877 #endif |
1881 | 1878 |
1882 // Get the return address from the stack and restore the frame pointer. | 1879 // Get the return address from the stack and restore the frame pointer. |
1883 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 1880 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
1884 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 1881 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
1885 | 1882 |
1886 // Pop everything up to and including the arguments and the receiver | 1883 // Pop everything up to and including the arguments and the receiver |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2241 CodePatcher::~CodePatcher() { | 2238 CodePatcher::~CodePatcher() { |
2242 // Indicate that code has changed. | 2239 // Indicate that code has changed. |
2243 CPU::FlushICache(address_, size_); | 2240 CPU::FlushICache(address_, size_); |
2244 | 2241 |
2245 // Check that the code was patched as expected. | 2242 // Check that the code was patched as expected. |
2246 ASSERT(masm_.pc_ == address_ + size_); | 2243 ASSERT(masm_.pc_ == address_ + size_); |
2247 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2244 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2248 } | 2245 } |
2249 | 2246 |
2250 } } // namespace v8::internal | 2247 } } // namespace v8::internal |
OLD | NEW |