| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 return change; | 1692 return change; |
| 1693 } | 1693 } |
| 1694 | 1694 |
| 1695 | 1695 |
| 1696 // Removes specified range of frames from stack. There may be 1 or more | 1696 // Removes specified range of frames from stack. There may be 1 or more |
| 1697 // frames in range. Anyway the bottom frame is restarted rather than dropped, | 1697 // frames in range. Anyway the bottom frame is restarted rather than dropped, |
| 1698 // and therefore has to be a JavaScript frame. | 1698 // and therefore has to be a JavaScript frame. |
| 1699 // Returns error message or NULL. | 1699 // Returns error message or NULL. |
| 1700 static const char* DropFrames(Vector<StackFrame*> frames, | 1700 static const char* DropFrames(Vector<StackFrame*> frames, |
| 1701 int top_frame_index, | 1701 int top_frame_index, |
| 1702 int bottom_js_frame_index, | 1702 const int bottom_js_frame_index, |
| 1703 Debug::FrameDropMode* mode, | 1703 Debug::FrameDropMode* mode, |
| 1704 Object*** restarter_frame_function_pointer) { | 1704 Object*** restarter_frame_function_pointer) { |
| 1705 if (!Debug::kFrameDropperSupported) { | 1705 if (!Debug::kFrameDropperSupported) { |
| 1706 return "Stack manipulations are not supported in this architecture."; | 1706 return "Stack manipulations are not supported in this architecture."; |
| 1707 } | 1707 } |
| 1708 | 1708 |
| 1709 StackFrame* pre_top_frame = frames[top_frame_index - 1]; | 1709 StackFrame* pre_top_frame = frames[top_frame_index - 1]; |
| 1710 StackFrame* top_frame = frames[top_frame_index]; | 1710 StackFrame* top_frame = frames[top_frame_index]; |
| 1711 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; | 1711 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; |
| 1712 | 1712 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1723 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | 1723 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
| 1724 } else if (pre_top_frame_code == | 1724 } else if (pre_top_frame_code == |
| 1725 isolate->debug()->debug_break_slot()) { | 1725 isolate->debug()->debug_break_slot()) { |
| 1726 // OK, we can drop debug break slot. | 1726 // OK, we can drop debug break slot. |
| 1727 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; | 1727 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
| 1728 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | 1728 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
| 1729 } else if (pre_top_frame_code == | 1729 } else if (pre_top_frame_code == |
| 1730 isolate->builtins()->builtin( | 1730 isolate->builtins()->builtin( |
| 1731 Builtins::kFrameDropper_LiveEdit)) { | 1731 Builtins::kFrameDropper_LiveEdit)) { |
| 1732 // OK, we can drop our own code. | 1732 // OK, we can drop our own code. |
| 1733 pre_top_frame = frames[top_frame_index - 2]; | 1733 top_frame_index--; |
| 1734 top_frame = frames[top_frame_index - 1]; | |
| 1735 *mode = Debug::CURRENTLY_SET_MODE; | 1734 *mode = Debug::CURRENTLY_SET_MODE; |
| 1736 frame_has_padding = false; | 1735 frame_has_padding = false; |
| 1737 } else if (pre_top_frame_code == | 1736 } else if (pre_top_frame_code == |
| 1738 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { | 1737 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { |
| 1739 *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL; | 1738 *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL; |
| 1740 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | 1739 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
| 1741 } else if (pre_top_frame_code->kind() == Code::STUB && | 1740 } else if (pre_top_frame->type() == StackFrame::EXIT) { |
| 1742 pre_top_frame_code->major_key() == CodeStub::CEntry) { | 1741 // Exit to C++ code. Could be 'debugger' statement or some regular code |
| 1743 // Entry from our unit tests on 'debugger' statement. | 1742 // that cause exception throwing (including 'throw' statement). |
| 1744 // It's fine, we support this case. | 1743 // It's fine, we support this case. |
| 1745 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; | 1744 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
| 1746 // We don't have a padding from 'debugger' statement call. | 1745 // We don't have a padding from 'debugger' statement call. |
| 1747 // Here the stub is CEntry, it's not debug-only and can't be padded. | 1746 // Here the stub is CEntry, it's not debug-only and can't be padded. |
| 1748 // If anyone would complain, a proxy padded stub could be added. | 1747 // If anyone would complain, a proxy padded stub could be added. |
| 1749 frame_has_padding = false; | 1748 frame_has_padding = false; |
| 1749 } else if (frames[top_frame_index - 2]->type() == StackFrame::EXIT) { |
| 1750 top_frame_index--; |
| 1751 // Same as above case. |
| 1752 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
| 1753 frame_has_padding = false; |
| 1750 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { | 1754 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { |
| 1751 // This must be adaptor that remain from the frame dropping that | 1755 // This must be adaptor that remain from the frame dropping that |
| 1752 // is still on stack. A frame dropper frame must be above it. | 1756 // is still on stack. A frame dropper frame must be above it. |
| 1753 ASSERT(frames[top_frame_index - 2]->LookupCode() == | 1757 ASSERT(frames[top_frame_index - 2]->LookupCode() == |
| 1754 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); | 1758 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); |
| 1755 pre_top_frame = frames[top_frame_index - 3]; | 1759 top_frame_index -= 2; |
| 1756 top_frame = frames[top_frame_index - 2]; | |
| 1757 *mode = Debug::CURRENTLY_SET_MODE; | 1760 *mode = Debug::CURRENTLY_SET_MODE; |
| 1758 frame_has_padding = false; | 1761 frame_has_padding = false; |
| 1759 } else { | 1762 } else { |
| 1760 return "Unknown structure of stack above changing function"; | 1763 return "Unknown structure of stack above changing function"; |
| 1761 } | 1764 } |
| 1762 | 1765 |
| 1766 pre_top_frame = frames[top_frame_index - 1]; |
| 1767 top_frame = frames[top_frame_index]; |
| 1768 |
| 1763 Address unused_stack_top = top_frame->sp(); | 1769 Address unused_stack_top = top_frame->sp(); |
| 1764 Address unused_stack_bottom = bottom_js_frame->fp() | 1770 Address unused_stack_bottom = bottom_js_frame->fp() |
| 1765 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. | 1771 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. |
| 1766 + kPointerSize; // Bigger address end is exclusive. | 1772 + kPointerSize; // Bigger address end is exclusive. |
| 1767 | 1773 |
| 1768 Address* top_frame_pc_address = top_frame->pc_address(); | 1774 Address* top_frame_pc_address = top_frame->pc_address(); |
| 1769 | 1775 |
| 1770 // top_frame may be damaged below this point. Do not used it. | 1776 // top_frame may be damaged below this point. Do not used it. |
| 1771 ASSERT(!(top_frame = NULL)); | 1777 ASSERT(!(top_frame = NULL)); |
| 1772 | 1778 |
| 1779 bool use_padding = false; |
| 1773 if (unused_stack_top > unused_stack_bottom) { | 1780 if (unused_stack_top > unused_stack_bottom) { |
| 1774 if (frame_has_padding) { | 1781 if (frame_has_padding) { |
| 1782 use_padding = true; |
| 1783 } else { |
| 1784 return "Not enough space for frame dropper frame"; |
| 1785 } |
| 1786 } |
| 1787 |
| 1788 // Committing now. After this point we should return only NULL value. |
| 1789 |
| 1790 if (use_padding) { |
| 1791 // Extra parenthses are temporary to retain indentation to keep diff clear. |
| 1792 // TODO(prybin): drop parenthses in a separate change. |
| 1793 { |
| 1775 int shortage_bytes = | 1794 int shortage_bytes = |
| 1776 static_cast<int>(unused_stack_top - unused_stack_bottom); | 1795 static_cast<int>(unused_stack_top - unused_stack_bottom); |
| 1777 | 1796 |
| 1778 Address padding_start = pre_top_frame->fp() - | 1797 Address padding_start = pre_top_frame->fp() - |
| 1779 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize; | 1798 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize; |
| 1780 | 1799 |
| 1781 Address padding_pointer = padding_start; | 1800 Address padding_pointer = padding_start; |
| 1782 Smi* padding_object = | 1801 Smi* padding_object = |
| 1783 Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue); | 1802 Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue); |
| 1784 while (Memory::Object_at(padding_pointer) == padding_object) { | 1803 while (Memory::Object_at(padding_pointer) == padding_object) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1798 OS::MemMove(padding_start + kPointerSize - shortage_bytes, | 1817 OS::MemMove(padding_start + kPointerSize - shortage_bytes, |
| 1799 padding_start + kPointerSize, | 1818 padding_start + kPointerSize, |
| 1800 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize); | 1819 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize); |
| 1801 | 1820 |
| 1802 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); | 1821 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); |
| 1803 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); | 1822 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); |
| 1804 unused_stack_top -= shortage_bytes; | 1823 unused_stack_top -= shortage_bytes; |
| 1805 | 1824 |
| 1806 STATIC_ASSERT(sizeof(Address) == kPointerSize); | 1825 STATIC_ASSERT(sizeof(Address) == kPointerSize); |
| 1807 top_frame_pc_address -= shortage_bytes / kPointerSize; | 1826 top_frame_pc_address -= shortage_bytes / kPointerSize; |
| 1808 } else { | |
| 1809 return "Not enough space for frame dropper frame"; | |
| 1810 } | 1827 } |
| 1811 } | 1828 } |
| 1812 | 1829 |
| 1813 // Committing now. After this point we should return only NULL value. | 1830 |
| 1831 if (pre_top_frame->type() == StackFrame::EXIT) { |
| 1832 isolate->debug()->set_c_entry_frame_to_ignore_exception( |
| 1833 pre_top_frame->fp()); |
| 1834 } |
| 1814 | 1835 |
| 1815 FixTryCatchHandler(pre_top_frame, bottom_js_frame); | 1836 FixTryCatchHandler(pre_top_frame, bottom_js_frame); |
| 1816 // Make sure FixTryCatchHandler is idempotent. | 1837 // Make sure FixTryCatchHandler is idempotent. |
| 1817 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); | 1838 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); |
| 1818 | 1839 |
| 1819 Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit(); | 1840 Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit(); |
| 1820 *top_frame_pc_address = code->entry(); | 1841 *top_frame_pc_address = code->entry(); |
| 1821 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); | 1842 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); |
| 1822 | 1843 |
| 1823 *restarter_frame_function_pointer = | 1844 *restarter_frame_function_pointer = |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 | 2175 |
| 2155 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2176 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
| 2156 return false; | 2177 return false; |
| 2157 } | 2178 } |
| 2158 | 2179 |
| 2159 #endif // ENABLE_DEBUGGER_SUPPORT | 2180 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2160 | 2181 |
| 2161 | 2182 |
| 2162 | 2183 |
| 2163 } } // namespace v8::internal | 2184 } } // namespace v8::internal |
| OLD | NEW |