OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 22 matching lines...) Expand all Loading... | |
33 #include "code-stubs.h" | 33 #include "code-stubs.h" |
34 #include "codegen.h" | 34 #include "codegen.h" |
35 #include "compilation-cache.h" | 35 #include "compilation-cache.h" |
36 #include "compiler.h" | 36 #include "compiler.h" |
37 #include "debug.h" | 37 #include "debug.h" |
38 #include "deoptimizer.h" | 38 #include "deoptimizer.h" |
39 #include "execution.h" | 39 #include "execution.h" |
40 #include "global-handles.h" | 40 #include "global-handles.h" |
41 #include "ic.h" | 41 #include "ic.h" |
42 #include "ic-inl.h" | 42 #include "ic-inl.h" |
43 #include "list.h" | |
43 #include "messages.h" | 44 #include "messages.h" |
44 #include "natives.h" | 45 #include "natives.h" |
45 #include "stub-cache.h" | 46 #include "stub-cache.h" |
46 #include "log.h" | 47 #include "log.h" |
47 | 48 |
48 #include "../include/v8-debug.h" | 49 #include "../include/v8-debug.h" |
49 | 50 |
50 namespace v8 { | 51 namespace v8 { |
51 namespace internal { | 52 namespace internal { |
52 | 53 |
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1098 ASSERT(HasDebugInfo(shared)); | 1099 ASSERT(HasDebugInfo(shared)); |
1099 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); | 1100 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); |
1100 } | 1101 } |
1101 | 1102 |
1102 | 1103 |
1103 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, | 1104 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, |
1104 Handle<Object> break_point_object, | 1105 Handle<Object> break_point_object, |
1105 int* source_position) { | 1106 int* source_position) { |
1106 HandleScope scope(isolate_); | 1107 HandleScope scope(isolate_); |
1107 | 1108 |
1109 PrepareForBreakPoints(); | |
1110 | |
1108 if (!EnsureDebugInfo(shared)) { | 1111 if (!EnsureDebugInfo(shared)) { |
1109 // Return if retrieving debug info failed. | 1112 // Return if retrieving debug info failed. |
1110 return; | 1113 return; |
1111 } | 1114 } |
1112 | 1115 |
1113 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1116 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1114 // Source positions starts with zero. | 1117 // Source positions starts with zero. |
1115 ASSERT(source_position >= 0); | 1118 ASSERT(source_position >= 0); |
1116 | 1119 |
1117 // Find the break point and change it. | 1120 // Find the break point and change it. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 } | 1174 } |
1172 | 1175 |
1173 // Remove all debug info. | 1176 // Remove all debug info. |
1174 while (debug_info_list_ != NULL) { | 1177 while (debug_info_list_ != NULL) { |
1175 RemoveDebugInfo(debug_info_list_->debug_info()); | 1178 RemoveDebugInfo(debug_info_list_->debug_info()); |
1176 } | 1179 } |
1177 } | 1180 } |
1178 | 1181 |
1179 | 1182 |
1180 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { | 1183 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { |
1184 PrepareForBreakPoints(); | |
1181 // Make sure the function has setup the debug info. | 1185 // Make sure the function has setup the debug info. |
1182 if (!EnsureDebugInfo(shared)) { | 1186 if (!EnsureDebugInfo(shared)) { |
1183 // Return if we failed to retrieve the debug info. | 1187 // Return if we failed to retrieve the debug info. |
1184 return; | 1188 return; |
1185 } | 1189 } |
1186 | 1190 |
1187 // Flood the function with break points. | 1191 // Flood the function with break points. |
1188 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); | 1192 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); |
1189 while (!it.Done()) { | 1193 while (!it.Done()) { |
1190 it.SetOneShot(); | 1194 it.SetOneShot(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1227 if (type == BreakUncaughtException) { | 1231 if (type == BreakUncaughtException) { |
1228 return break_on_uncaught_exception_; | 1232 return break_on_uncaught_exception_; |
1229 } else { | 1233 } else { |
1230 return break_on_exception_; | 1234 return break_on_exception_; |
1231 } | 1235 } |
1232 } | 1236 } |
1233 | 1237 |
1234 | 1238 |
1235 void Debug::PrepareStep(StepAction step_action, int step_count) { | 1239 void Debug::PrepareStep(StepAction step_action, int step_count) { |
1236 HandleScope scope(isolate_); | 1240 HandleScope scope(isolate_); |
1241 | |
1242 PrepareForBreakPoints(); | |
1243 | |
1237 ASSERT(Debug::InDebugger()); | 1244 ASSERT(Debug::InDebugger()); |
1238 | 1245 |
1239 // Remember this step action and count. | 1246 // Remember this step action and count. |
1240 thread_local_.last_step_action_ = step_action; | 1247 thread_local_.last_step_action_ = step_action; |
1241 if (step_action == StepOut) { | 1248 if (step_action == StepOut) { |
1242 // For step out target frame will be found on the stack so there is no need | 1249 // For step out target frame will be found on the stack so there is no need |
1243 // to set step counter for it. It's expected to always be 0 for StepOut. | 1250 // to set step counter for it. It's expected to always be 0 for StepOut. |
1244 thread_local_.step_count_ = 0; | 1251 thread_local_.step_count_ = 0; |
1245 } else { | 1252 } else { |
1246 thread_local_.step_count_ = step_count; | 1253 thread_local_.step_count_ = step_count; |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1669 } | 1676 } |
1670 | 1677 |
1671 | 1678 |
1672 void Debug::ClearStepNext() { | 1679 void Debug::ClearStepNext() { |
1673 thread_local_.last_step_action_ = StepNone; | 1680 thread_local_.last_step_action_ = StepNone; |
1674 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 1681 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
1675 thread_local_.last_fp_ = 0; | 1682 thread_local_.last_fp_ = 0; |
1676 } | 1683 } |
1677 | 1684 |
1678 | 1685 |
1686 bool SortedListContains(List<JSFunction*>* functions, JSFunction* function) { | |
Sven Panne
2011/09/08 08:07:59
Perhaps this should be moved to the List template
Søren Thygesen Gjesse
2011/09/13 07:31:19
Added the following template functions to list.h.
| |
1687 int low = 0; | |
1688 int high = functions->length() - 1; | |
1689 while (low <= high) { | |
1690 int mid = (low + high) / 2; | |
1691 JSFunction* mid_function = (*functions)[mid]; | |
1692 | |
1693 if (mid_function > function) { | |
1694 high = mid - 1; | |
1695 continue; | |
1696 } | |
1697 if (mid_function < function) { | |
1698 low = mid + 1; | |
1699 continue; | |
1700 } | |
1701 // Found the function. | |
1702 return true; | |
1703 } | |
1704 return false; | |
1705 } | |
1706 | |
1707 | |
1708 void Debug::PrepareForBreakPoints() { | |
1709 // If preparing for the first break point make sure to deoptimize all | |
1710 // functions as debugging does not work with optimized code. | |
1711 if (!has_break_points_) { | |
1712 Deoptimizer::DeoptimizeAll(); | |
1713 | |
1714 AssertNoAllocation no_allocation; | |
1715 Builtins* builtins = isolate_->builtins(); | |
1716 Code* lazy_compile = builtins->builtin(Builtins::kLazyCompile); | |
1717 | |
1718 // Find all non-optimized code functions with activation frames on | |
1719 // the stack. | |
1720 List<JSFunction*> functions(100); | |
Sven Panne
2011/09/08 08:07:59
functions => active_functions
Søren Thygesen Gjesse
2011/09/13 07:31:19
Done.
| |
1721 for (JavaScriptFrameIterator it(isolate_); !it.done(); it.Advance()) { | |
1722 JavaScriptFrame* frame = it.frame(); | |
1723 if (frame->function()->IsJSFunction()) { | |
1724 JSFunction* function = JSFunction::cast(frame->function()); | |
1725 if (function->code()->kind() == Code::FUNCTION) | |
1726 functions.Add(function); | |
1727 } | |
1728 } | |
1729 functions.Sort(); | |
1730 | |
1731 // Scan the heap for all non-optimized functions which has no | |
1732 // debug break slots. | |
1733 HeapIterator iterator; | |
1734 HeapObject* obj = NULL; | |
1735 while (((obj = iterator.next()) != NULL)) { | |
1736 if (obj->IsJSFunction()) { | |
1737 JSFunction* function = JSFunction::cast(obj); | |
1738 if (function->shared()->allows_lazy_compilation() && | |
1739 function->shared()->script()->IsScript() && | |
1740 function->code()->kind() == Code::FUNCTION && | |
1741 !function->code()->has_debug_break_slots()) { | |
1742 bool has_activation = SortedListContains(&functions, function); | |
1743 if (!has_activation) { | |
1744 function->set_code(lazy_compile); | |
1745 function->shared()->set_code(lazy_compile); | |
1746 } | |
1747 } | |
1748 } | |
1749 } | |
1750 } | |
1751 } | |
1752 | |
1753 | |
1679 // Ensures the debug information is present for shared. | 1754 // Ensures the debug information is present for shared. |
1680 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { | 1755 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { |
1681 // Return if we already have the debug info for shared. | 1756 // Return if we already have the debug info for shared. |
1682 if (HasDebugInfo(shared)) return true; | 1757 if (HasDebugInfo(shared)) { |
1758 ASSERT(shared->is_compiled()); | |
1759 return true; | |
1760 } | |
1683 | 1761 |
1684 // Ensure shared in compiled. Return false if this failed. | 1762 // Ensure shared in compiled. Return false if this failed. |
1685 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; | 1763 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; |
1686 | 1764 |
1687 // If preparing for the first break point make sure to deoptimize all | |
1688 // functions as debugging does not work with optimized code. | |
1689 if (!has_break_points_) { | |
1690 Deoptimizer::DeoptimizeAll(); | |
1691 } | |
1692 | |
1693 // Create the debug info object. | 1765 // Create the debug info object. |
1694 Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); | 1766 Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); |
1695 | 1767 |
1696 // Add debug info to the list. | 1768 // Add debug info to the list. |
1697 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); | 1769 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); |
1698 node->set_next(debug_info_list_); | 1770 node->set_next(debug_info_list_); |
1699 debug_info_list_ = node; | 1771 debug_info_list_ = node; |
1700 | 1772 |
1701 // Now there is at least one break point. | 1773 // Now there is at least one break point. |
1702 has_break_points_ = true; | 1774 has_break_points_ = true; |
(...skipping 29 matching lines...) Expand all Loading... | |
1732 prev = current; | 1804 prev = current; |
1733 current = current->next(); | 1805 current = current->next(); |
1734 } | 1806 } |
1735 UNREACHABLE(); | 1807 UNREACHABLE(); |
1736 } | 1808 } |
1737 | 1809 |
1738 | 1810 |
1739 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 1811 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |
1740 HandleScope scope(isolate_); | 1812 HandleScope scope(isolate_); |
1741 | 1813 |
1814 PrepareForBreakPoints(); | |
1815 | |
1742 // Get the executing function in which the debug break occurred. | 1816 // Get the executing function in which the debug break occurred. |
1743 Handle<SharedFunctionInfo> shared = | 1817 Handle<SharedFunctionInfo> shared = |
1744 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1818 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
1745 if (!EnsureDebugInfo(shared)) { | 1819 if (!EnsureDebugInfo(shared)) { |
1746 // Return if we failed to retrieve the debug info. | 1820 // Return if we failed to retrieve the debug info. |
1747 return; | 1821 return; |
1748 } | 1822 } |
1749 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1823 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1750 Handle<Code> code(debug_info->code()); | 1824 Handle<Code> code(debug_info->code()); |
1751 Handle<Code> original_code(debug_info->original_code()); | 1825 Handle<Code> original_code(debug_info->original_code()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1822 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { | 1896 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { |
1823 HandleScope scope(isolate_); | 1897 HandleScope scope(isolate_); |
1824 | 1898 |
1825 // If there are no break points this cannot be break at return, as | 1899 // If there are no break points this cannot be break at return, as |
1826 // the debugger statement and stack guard bebug break cannot be at | 1900 // the debugger statement and stack guard bebug break cannot be at |
1827 // return. | 1901 // return. |
1828 if (!has_break_points_) { | 1902 if (!has_break_points_) { |
1829 return false; | 1903 return false; |
1830 } | 1904 } |
1831 | 1905 |
1906 PrepareForBreakPoints(); | |
1907 | |
1832 // Get the executing function in which the debug break occurred. | 1908 // Get the executing function in which the debug break occurred. |
1833 Handle<SharedFunctionInfo> shared = | 1909 Handle<SharedFunctionInfo> shared = |
1834 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1910 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
1835 if (!EnsureDebugInfo(shared)) { | 1911 if (!EnsureDebugInfo(shared)) { |
1836 // Return if we failed to retrieve the debug info. | 1912 // Return if we failed to retrieve the debug info. |
1837 return false; | 1913 return false; |
1838 } | 1914 } |
1839 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1915 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1840 Handle<Code> code(debug_info->code()); | 1916 Handle<Code> code(debug_info->code()); |
1841 #ifdef DEBUG | 1917 #ifdef DEBUG |
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3126 { | 3202 { |
3127 Locker locker; | 3203 Locker locker; |
3128 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3204 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
3129 } | 3205 } |
3130 } | 3206 } |
3131 } | 3207 } |
3132 | 3208 |
3133 #endif // ENABLE_DEBUGGER_SUPPORT | 3209 #endif // ENABLE_DEBUGGER_SUPPORT |
3134 | 3210 |
3135 } } // namespace v8::internal | 3211 } } // namespace v8::internal |
OLD | NEW |