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 void Debug::PrepareForBreakPoints() { |
| 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 AssertNoAllocation no_allocation; |
| 1693 Builtins* builtins = isolate_->builtins(); |
| 1694 Code* lazy_compile = builtins->builtin(Builtins::kLazyCompile); |
| 1695 |
| 1696 // Find all non-optimized code functions with activation frames on |
| 1697 // the stack. |
| 1698 List<JSFunction*> active_functions(100); |
| 1699 for (JavaScriptFrameIterator it(isolate_); !it.done(); it.Advance()) { |
| 1700 JavaScriptFrame* frame = it.frame(); |
| 1701 if (frame->function()->IsJSFunction()) { |
| 1702 JSFunction* function = JSFunction::cast(frame->function()); |
| 1703 if (function->code()->kind() == Code::FUNCTION) |
| 1704 active_functions.Add(function); |
| 1705 } |
| 1706 } |
| 1707 active_functions.Sort(); |
| 1708 |
| 1709 // Scan the heap for all non-optimized functions which has no |
| 1710 // debug break slots. |
| 1711 HeapIterator iterator; |
| 1712 HeapObject* obj = NULL; |
| 1713 while (((obj = iterator.next()) != NULL)) { |
| 1714 if (obj->IsJSFunction()) { |
| 1715 JSFunction* function = JSFunction::cast(obj); |
| 1716 if (function->shared()->allows_lazy_compilation() && |
| 1717 function->shared()->script()->IsScript() && |
| 1718 function->code()->kind() == Code::FUNCTION && |
| 1719 !function->code()->has_debug_break_slots()) { |
| 1720 bool has_activation = |
| 1721 SortedListBSearch<JSFunction*>(active_functions, function) != -1; |
| 1722 if (!has_activation) { |
| 1723 function->set_code(lazy_compile); |
| 1724 function->shared()->set_code(lazy_compile); |
| 1725 } |
| 1726 } |
| 1727 } |
| 1728 } |
| 1729 } |
| 1730 } |
| 1731 |
| 1732 |
1679 // Ensures the debug information is present for shared. | 1733 // Ensures the debug information is present for shared. |
1680 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { | 1734 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { |
1681 // Return if we already have the debug info for shared. | 1735 // Return if we already have the debug info for shared. |
1682 if (HasDebugInfo(shared)) return true; | 1736 if (HasDebugInfo(shared)) { |
| 1737 ASSERT(shared->is_compiled()); |
| 1738 return true; |
| 1739 } |
1683 | 1740 |
1684 // Ensure shared in compiled. Return false if this failed. | 1741 // Ensure shared in compiled. Return false if this failed. |
1685 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; | 1742 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; |
1686 | 1743 |
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. | 1744 // Create the debug info object. |
1694 Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); | 1745 Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); |
1695 | 1746 |
1696 // Add debug info to the list. | 1747 // Add debug info to the list. |
1697 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); | 1748 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); |
1698 node->set_next(debug_info_list_); | 1749 node->set_next(debug_info_list_); |
1699 debug_info_list_ = node; | 1750 debug_info_list_ = node; |
1700 | 1751 |
1701 // Now there is at least one break point. | 1752 // Now there is at least one break point. |
1702 has_break_points_ = true; | 1753 has_break_points_ = true; |
(...skipping 29 matching lines...) Expand all Loading... |
1732 prev = current; | 1783 prev = current; |
1733 current = current->next(); | 1784 current = current->next(); |
1734 } | 1785 } |
1735 UNREACHABLE(); | 1786 UNREACHABLE(); |
1736 } | 1787 } |
1737 | 1788 |
1738 | 1789 |
1739 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 1790 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |
1740 HandleScope scope(isolate_); | 1791 HandleScope scope(isolate_); |
1741 | 1792 |
| 1793 PrepareForBreakPoints(); |
| 1794 |
1742 // Get the executing function in which the debug break occurred. | 1795 // Get the executing function in which the debug break occurred. |
1743 Handle<SharedFunctionInfo> shared = | 1796 Handle<SharedFunctionInfo> shared = |
1744 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1797 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
1745 if (!EnsureDebugInfo(shared)) { | 1798 if (!EnsureDebugInfo(shared)) { |
1746 // Return if we failed to retrieve the debug info. | 1799 // Return if we failed to retrieve the debug info. |
1747 return; | 1800 return; |
1748 } | 1801 } |
1749 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1802 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1750 Handle<Code> code(debug_info->code()); | 1803 Handle<Code> code(debug_info->code()); |
1751 Handle<Code> original_code(debug_info->original_code()); | 1804 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) { | 1875 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { |
1823 HandleScope scope(isolate_); | 1876 HandleScope scope(isolate_); |
1824 | 1877 |
1825 // If there are no break points this cannot be break at return, as | 1878 // 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 | 1879 // the debugger statement and stack guard bebug break cannot be at |
1827 // return. | 1880 // return. |
1828 if (!has_break_points_) { | 1881 if (!has_break_points_) { |
1829 return false; | 1882 return false; |
1830 } | 1883 } |
1831 | 1884 |
| 1885 PrepareForBreakPoints(); |
| 1886 |
1832 // Get the executing function in which the debug break occurred. | 1887 // Get the executing function in which the debug break occurred. |
1833 Handle<SharedFunctionInfo> shared = | 1888 Handle<SharedFunctionInfo> shared = |
1834 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1889 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
1835 if (!EnsureDebugInfo(shared)) { | 1890 if (!EnsureDebugInfo(shared)) { |
1836 // Return if we failed to retrieve the debug info. | 1891 // Return if we failed to retrieve the debug info. |
1837 return false; | 1892 return false; |
1838 } | 1893 } |
1839 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1894 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1840 Handle<Code> code(debug_info->code()); | 1895 Handle<Code> code(debug_info->code()); |
1841 #ifdef DEBUG | 1896 #ifdef DEBUG |
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3126 { | 3181 { |
3127 Locker locker; | 3182 Locker locker; |
3128 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3183 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
3129 } | 3184 } |
3130 } | 3185 } |
3131 } | 3186 } |
3132 | 3187 |
3133 #endif // ENABLE_DEBUGGER_SUPPORT | 3188 #endif // ENABLE_DEBUGGER_SUPPORT |
3134 | 3189 |
3135 } } // namespace v8::internal | 3190 } } // namespace v8::internal |
OLD | NEW |