Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(504)

Side by Side Diff: src/liveedit.cc

Issue 10544151: Support 'restart call frame' debug command (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: merge Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/liveedit.h ('k') | src/liveedit-debugger.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 execute 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,
1604 Handle<JSArray> result)
1605 : m_shared_info_array(shared_info_array),
1606 m_result(result) {}
1607 bool MatchActivation(StackFrame* frame,
1608 LiveEdit::FunctionPatchabilityStatus status) {
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)) {
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)) {
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)) {
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 =
1723 DropActivationsInActiveThreadImpl(target, do_drop, zone);
1724 if (message) {
1725 return message;
1726 }
1727
1728 int array_len = Smi::cast(shared_info_array->length())->value();
1693 1729
1694 // Replace "blocked on active" with "replaced on active" status. 1730 // Replace "blocked on active" with "replaced on active" status.
1695 for (int i = 0; i < array_len; i++) { 1731 for (int i = 0; i < array_len; i++) {
1696 if (result->GetElement(i) == 1732 if (result->GetElement(i) ==
1697 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { 1733 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
1698 Handle<Object> replaced( 1734 Handle<Object> replaced(
1699 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); 1735 Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK));
1700 SetElementNonStrict(result, i, replaced); 1736 SetElementNonStrict(result, i, replaced);
1701 } 1737 }
1702 } 1738 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 if (error_message != NULL) { 1795 if (error_message != NULL) {
1760 // Add error message as an array extra element. 1796 // Add error message as an array extra element.
1761 Vector<const char> vector_message(error_message, StrLength(error_message)); 1797 Vector<const char> vector_message(error_message, StrLength(error_message));
1762 Handle<String> str = FACTORY->NewStringFromAscii(vector_message); 1798 Handle<String> str = FACTORY->NewStringFromAscii(vector_message);
1763 SetElementNonStrict(result, len, str); 1799 SetElementNonStrict(result, len, str);
1764 } 1800 }
1765 return result; 1801 return result;
1766 } 1802 }
1767 1803
1768 1804
1805 // Describes a single callframe a target. Not finding this frame
1806 // means an error.
1807 class SingleFrameTarget {
1808 public:
1809 explicit SingleFrameTarget(JavaScriptFrame* frame) : m_frame(frame) {}
1810
1811 bool MatchActivation(StackFrame* frame,
1812 LiveEdit::FunctionPatchabilityStatus status) {
1813 if (frame->fp() == m_frame->fp()) {
1814 m_saved_status = status;
1815 return true;
1816 }
1817 return false;
1818 }
1819 const char* GetNotFoundMessage() {
1820 return "Failed to found requested frame";
1821 }
1822 LiveEdit::FunctionPatchabilityStatus saved_status() {
1823 return m_saved_status;
1824 }
1825 private:
1826 JavaScriptFrame* m_frame;
1827 LiveEdit::FunctionPatchabilityStatus m_saved_status;
1828 };
1829
1830
1831 // Finds a drops required frame and all frames above.
1832 // Returns error message or NULL.
1833 const char* LiveEdit::RestartFrame(JavaScriptFrame* frame, Zone* zone) {
1834 SingleFrameTarget target(frame);
1835
1836 return DropActivationsInActiveThreadImpl(target, true, zone);
1837 }
1838
1839
1769 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate, 1840 LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
1770 FunctionLiteral* fun) 1841 FunctionLiteral* fun)
1771 : isolate_(isolate) { 1842 : isolate_(isolate) {
1772 if (isolate_->active_function_info_listener() != NULL) { 1843 if (isolate_->active_function_info_listener() != NULL) {
1773 isolate_->active_function_info_listener()->FunctionStarted(fun); 1844 isolate_->active_function_info_listener()->FunctionStarted(fun);
1774 } 1845 }
1775 } 1846 }
1776 1847
1777 1848
1778 LiveEditFunctionTracker::~LiveEditFunctionTracker() { 1849 LiveEditFunctionTracker::~LiveEditFunctionTracker() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 1897
1827 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { 1898 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
1828 return false; 1899 return false;
1829 } 1900 }
1830 1901
1831 #endif // ENABLE_DEBUGGER_SUPPORT 1902 #endif // ENABLE_DEBUGGER_SUPPORT
1832 1903
1833 1904
1834 1905
1835 } } // namespace v8::internal 1906 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/liveedit.h ('k') | src/liveedit-debugger.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698