Chromium Code Reviews| 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 |