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 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
856 // step in at call sites. | 856 // step in at call sites. |
857 Deoptimizer::DeoptimizeFunction(*function); | 857 Deoptimizer::DeoptimizeFunction(*function); |
858 return; | 858 return; |
859 } | 859 } |
860 // Make sure the function is compiled and has set up the debug info. | 860 // Make sure the function is compiled and has set up the debug info. |
861 Handle<SharedFunctionInfo> shared(function->shared()); | 861 Handle<SharedFunctionInfo> shared(function->shared()); |
862 if (!EnsureDebugInfo(shared, function)) { | 862 if (!EnsureDebugInfo(shared, function)) { |
863 // Return if we failed to retrieve the debug info. | 863 // Return if we failed to retrieve the debug info. |
864 return; | 864 return; |
865 } | 865 } |
866 if (shared->debug_is_blackboxed()) return; | |
Yang
2017/01/19 13:55:35
Do we need to ensure debug info if it's blackboxed
kozy
2017/01/19 16:08:38
Done.
| |
866 | 867 |
867 // Flood the function with break points. | 868 // Flood the function with break points. |
868 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 869 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
869 if (debug_info->HasDebugCode()) { | 870 if (debug_info->HasDebugCode()) { |
870 for (CodeBreakIterator it(debug_info, type); !it.Done(); it.Next()) { | 871 for (CodeBreakIterator it(debug_info, type); !it.Done(); it.Next()) { |
871 it.SetDebugBreak(); | 872 it.SetDebugBreak(); |
872 } | 873 } |
873 } | 874 } |
874 if (debug_info->HasDebugBytecodeArray()) { | 875 if (debug_info->HasDebugBytecodeArray()) { |
875 for (BytecodeArrayBreakIterator it(debug_info, type); !it.Done(); | 876 for (BytecodeArrayBreakIterator it(debug_info, type); !it.Done(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
962 if (last_step_action() == StepNext || last_step_action() == StepOut) { | 963 if (last_step_action() == StepNext || last_step_action() == StepOut) { |
963 while (!it.done()) { | 964 while (!it.done()) { |
964 Address current_fp = it.frame()->UnpaddedFP(); | 965 Address current_fp = it.frame()->UnpaddedFP(); |
965 if (current_fp >= thread_local_.target_fp_) break; | 966 if (current_fp >= thread_local_.target_fp_) break; |
966 it.Advance(); | 967 it.Advance(); |
967 } | 968 } |
968 } | 969 } |
969 | 970 |
970 // Find the closest Javascript frame we can flood with one-shots. | 971 // Find the closest Javascript frame we can flood with one-shots. |
971 while (!it.done() && | 972 while (!it.done() && |
972 !it.frame()->function()->shared()->IsSubjectToDebugging()) { | 973 (!it.frame()->function()->shared()->IsSubjectToDebugging() || |
974 it.frame()->function()->shared()->debug_is_blackboxed())) { | |
973 it.Advance(); | 975 it.Advance(); |
974 } | 976 } |
975 | 977 |
976 if (it.done()) return; // No suitable Javascript catch handler. | 978 if (it.done()) return; // No suitable Javascript catch handler. |
977 | 979 |
978 FloodWithOneShot(Handle<JSFunction>(it.frame()->function())); | 980 FloodWithOneShot(Handle<JSFunction>(it.frame()->function())); |
979 } | 981 } |
980 | 982 |
981 | 983 |
982 void Debug::PrepareStep(StepAction step_action) { | 984 void Debug::PrepareStep(StepAction step_action) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1036 clear_suspended_generator(); | 1038 clear_suspended_generator(); |
1037 | 1039 |
1038 switch (step_action) { | 1040 switch (step_action) { |
1039 case StepNone: | 1041 case StepNone: |
1040 UNREACHABLE(); | 1042 UNREACHABLE(); |
1041 break; | 1043 break; |
1042 case StepOut: | 1044 case StepOut: |
1043 // Advance to caller frame. | 1045 // Advance to caller frame. |
1044 frames_it.Advance(); | 1046 frames_it.Advance(); |
1045 // Skip native and extension functions on the stack. | 1047 // Skip native and extension functions on the stack. |
1046 while (!frames_it.done() && | 1048 while ( |
1047 !frames_it.frame()->function()->shared()->IsSubjectToDebugging()) { | 1049 !frames_it.done() && |
1050 (!frames_it.frame()->function()->shared()->IsSubjectToDebugging() || | |
1051 frames_it.frame()->function()->shared()->debug_is_blackboxed())) { | |
1048 // Builtin functions are not subject to stepping, but need to be | 1052 // Builtin functions are not subject to stepping, but need to be |
1049 // deoptimized to include checks for step-in at call sites. | 1053 // deoptimized to include checks for step-in at call sites. |
1050 Deoptimizer::DeoptimizeFunction(frames_it.frame()->function()); | 1054 Deoptimizer::DeoptimizeFunction(frames_it.frame()->function()); |
1051 frames_it.Advance(); | 1055 frames_it.Advance(); |
1052 } | 1056 } |
1053 if (!frames_it.done()) { | 1057 if (!frames_it.done()) { |
1054 // Fill the caller function to return to with one-shot break points. | 1058 // Fill the caller function to return to with one-shot break points. |
1055 Handle<JSFunction> caller_function(frames_it.frame()->function()); | 1059 Handle<JSFunction> caller_function(frames_it.frame()->function()); |
1056 FloodWithOneShot(caller_function); | 1060 FloodWithOneShot(caller_function); |
1057 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); | 1061 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1749 // Bail out if exception breaks are not active | 1753 // Bail out if exception breaks are not active |
1750 if (uncaught) { | 1754 if (uncaught) { |
1751 // Uncaught exceptions are reported by either flags. | 1755 // Uncaught exceptions are reported by either flags. |
1752 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; | 1756 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; |
1753 } else { | 1757 } else { |
1754 // Caught exceptions are reported is activated. | 1758 // Caught exceptions are reported is activated. |
1755 if (!break_on_exception_) return; | 1759 if (!break_on_exception_) return; |
1756 } | 1760 } |
1757 | 1761 |
1758 { | 1762 { |
1763 JavaScriptFrameIterator it(isolate_); | |
1764 // Check whether the top frame is blackboxed. | |
1765 if (!it.done() && it.frame()->function()->shared()->debug_is_blackboxed()) | |
Yang
2017/01/19 13:55:35
please add {} around if-statement body if we have
kozy
2017/01/19 16:08:38
Done.
| |
1766 return; | |
1759 // Check whether the break location is muted. | 1767 // Check whether the break location is muted. |
1760 JavaScriptFrameIterator it(isolate_); | |
1761 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return; | 1768 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return; |
Yang
2017/01/19 13:55:35
can we merge these two redundant checks?
kozy
2017/01/19 16:08:38
Done.
| |
1762 } | 1769 } |
1763 | 1770 |
1764 DebugScope debug_scope(this); | 1771 DebugScope debug_scope(this); |
1765 if (debug_scope.failed()) return; | 1772 if (debug_scope.failed()) return; |
1766 | 1773 |
1767 if (debug_event_listener_) { | 1774 if (debug_event_listener_) { |
1768 HandleScope scope(isolate_); | 1775 HandleScope scope(isolate_); |
1769 | 1776 |
1770 // Create the execution state. | 1777 // Create the execution state. |
1771 Handle<Object> exec_state; | 1778 Handle<Object> exec_state; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1890 // Since we holding promise when at least one microtask is scheduled (inside | 1897 // Since we holding promise when at least one microtask is scheduled (inside |
1891 // PromiseReactionJobInfo), we can send cancel event in weak callback. | 1898 // PromiseReactionJobInfo), we can send cancel event in weak callback. |
1892 GlobalHandles::MakeWeak( | 1899 GlobalHandles::MakeWeak( |
1893 global_handle.location(), | 1900 global_handle.location(), |
1894 new CollectedCallbackData(global_handle.location(), async_id->value(), | 1901 new CollectedCallbackData(global_handle.location(), async_id->value(), |
1895 this, isolate_), | 1902 this, isolate_), |
1896 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); | 1903 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); |
1897 return async_id->value(); | 1904 return async_id->value(); |
1898 } | 1905 } |
1899 | 1906 |
1907 void Debug::SetIsBlackboxedCallback(debug::IsBlackboxedCallback callback, | |
1908 void* data) { | |
1909 is_blackboxed_callback_ = callback; | |
1910 is_blackboxed_callback_data_ = data; | |
1911 } | |
1912 | |
1913 namespace { | |
1914 debug::Location GetDebugLocation(Handle<Script> script, int source_position) { | |
1915 Script::InitLineEnds(script); | |
1916 int line = Script::GetLineNumber(script, source_position); | |
1917 int column = Script::GetColumnNumber(script, source_position); | |
1918 return debug::Location(line, column); | |
1919 } | |
1920 } // namespace | |
1921 | |
1922 void Debug::OnNewSharedFunctionInfo(Handle<SharedFunctionInfo> shared) { | |
1923 if (!is_blackboxed_callback_) return; | |
1924 Handle<Script> script(Script::cast(shared->script())); | |
1925 if (script->type() != i::Script::TYPE_NORMAL) return; | |
1926 | |
1927 debug::Location start = GetDebugLocation(script, shared->start_position()); | |
1928 debug::Location end = GetDebugLocation(script, shared->end_position()); | |
1929 | |
1930 bool is_blackboxed = | |
1931 is_blackboxed_callback_(ToApiHandle<debug::Script>(script), start, end, | |
1932 is_blackboxed_callback_data_); | |
1933 shared->set_debug_is_blackboxed(is_blackboxed); | |
1934 } | |
1935 | |
1900 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { | 1936 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { |
1901 if (in_debug_scope() || ignore_events()) return; | 1937 if (in_debug_scope() || ignore_events()) return; |
1902 | 1938 |
1903 if (debug_event_listener_) { | 1939 if (debug_event_listener_) { |
1904 debug_event_listener_->PromiseEventOccurred(type, id); | 1940 debug_event_listener_->PromiseEventOccurred(type, id); |
1905 if (!non_inspector_listener_exists()) return; | 1941 if (!non_inspector_listener_exists()) return; |
1906 } | 1942 } |
1907 | 1943 |
1908 HandleScope scope(isolate_); | 1944 HandleScope scope(isolate_); |
1909 DebugScope debug_scope(this); | 1945 DebugScope debug_scope(this); |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2272 | 2308 |
2273 StackLimitCheck check(isolate_); | 2309 StackLimitCheck check(isolate_); |
2274 if (check.HasOverflowed()) return; | 2310 if (check.HasOverflowed()) return; |
2275 | 2311 |
2276 { JavaScriptFrameIterator it(isolate_); | 2312 { JavaScriptFrameIterator it(isolate_); |
2277 DCHECK(!it.done()); | 2313 DCHECK(!it.done()); |
2278 Object* fun = it.frame()->function(); | 2314 Object* fun = it.frame()->function(); |
2279 if (fun && fun->IsJSFunction()) { | 2315 if (fun && fun->IsJSFunction()) { |
2280 // Don't stop in builtin functions. | 2316 // Don't stop in builtin functions. |
2281 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return; | 2317 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return; |
2318 if (isolate_->stack_guard()->CheckDebugBreak() && | |
2319 JSFunction::cast(fun)->shared()->debug_is_blackboxed()) | |
2320 return; | |
2282 JSGlobalObject* global = | 2321 JSGlobalObject* global = |
2283 JSFunction::cast(fun)->context()->global_object(); | 2322 JSFunction::cast(fun)->context()->global_object(); |
2284 // Don't stop in debugger functions. | 2323 // Don't stop in debugger functions. |
2285 if (IsDebugGlobal(global)) return; | 2324 if (IsDebugGlobal(global)) return; |
2286 // Don't stop if the break location is muted. | 2325 // Don't stop if the break location is muted. |
2287 if (IsMutedAtCurrentLocation(it.frame())) return; | 2326 if (IsMutedAtCurrentLocation(it.frame())) return; |
2288 } | 2327 } |
2289 } | 2328 } |
2290 | 2329 |
2291 // Collect the break state before clearing the flags. | 2330 // Collect the break state before clearing the flags. |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2669 logger_->DebugEvent("Put", message.text()); | 2708 logger_->DebugEvent("Put", message.text()); |
2670 } | 2709 } |
2671 | 2710 |
2672 void LockingCommandMessageQueue::Clear() { | 2711 void LockingCommandMessageQueue::Clear() { |
2673 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2712 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2674 queue_.Clear(); | 2713 queue_.Clear(); |
2675 } | 2714 } |
2676 | 2715 |
2677 } // namespace internal | 2716 } // namespace internal |
2678 } // namespace v8 | 2717 } // namespace v8 |
OLD | NEW |