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 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1588 } | 1588 } |
1589 | 1589 |
1590 return NULL; | 1590 return NULL; |
1591 } | 1591 } |
1592 | 1592 |
1593 | 1593 |
1594 static bool IsDropableFrame(StackFrame* frame) { | 1594 static bool IsDropableFrame(StackFrame* frame) { |
1595 return !frame->is_exit(); | 1595 return !frame->is_exit(); |
1596 } | 1596 } |
1597 | 1597 |
1598 // Fills result array with statuses of functions. Modifies the stack | 1598 |
1599 // removing all listed function if possible and if do_drop is true. | 1599 // Describes a set of call frames that executes any of listed functions. |
1600 static const char* DropActivationsInActiveThread( | 1600 // Finding no such frames does not mean error. |
1601 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop, | 1601 class MultipleFunctionTarget { |
1602 Zone* zone) { | 1602 public: |
1603 MultipleFunctionTarget(Handle<JSArray> shared_info_array, Handle<JSArray> resu lt) | |
Yang
2012/06/14 09:09:28
80 char limit.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1604 : m_shared_info_array(shared_info_array), | |
1605 m_result(result) | |
1606 { | |
1607 } | |
Yang
2012/06/14 09:09:28
You can put the empty function body on the same li
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1608 bool MatchActivation(StackFrame* frame, LiveEdit::FunctionPatchabilityStatus s tatus) { | |
Yang
2012/06/14 09:09:28
80 char limit.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1609 return CheckActivation(m_shared_info_array, m_result, frame, status); | |
1610 } | |
1611 const char* GetNotFoundMessage() { | |
1612 return NULL; | |
1613 } | |
1614 private: | |
1615 Handle<JSArray> m_shared_info_array; | |
1616 Handle<JSArray> m_result; | |
1617 }; | |
1618 | |
1619 // Drops all call frame matched by target and all frames above them. | |
1620 template<typename TARGET> | |
1621 static const char* DropActivationsInActiveThreadImpl( | |
1622 TARGET& target, bool do_drop, Zone* zone) { | |
1603 Isolate* isolate = Isolate::Current(); | 1623 Isolate* isolate = Isolate::Current(); |
1604 Debug* debug = isolate->debug(); | 1624 Debug* debug = isolate->debug(); |
1605 ZoneScope scope(isolate, DELETE_ON_EXIT); | 1625 ZoneScope scope(isolate, DELETE_ON_EXIT); |
1606 Vector<StackFrame*> frames = CreateStackMap(zone); | 1626 Vector<StackFrame*> frames = CreateStackMap(zone); |
1607 | 1627 |
1608 int array_len = Smi::cast(shared_info_array->length())->value(); | |
1609 | 1628 |
1610 int top_frame_index = -1; | 1629 int top_frame_index = -1; |
1611 int frame_index = 0; | 1630 int frame_index = 0; |
1612 for (; frame_index < frames.length(); frame_index++) { | 1631 for (; frame_index < frames.length(); frame_index++) { |
1613 StackFrame* frame = frames[frame_index]; | 1632 StackFrame* frame = frames[frame_index]; |
1614 if (frame->id() == debug->break_frame_id()) { | 1633 if (frame->id() == debug->break_frame_id()) { |
1615 top_frame_index = frame_index; | 1634 top_frame_index = frame_index; |
1616 break; | 1635 break; |
1617 } | 1636 } |
1618 if (CheckActivation(shared_info_array, result, frame, | 1637 if (target.MatchActivation( |
1619 LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) { | 1638 frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) { |
Yang
2012/06/14 09:09:28
4 spaces more indent.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1620 // We are still above break_frame. It is not a target frame, | 1639 // We are still above break_frame. It is not a target frame, |
1621 // it is a problem. | 1640 // it is a problem. |
1622 return "Debugger mark-up on stack is not found"; | 1641 return "Debugger mark-up on stack is not found"; |
1623 } | 1642 } |
1624 } | 1643 } |
1625 | 1644 |
1626 if (top_frame_index == -1) { | 1645 if (top_frame_index == -1) { |
1627 // We haven't found break frame, but no function is blocking us anyway. | 1646 // We haven't found break frame, but no function is blocking us anyway. |
1628 return NULL; | 1647 return target.GetNotFoundMessage(); |
1629 } | 1648 } |
1630 | 1649 |
1631 bool target_frame_found = false; | 1650 bool target_frame_found = false; |
1632 int bottom_js_frame_index = top_frame_index; | 1651 int bottom_js_frame_index = top_frame_index; |
1633 bool c_code_found = false; | 1652 bool c_code_found = false; |
1634 | 1653 |
1635 for (; frame_index < frames.length(); frame_index++) { | 1654 for (; frame_index < frames.length(); frame_index++) { |
1636 StackFrame* frame = frames[frame_index]; | 1655 StackFrame* frame = frames[frame_index]; |
1637 if (!IsDropableFrame(frame)) { | 1656 if (!IsDropableFrame(frame)) { |
1638 c_code_found = true; | 1657 c_code_found = true; |
1639 break; | 1658 break; |
1640 } | 1659 } |
1641 if (CheckActivation(shared_info_array, result, frame, | 1660 if (target.MatchActivation( |
1642 LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { | 1661 frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { |
Yang
2012/06/14 09:09:28
ditto.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1643 target_frame_found = true; | 1662 target_frame_found = true; |
1644 bottom_js_frame_index = frame_index; | 1663 bottom_js_frame_index = frame_index; |
1645 } | 1664 } |
1646 } | 1665 } |
1647 | 1666 |
1648 if (c_code_found) { | 1667 if (c_code_found) { |
1649 // There is a C frames on stack. Check that there are no target frames | 1668 // There is a C frames on stack. Check that there are no target frames |
1650 // below them. | 1669 // below them. |
1651 for (; frame_index < frames.length(); frame_index++) { | 1670 for (; frame_index < frames.length(); frame_index++) { |
1652 StackFrame* frame = frames[frame_index]; | 1671 StackFrame* frame = frames[frame_index]; |
1653 if (frame->is_java_script()) { | 1672 if (frame->is_java_script()) { |
1654 if (CheckActivation(shared_info_array, result, frame, | 1673 if (target.MatchActivation( |
1655 LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) { | 1674 frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) { |
Yang
2012/06/14 09:09:28
ditto.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1656 // Cannot drop frame under C frames. | 1675 // Cannot drop frame under C frames. |
1657 return NULL; | 1676 return NULL; |
1658 } | 1677 } |
1659 } | 1678 } |
1660 } | 1679 } |
1661 } | 1680 } |
1662 | 1681 |
1663 if (!do_drop) { | 1682 if (!do_drop) { |
1664 // We are in check-only mode. | 1683 // We are in check-only mode. |
1665 return NULL; | 1684 return NULL; |
1666 } | 1685 } |
1667 | 1686 |
1668 if (!target_frame_found) { | 1687 if (!target_frame_found) { |
1669 // Nothing to drop. | 1688 // Nothing to drop. |
1670 return NULL; | 1689 return target.GetNotFoundMessage(); |
1671 } | 1690 } |
1672 | 1691 |
1673 Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED; | 1692 Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED; |
1674 Object** restarter_frame_function_pointer = NULL; | 1693 Object** restarter_frame_function_pointer = NULL; |
1675 const char* error_message = DropFrames(frames, top_frame_index, | 1694 const char* error_message = DropFrames(frames, top_frame_index, |
1676 bottom_js_frame_index, &drop_mode, | 1695 bottom_js_frame_index, &drop_mode, |
1677 &restarter_frame_function_pointer); | 1696 &restarter_frame_function_pointer); |
1678 | 1697 |
1679 if (error_message != NULL) { | 1698 if (error_message != NULL) { |
1680 return error_message; | 1699 return error_message; |
1681 } | 1700 } |
1682 | 1701 |
1683 // Adjust break_frame after some frames has been dropped. | 1702 // Adjust break_frame after some frames has been dropped. |
1684 StackFrame::Id new_id = StackFrame::NO_ID; | 1703 StackFrame::Id new_id = StackFrame::NO_ID; |
1685 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { | 1704 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { |
1686 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { | 1705 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { |
1687 new_id = frames[i]->id(); | 1706 new_id = frames[i]->id(); |
1688 break; | 1707 break; |
1689 } | 1708 } |
1690 } | 1709 } |
1691 debug->FramesHaveBeenDropped(new_id, drop_mode, | 1710 debug->FramesHaveBeenDropped(new_id, drop_mode, |
1692 restarter_frame_function_pointer); | 1711 restarter_frame_function_pointer); |
1712 return NULL; | |
1713 } | |
1714 | |
1715 // Fills result array with statuses of functions. Modifies the stack | |
1716 // removing all listed function if possible and if do_drop is true. | |
1717 static const char* DropActivationsInActiveThread( | |
1718 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop, | |
1719 Zone* zone) { | |
1720 MultipleFunctionTarget target(shared_info_array, result); | |
1721 | |
1722 const char* message = DropActivationsInActiveThreadImpl(target, do_drop, zone) ; | |
Yang
2012/06/14 09:09:28
80 char limit.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1723 if (message) { | |
1724 return message; | |
1725 } | |
1726 | |
1727 int array_len = Smi::cast(shared_info_array->length())->value(); | |
1693 | 1728 |
1694 // Replace "blocked on active" with "replaced on active" status. | 1729 // Replace "blocked on active" with "replaced on active" status. |
1695 for (int i = 0; i < array_len; i++) { | 1730 for (int i = 0; i < array_len; i++) { |
1696 if (result->GetElement(i) == | 1731 if (result->GetElement(i) == |
1697 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { | 1732 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { |
1698 Handle<Object> replaced( | 1733 Handle<Object> replaced( |
1699 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); | 1734 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); |
1700 SetElementNonStrict(result, i, replaced); | 1735 SetElementNonStrict(result, i, replaced); |
1701 } | 1736 } |
1702 } | 1737 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1759 if (error_message != NULL) { | 1794 if (error_message != NULL) { |
1760 // Add error message as an array extra element. | 1795 // Add error message as an array extra element. |
1761 Vector<const char> vector_message(error_message, StrLength(error_message)); | 1796 Vector<const char> vector_message(error_message, StrLength(error_message)); |
1762 Handle<String> str = FACTORY->NewStringFromAscii(vector_message); | 1797 Handle<String> str = FACTORY->NewStringFromAscii(vector_message); |
1763 SetElementNonStrict(result, len, str); | 1798 SetElementNonStrict(result, len, str); |
1764 } | 1799 } |
1765 return result; | 1800 return result; |
1766 } | 1801 } |
1767 | 1802 |
1768 | 1803 |
1804 // Describes a single callframe a target. Not finding this frame | |
1805 // means an error. | |
1806 class SingleFrameTarget { | |
1807 public: | |
1808 SingleFrameTarget(JavaScriptFrame* frame) : m_frame(frame) {} | |
1809 | |
1810 bool MatchActivation(StackFrame* frame, LiveEdit::FunctionPatchabilityStatus s tatus) { | |
Yang
2012/06/14 09:09:28
80 char limit.
Peter Rybin
2012/06/14 22:08:03
Done.
| |
1811 if (frame->fp() == m_frame->fp()) { | |
1812 m_saved_status = status; | |
1813 return true; | |
1814 } | |
1815 return false; | |
1816 } | |
1817 const char* GetNotFoundMessage() { | |
1818 return "Failed to found requested frame"; | |
1819 } | |
1820 LiveEdit::FunctionPatchabilityStatus saved_status() { | |
1821 return m_saved_status; | |
1822 } | |
1823 private: | |
1824 JavaScriptFrame* m_frame; | |
1825 LiveEdit::FunctionPatchabilityStatus m_saved_status; | |
1826 }; | |
1827 | |
1828 | |
1829 // Finds a drops required frame and all frames above. | |
1830 // Returns error message or NULL. | |
1831 const char* LiveEdit::RestartFrame(JavaScriptFrame* frame, Zone* zone) { | |
1832 SingleFrameTarget target(frame); | |
1833 | |
1834 return DropActivationsInActiveThreadImpl(target, true, zone); | |
1835 } | |
1836 | |
1837 | |
1769 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, | 1838 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, |
1770 FunctionLiteral* fun) | 1839 FunctionLiteral* fun) |
1771 : isolate_(isolate) { | 1840 : isolate_(isolate) { |
1772 if (isolate_->active_function_info_listener() != NULL) { | 1841 if (isolate_->active_function_info_listener() != NULL) { |
1773 isolate_->active_function_info_listener()->FunctionStarted(fun); | 1842 isolate_->active_function_info_listener()->FunctionStarted(fun); |
1774 } | 1843 } |
1775 } | 1844 } |
1776 | 1845 |
1777 | 1846 |
1778 LiveEditFunctionTracker::~LiveEditFunctionTracker() { | 1847 LiveEditFunctionTracker::~LiveEditFunctionTracker() { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1826 | 1895 |
1827 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 1896 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
1828 return false; | 1897 return false; |
1829 } | 1898 } |
1830 | 1899 |
1831 #endif // ENABLE_DEBUGGER_SUPPORT | 1900 #endif // ENABLE_DEBUGGER_SUPPORT |
1832 | 1901 |
1833 | 1902 |
1834 | 1903 |
1835 } } // namespace v8::internal | 1904 } } // namespace v8::internal |
OLD | NEW |