Chromium Code Reviews| 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 |