OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
836 while (debug_info_list_ != NULL) { | 836 while (debug_info_list_ != NULL) { |
837 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); | 837 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); |
838 } | 838 } |
839 } | 839 } |
840 | 840 |
841 void Debug::FloodWithOneShot(Handle<JSFunction> function, | 841 void Debug::FloodWithOneShot(Handle<JSFunction> function, |
842 BreakLocatorType type) { | 842 BreakLocatorType type) { |
843 // Debug utility functions are not subject to debugging. | 843 // Debug utility functions are not subject to debugging. |
844 if (function->native_context() == *debug_context()) return; | 844 if (function->native_context() == *debug_context()) return; |
845 | 845 |
846 if (!function->shared()->IsSubjectToDebugging()) { | 846 if (!function->shared()->IsSubjectToDebugging() || |
847 function->shared()->DebugIsBlackboxed()) { | |
847 // Builtin functions are not subject to stepping, but need to be | 848 // Builtin functions are not subject to stepping, but need to be |
848 // deoptimized, because optimized code does not check for debug | 849 // deoptimized, because optimized code does not check for debug |
849 // step in at call sites. | 850 // step in at call sites. |
850 Deoptimizer::DeoptimizeFunction(*function); | 851 Deoptimizer::DeoptimizeFunction(*function); |
851 return; | 852 return; |
852 } | 853 } |
853 // Make sure the function is compiled and has set up the debug info. | 854 // Make sure the function is compiled and has set up the debug info. |
854 Handle<SharedFunctionInfo> shared(function->shared()); | 855 Handle<SharedFunctionInfo> shared(function->shared()); |
855 if (!EnsureDebugInfo(shared, function)) { | 856 if (!EnsureDebugInfo(shared, function)) { |
856 // Return if we failed to retrieve the debug info. | 857 // Return if we failed to retrieve the debug info. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
955 if (last_step_action() == StepNext || last_step_action() == StepOut) { | 956 if (last_step_action() == StepNext || last_step_action() == StepOut) { |
956 while (!it.done()) { | 957 while (!it.done()) { |
957 Address current_fp = it.frame()->UnpaddedFP(); | 958 Address current_fp = it.frame()->UnpaddedFP(); |
958 if (current_fp >= thread_local_.target_fp_) break; | 959 if (current_fp >= thread_local_.target_fp_) break; |
959 it.Advance(); | 960 it.Advance(); |
960 } | 961 } |
961 } | 962 } |
962 | 963 |
963 // Find the closest Javascript frame we can flood with one-shots. | 964 // Find the closest Javascript frame we can flood with one-shots. |
964 while (!it.done() && | 965 while (!it.done() && |
965 !it.frame()->function()->shared()->IsSubjectToDebugging()) { | 966 (!it.frame()->function()->shared()->IsSubjectToDebugging() || |
967 it.frame()->function()->shared()->DebugIsBlackboxed())) { | |
dgozman
2017/01/19 21:49:14
Should we make IsSubjectToDebugging() to check for
kozy
2017/01/20 02:32:37
Acknowledged.
Yang
2017/01/20 09:30:48
I think the reason we don't is because we want bla
| |
966 it.Advance(); | 968 it.Advance(); |
967 } | 969 } |
968 | 970 |
969 if (it.done()) return; // No suitable Javascript catch handler. | 971 if (it.done()) return; // No suitable Javascript catch handler. |
970 | 972 |
971 FloodWithOneShot(Handle<JSFunction>(it.frame()->function())); | 973 FloodWithOneShot(Handle<JSFunction>(it.frame()->function())); |
972 } | 974 } |
973 | 975 |
974 | 976 |
975 void Debug::PrepareStep(StepAction step_action) { | 977 void Debug::PrepareStep(StepAction step_action) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1030 clear_suspended_generator(); | 1032 clear_suspended_generator(); |
1031 | 1033 |
1032 switch (step_action) { | 1034 switch (step_action) { |
1033 case StepNone: | 1035 case StepNone: |
1034 UNREACHABLE(); | 1036 UNREACHABLE(); |
1035 break; | 1037 break; |
1036 case StepOut: | 1038 case StepOut: |
1037 // Advance to caller frame. | 1039 // Advance to caller frame. |
1038 frames_it.Advance(); | 1040 frames_it.Advance(); |
1039 // Skip native and extension functions on the stack. | 1041 // Skip native and extension functions on the stack. |
1040 while (!frames_it.done() && | 1042 while ( |
1041 !frames_it.frame()->function()->shared()->IsSubjectToDebugging()) { | 1043 !frames_it.done() && |
1044 (!frames_it.frame()->function()->shared()->IsSubjectToDebugging() || | |
1045 frames_it.frame()->function()->shared()->DebugIsBlackboxed())) { | |
1042 // Builtin functions are not subject to stepping, but need to be | 1046 // Builtin functions are not subject to stepping, but need to be |
1043 // deoptimized to include checks for step-in at call sites. | 1047 // deoptimized to include checks for step-in at call sites. |
1044 Deoptimizer::DeoptimizeFunction(frames_it.frame()->function()); | 1048 Deoptimizer::DeoptimizeFunction(frames_it.frame()->function()); |
1045 frames_it.Advance(); | 1049 frames_it.Advance(); |
1046 } | 1050 } |
1047 if (!frames_it.done()) { | 1051 if (!frames_it.done()) { |
1048 // Fill the caller function to return to with one-shot break points. | 1052 // Fill the caller function to return to with one-shot break points. |
1049 Handle<JSFunction> caller_function(frames_it.frame()->function()); | 1053 Handle<JSFunction> caller_function(frames_it.frame()->function()); |
1050 FloodWithOneShot(caller_function); | 1054 FloodWithOneShot(caller_function); |
1051 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); | 1055 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1747 // Bail out if exception breaks are not active | 1751 // Bail out if exception breaks are not active |
1748 if (uncaught) { | 1752 if (uncaught) { |
1749 // Uncaught exceptions are reported by either flags. | 1753 // Uncaught exceptions are reported by either flags. |
1750 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; | 1754 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; |
1751 } else { | 1755 } else { |
1752 // Caught exceptions are reported is activated. | 1756 // Caught exceptions are reported is activated. |
1753 if (!break_on_exception_) return; | 1757 if (!break_on_exception_) return; |
1754 } | 1758 } |
1755 | 1759 |
1756 { | 1760 { |
1757 // Check whether the break location is muted. | |
1758 JavaScriptFrameIterator it(isolate_); | 1761 JavaScriptFrameIterator it(isolate_); |
1759 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return; | 1762 // Check whether the top frame is blackboxed or the break location is muted. |
1763 if (!it.done() && (it.frame()->function()->shared()->DebugIsBlackboxed() || | |
1764 IsMutedAtCurrentLocation(it.frame()))) { | |
1765 return; | |
1766 } | |
1760 } | 1767 } |
1761 | 1768 |
1762 DebugScope debug_scope(this); | 1769 DebugScope debug_scope(this); |
1763 if (debug_scope.failed()) return; | 1770 if (debug_scope.failed()) return; |
1764 | 1771 |
1765 if (debug_event_listener_) { | 1772 if (debug_event_listener_) { |
1766 HandleScope scope(isolate_); | 1773 HandleScope scope(isolate_); |
1767 | 1774 |
1768 // Create the execution state. | 1775 // Create the execution state. |
1769 Handle<Object> exec_state; | 1776 Handle<Object> exec_state; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1888 // Since we holding promise when at least one microtask is scheduled (inside | 1895 // Since we holding promise when at least one microtask is scheduled (inside |
1889 // PromiseReactionJobInfo), we can send cancel event in weak callback. | 1896 // PromiseReactionJobInfo), we can send cancel event in weak callback. |
1890 GlobalHandles::MakeWeak( | 1897 GlobalHandles::MakeWeak( |
1891 global_handle.location(), | 1898 global_handle.location(), |
1892 new CollectedCallbackData(global_handle.location(), async_id->value(), | 1899 new CollectedCallbackData(global_handle.location(), async_id->value(), |
1893 this, isolate_), | 1900 this, isolate_), |
1894 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); | 1901 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); |
1895 return async_id->value(); | 1902 return async_id->value(); |
1896 } | 1903 } |
1897 | 1904 |
1905 void Debug::SetIsBlackboxedCallback(debug::IsBlackboxedCallback callback, | |
1906 void* data) { | |
1907 is_blackboxed_callback_ = callback; | |
1908 is_blackboxed_callback_data_ = data; | |
1909 } | |
1910 | |
1911 namespace { | |
1912 debug::Location GetDebugLocation(Handle<Script> script, int source_position) { | |
1913 Script::InitLineEnds(script); | |
1914 int line = Script::GetLineNumber(script, source_position); | |
dgozman
2017/01/19 22:34:20
GetPositionInfo
kozy
2017/01/20 02:32:37
Done.
| |
1915 int column = Script::GetColumnNumber(script, source_position); | |
1916 return debug::Location(line, column); | |
1917 } | |
1918 } // namespace | |
1919 | |
1920 bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) { | |
1921 if (!is_blackboxed_callback_) return false; | |
1922 Handle<Script> script(Script::cast(shared->script())); | |
1923 if (script->type() != i::Script::TYPE_NORMAL) return false; | |
1924 | |
1925 debug::Location start = GetDebugLocation(script, shared->start_position()); | |
1926 debug::Location end = GetDebugLocation(script, shared->end_position()); | |
1927 | |
1928 return is_blackboxed_callback_(ToApiHandle<debug::Script>(script), start, end, | |
1929 is_blackboxed_callback_data_); | |
1930 } | |
1931 | |
1898 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { | 1932 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { |
1899 if (in_debug_scope() || ignore_events()) return; | 1933 if (in_debug_scope() || ignore_events()) return; |
1900 | 1934 |
1901 if (debug_event_listener_) { | 1935 if (debug_event_listener_) { |
1902 debug_event_listener_->PromiseEventOccurred(type, id); | 1936 debug_event_listener_->PromiseEventOccurred(type, id); |
1903 if (!non_inspector_listener_exists()) return; | 1937 if (!non_inspector_listener_exists()) return; |
1904 } | 1938 } |
1905 | 1939 |
1906 HandleScope scope(isolate_); | 1940 HandleScope scope(isolate_); |
1907 DebugScope debug_scope(this); | 1941 DebugScope debug_scope(this); |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2270 | 2304 |
2271 StackLimitCheck check(isolate_); | 2305 StackLimitCheck check(isolate_); |
2272 if (check.HasOverflowed()) return; | 2306 if (check.HasOverflowed()) return; |
2273 | 2307 |
2274 { JavaScriptFrameIterator it(isolate_); | 2308 { JavaScriptFrameIterator it(isolate_); |
2275 DCHECK(!it.done()); | 2309 DCHECK(!it.done()); |
2276 Object* fun = it.frame()->function(); | 2310 Object* fun = it.frame()->function(); |
2277 if (fun && fun->IsJSFunction()) { | 2311 if (fun && fun->IsJSFunction()) { |
2278 // Don't stop in builtin functions. | 2312 // Don't stop in builtin functions. |
2279 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return; | 2313 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return; |
2314 if (isolate_->stack_guard()->CheckDebugBreak() && | |
2315 JSFunction::cast(fun)->shared()->DebugIsBlackboxed()) | |
2316 return; | |
2280 JSGlobalObject* global = | 2317 JSGlobalObject* global = |
2281 JSFunction::cast(fun)->context()->global_object(); | 2318 JSFunction::cast(fun)->context()->global_object(); |
2282 // Don't stop in debugger functions. | 2319 // Don't stop in debugger functions. |
2283 if (IsDebugGlobal(global)) return; | 2320 if (IsDebugGlobal(global)) return; |
2284 // Don't stop if the break location is muted. | 2321 // Don't stop if the break location is muted. |
2285 if (IsMutedAtCurrentLocation(it.frame())) return; | 2322 if (IsMutedAtCurrentLocation(it.frame())) return; |
2286 } | 2323 } |
2287 } | 2324 } |
2288 | 2325 |
2289 // Collect the break state before clearing the flags. | 2326 // Collect the break state before clearing the flags. |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2667 logger_->DebugEvent("Put", message.text()); | 2704 logger_->DebugEvent("Put", message.text()); |
2668 } | 2705 } |
2669 | 2706 |
2670 void LockingCommandMessageQueue::Clear() { | 2707 void LockingCommandMessageQueue::Clear() { |
2671 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2708 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2672 queue_.Clear(); | 2709 queue_.Clear(); |
2673 } | 2710 } |
2674 | 2711 |
2675 } // namespace internal | 2712 } // namespace internal |
2676 } // namespace v8 | 2713 } // namespace v8 |
OLD | NEW |