| 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 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1666 return change; | 1666 return change; |
| 1667 } | 1667 } |
| 1668 | 1668 |
| 1669 | 1669 |
| 1670 // Removes specified range of frames from stack. There may be 1 or more | 1670 // Removes specified range of frames from stack. There may be 1 or more |
| 1671 // frames in range. Anyway the bottom frame is restarted rather than dropped, | 1671 // frames in range. Anyway the bottom frame is restarted rather than dropped, |
| 1672 // and therefore has to be a JavaScript frame. | 1672 // and therefore has to be a JavaScript frame. |
| 1673 // Returns error message or NULL. | 1673 // Returns error message or NULL. |
| 1674 static const char* DropFrames(Vector<StackFrame*> frames, | 1674 static const char* DropFrames(Vector<StackFrame*> frames, |
| 1675 int top_frame_index, | 1675 int top_frame_index, |
| 1676 int bottom_js_frame_index, | 1676 const int bottom_js_frame_index, |
| 1677 Debug::FrameDropMode* mode, | 1677 Debug::FrameDropMode* mode, |
| 1678 Object*** restarter_frame_function_pointer) { | 1678 Object*** restarter_frame_function_pointer) { |
| 1679 if (!Debug::kFrameDropperSupported) { | 1679 if (!Debug::kFrameDropperSupported) { |
| 1680 return "Stack manipulations are not supported in this architecture."; | 1680 return "Stack manipulations are not supported in this architecture."; |
| 1681 } | 1681 } |
| 1682 | 1682 |
| 1683 StackFrame* pre_top_frame = frames[top_frame_index - 1]; | 1683 StackFrame* pre_top_frame = frames[top_frame_index - 1]; |
| 1684 StackFrame* top_frame = frames[top_frame_index]; | 1684 StackFrame* top_frame = frames[top_frame_index]; |
| 1685 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; | 1685 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; |
| 1686 | 1686 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1697 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | 1697 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
| 1698 } else if (pre_top_frame_code == | 1698 } else if (pre_top_frame_code == |
| 1699 isolate->debug()->debug_break_slot()) { | 1699 isolate->debug()->debug_break_slot()) { |
| 1700 // OK, we can drop debug break slot. | 1700 // OK, we can drop debug break slot. |
| 1701 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; | 1701 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
| 1702 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | 1702 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
| 1703 } else if (pre_top_frame_code == | 1703 } else if (pre_top_frame_code == |
| 1704 isolate->builtins()->builtin( | 1704 isolate->builtins()->builtin( |
| 1705 Builtins::kFrameDropper_LiveEdit)) { | 1705 Builtins::kFrameDropper_LiveEdit)) { |
| 1706 // OK, we can drop our own code. | 1706 // OK, we can drop our own code. |
| 1707 pre_top_frame = frames[top_frame_index - 2]; | 1707 top_frame_index--; |
| 1708 top_frame = frames[top_frame_index - 1]; | |
| 1709 *mode = Debug::CURRENTLY_SET_MODE; | 1708 *mode = Debug::CURRENTLY_SET_MODE; |
| 1710 frame_has_padding = false; | 1709 frame_has_padding = false; |
| 1711 } else if (pre_top_frame_code == | 1710 } else if (pre_top_frame_code == |
| 1712 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { | 1711 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { |
| 1713 *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL; | 1712 *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL; |
| 1714 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | 1713 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
| 1715 } else if (pre_top_frame_code->kind() == Code::STUB && | 1714 } else if (pre_top_frame->type() == StackFrame::EXIT) { |
| 1716 pre_top_frame_code->major_key() == CodeStub::CEntry) { | 1715 // Exit to C++ code. Could be 'debugger' statement or some regular code |
| 1717 // Entry from our unit tests on 'debugger' statement. | 1716 // that cause exception throwing (including 'throw' statement). |
| 1718 // It's fine, we support this case. | 1717 // It's fine, we support this case. |
| 1719 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; | 1718 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
| 1720 // We don't have a padding from 'debugger' statement call. | 1719 // We don't have a padding from 'debugger' statement call. |
| 1721 // Here the stub is CEntry, it's not debug-only and can't be padded. | 1720 // Here the stub is CEntry, it's not debug-only and can't be padded. |
| 1722 // If anyone would complain, a proxy padded stub could be added. | 1721 // If anyone would complain, a proxy padded stub could be added. |
| 1723 frame_has_padding = false; | 1722 frame_has_padding = false; |
| 1723 } else if (frames[top_frame_index - 2]->type() == StackFrame::EXIT) { |
| 1724 top_frame_index--; |
| 1725 // Same as above case. |
| 1726 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
| 1727 frame_has_padding = false; |
| 1724 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { | 1728 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { |
| 1725 // This must be adaptor that remain from the frame dropping that | 1729 // This must be adaptor that remain from the frame dropping that |
| 1726 // is still on stack. A frame dropper frame must be above it. | 1730 // is still on stack. A frame dropper frame must be above it. |
| 1727 ASSERT(frames[top_frame_index - 2]->LookupCode() == | 1731 ASSERT(frames[top_frame_index - 2]->LookupCode() == |
| 1728 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); | 1732 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); |
| 1729 pre_top_frame = frames[top_frame_index - 3]; | 1733 top_frame_index -= 2; |
| 1730 top_frame = frames[top_frame_index - 2]; | |
| 1731 *mode = Debug::CURRENTLY_SET_MODE; | 1734 *mode = Debug::CURRENTLY_SET_MODE; |
| 1732 frame_has_padding = false; | 1735 frame_has_padding = false; |
| 1733 } else { | 1736 } else { |
| 1734 return "Unknown structure of stack above changing function"; | 1737 return "Unknown structure of stack above changing function"; |
| 1735 } | 1738 } |
| 1736 | 1739 |
| 1740 pre_top_frame = frames[top_frame_index - 1]; |
| 1741 top_frame = frames[top_frame_index]; |
| 1742 |
| 1737 Address unused_stack_top = top_frame->sp(); | 1743 Address unused_stack_top = top_frame->sp(); |
| 1738 Address unused_stack_bottom = bottom_js_frame->fp() | 1744 Address unused_stack_bottom = bottom_js_frame->fp() |
| 1739 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. | 1745 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. |
| 1740 + kPointerSize; // Bigger address end is exclusive. | 1746 + kPointerSize; // Bigger address end is exclusive. |
| 1741 | 1747 |
| 1742 Address* top_frame_pc_address = top_frame->pc_address(); | 1748 Address* top_frame_pc_address = top_frame->pc_address(); |
| 1743 | 1749 |
| 1744 // top_frame may be damaged below this point. Do not used it. | 1750 // top_frame may be damaged below this point. Do not used it. |
| 1745 ASSERT(!(top_frame = NULL)); | 1751 ASSERT(!(top_frame = NULL)); |
| 1746 | 1752 |
| 1753 bool use_padding = false; |
| 1747 if (unused_stack_top > unused_stack_bottom) { | 1754 if (unused_stack_top > unused_stack_bottom) { |
| 1748 if (frame_has_padding) { | 1755 if (frame_has_padding) { |
| 1756 use_padding = true; |
| 1757 } else { |
| 1758 return "Not enough space for frame dropper frame"; |
| 1759 } |
| 1760 } |
| 1761 |
| 1762 // Committing now. After this point we should return only NULL value. |
| 1763 |
| 1764 if (use_padding) { |
| 1765 // Extra parenthses are temporary to retain indentation to keep diff clear. |
| 1766 // TODO(prybin): drop parenthses in a separate change. |
| 1767 { |
| 1749 int shortage_bytes = | 1768 int shortage_bytes = |
| 1750 static_cast<int>(unused_stack_top - unused_stack_bottom); | 1769 static_cast<int>(unused_stack_top - unused_stack_bottom); |
| 1751 | 1770 |
| 1752 Address padding_start = pre_top_frame->fp() - | 1771 Address padding_start = pre_top_frame->fp() - |
| 1753 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize; | 1772 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize; |
| 1754 | 1773 |
| 1755 Address padding_pointer = padding_start; | 1774 Address padding_pointer = padding_start; |
| 1756 Smi* padding_object = | 1775 Smi* padding_object = |
| 1757 Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue); | 1776 Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue); |
| 1758 while (Memory::Object_at(padding_pointer) == padding_object) { | 1777 while (Memory::Object_at(padding_pointer) == padding_object) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1772 OS::MemMove(padding_start + kPointerSize - shortage_bytes, | 1791 OS::MemMove(padding_start + kPointerSize - shortage_bytes, |
| 1773 padding_start + kPointerSize, | 1792 padding_start + kPointerSize, |
| 1774 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize); | 1793 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize); |
| 1775 | 1794 |
| 1776 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); | 1795 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); |
| 1777 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); | 1796 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); |
| 1778 unused_stack_top -= shortage_bytes; | 1797 unused_stack_top -= shortage_bytes; |
| 1779 | 1798 |
| 1780 STATIC_ASSERT(sizeof(Address) == kPointerSize); | 1799 STATIC_ASSERT(sizeof(Address) == kPointerSize); |
| 1781 top_frame_pc_address -= shortage_bytes / kPointerSize; | 1800 top_frame_pc_address -= shortage_bytes / kPointerSize; |
| 1782 } else { | |
| 1783 return "Not enough space for frame dropper frame"; | |
| 1784 } | 1801 } |
| 1785 } | 1802 } |
| 1786 | 1803 |
| 1787 // Committing now. After this point we should return only NULL value. | 1804 |
| 1805 if (pre_top_frame->type() == StackFrame::EXIT) { |
| 1806 isolate->debug()->set_c_entry_frame_to_ignore_exception( |
| 1807 pre_top_frame->fp()); |
| 1808 } |
| 1788 | 1809 |
| 1789 FixTryCatchHandler(pre_top_frame, bottom_js_frame); | 1810 FixTryCatchHandler(pre_top_frame, bottom_js_frame); |
| 1790 // Make sure FixTryCatchHandler is idempotent. | 1811 // Make sure FixTryCatchHandler is idempotent. |
| 1791 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); | 1812 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); |
| 1792 | 1813 |
| 1793 Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit(); | 1814 Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit(); |
| 1794 *top_frame_pc_address = code->entry(); | 1815 *top_frame_pc_address = code->entry(); |
| 1795 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); | 1816 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); |
| 1796 | 1817 |
| 1797 *restarter_frame_function_pointer = | 1818 *restarter_frame_function_pointer = |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2128 | 2149 |
| 2129 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2150 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
| 2130 return false; | 2151 return false; |
| 2131 } | 2152 } |
| 2132 | 2153 |
| 2133 #endif // ENABLE_DEBUGGER_SUPPORT | 2154 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2134 | 2155 |
| 2135 | 2156 |
| 2136 | 2157 |
| 2137 } } // namespace v8::internal | 2158 } } // namespace v8::internal |
| OLD | NEW |