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 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
978 DCHECK(in_debug_scope()); | 978 DCHECK(in_debug_scope()); |
979 | 979 |
980 // Get the frame where the execution has stopped and skip the debug frame if | 980 // Get the frame where the execution has stopped and skip the debug frame if |
981 // any. The debug frame will only be present if execution was stopped due to | 981 // any. The debug frame will only be present if execution was stopped due to |
982 // hitting a break point. In other situations (e.g. unhandled exception) the | 982 // hitting a break point. In other situations (e.g. unhandled exception) the |
983 // debug frame is not present. | 983 // debug frame is not present. |
984 StackFrame::Id frame_id = break_frame_id(); | 984 StackFrame::Id frame_id = break_frame_id(); |
985 // If there is no JavaScript stack don't do anything. | 985 // If there is no JavaScript stack don't do anything. |
986 if (frame_id == StackFrame::NO_ID) return; | 986 if (frame_id == StackFrame::NO_ID) return; |
987 | 987 |
988 JavaScriptFrameIterator frames_it(isolate_, frame_id); | 988 StackTraceFrameIterator frames_it(isolate_, frame_id); |
989 JavaScriptFrame* frame = frames_it.frame(); | 989 StandardFrame* frame = frames_it.frame(); |
990 | 990 |
991 feature_tracker()->Track(DebugFeatureTracker::kStepping); | 991 feature_tracker()->Track(DebugFeatureTracker::kStepping); |
992 | 992 |
993 thread_local_.last_step_action_ = step_action; | 993 thread_local_.last_step_action_ = step_action; |
994 UpdateHookOnFunctionCall(); | 994 UpdateHookOnFunctionCall(); |
995 | 995 |
996 // Handle stepping in wasm functions via the wasm interpreter. | |
997 if (frame->is_wasm()) { | |
titzer
2017/01/23 10:10:09
How do we know that this is a WasmInterpreterEntry
Clemens Hammacher
2017/01/23 12:25:33
Not in stepping or when paused at a breakpoint, bu
| |
998 WasmInterpreterEntryFrame* wasm_frame = | |
999 WasmInterpreterEntryFrame::cast(frame); | |
1000 wasm_frame->wasm_instance()->debug_info()->PrepareStep(step_action); | |
1001 return; | |
1002 } | |
1003 | |
1004 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); | |
1005 | |
996 // If the function on the top frame is unresolved perform step out. This will | 1006 // If the function on the top frame is unresolved perform step out. This will |
997 // be the case when calling unknown function and having the debugger stopped | 1007 // be the case when calling unknown function and having the debugger stopped |
998 // in an unhandled exception. | 1008 // in an unhandled exception. |
999 if (!frame->function()->IsJSFunction()) { | 1009 if (!js_frame->function()->IsJSFunction()) { |
1000 // Step out: Find the calling JavaScript frame and flood it with | 1010 // Step out: Find the calling JavaScript frame and flood it with |
1001 // breakpoints. | 1011 // breakpoints. |
1002 frames_it.Advance(); | 1012 frames_it.Advance(); |
1003 // Fill the function to return to with one-shot break points. | 1013 // Fill the function to return to with one-shot break points. |
1004 JSFunction* function = frames_it.frame()->function(); | 1014 JSFunction* function = JavaScriptFrame::cast(frames_it.frame())->function(); |
1005 FloodWithOneShot(Handle<JSFunction>(function)); | 1015 FloodWithOneShot(handle(function, isolate_)); |
1006 return; | 1016 return; |
1007 } | 1017 } |
1008 | 1018 |
1009 // Get the debug info (create it if it does not exist). | 1019 // Get the debug info (create it if it does not exist). |
1010 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); | 1020 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); |
1011 Handle<JSFunction> function(summary.function()); | 1021 Handle<JSFunction> function(summary.function()); |
1012 Handle<SharedFunctionInfo> shared(function->shared()); | 1022 Handle<SharedFunctionInfo> shared(function->shared()); |
1013 if (!EnsureDebugInfo(shared, function)) { | 1023 if (!EnsureDebugInfo(shared, function)) { |
1014 // Return if ensuring debug info failed. | 1024 // Return if ensuring debug info failed. |
1015 return; | 1025 return; |
1016 } | 1026 } |
1017 | 1027 |
1018 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 1028 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
1019 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); | 1029 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame); |
1020 | 1030 |
1021 // Any step at a return is a step-out. | 1031 // Any step at a return is a step-out. |
1022 if (location.IsReturn()) step_action = StepOut; | 1032 if (location.IsReturn()) step_action = StepOut; |
1023 // A step-next at a tail call is a step-out. | 1033 // A step-next at a tail call is a step-out. |
1024 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; | 1034 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; |
1025 | 1035 |
1026 thread_local_.last_statement_position_ = | 1036 thread_local_.last_statement_position_ = |
1027 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); | 1037 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); |
1028 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1038 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1029 // No longer perform the current async step. | 1039 // No longer perform the current async step. |
1030 clear_suspended_generator(); | 1040 clear_suspended_generator(); |
1031 | 1041 |
1032 switch (step_action) { | 1042 switch (step_action) { |
1033 case StepNone: | 1043 case StepNone: |
1034 UNREACHABLE(); | 1044 UNREACHABLE(); |
1035 break; | 1045 break; |
1036 case StepOut: | 1046 case StepOut: |
1037 // Advance to caller frame. | 1047 // Advance to caller frame. |
1038 frames_it.Advance(); | 1048 frames_it.Advance(); |
1039 // Skip native and extension functions on the stack. | 1049 // Skip native and extension functions on the stack. |
1040 while (!frames_it.done() && | 1050 while (!frames_it.done()) { |
1041 !frames_it.frame()->function()->shared()->IsSubjectToDebugging()) { | 1051 if (!frames_it.frame()->is_java_script()) break; |
1052 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frames_it.frame()); | |
1053 if (js_frame->function()->shared()->IsSubjectToDebugging()) break; | |
1042 // Builtin functions are not subject to stepping, but need to be | 1054 // Builtin functions are not subject to stepping, but need to be |
1043 // deoptimized to include checks for step-in at call sites. | 1055 // deoptimized to include checks for step-in at call sites. |
1044 Deoptimizer::DeoptimizeFunction(frames_it.frame()->function()); | 1056 Deoptimizer::DeoptimizeFunction(js_frame->function()); |
1045 frames_it.Advance(); | 1057 frames_it.Advance(); |
1046 } | 1058 } |
1047 if (!frames_it.done()) { | 1059 if (!frames_it.done()) { |
titzer
2017/01/23 10:10:10
Does it make sense to move this condition into the
Clemens Hammacher
2017/01/23 12:25:34
I agree that the loop is hard to read. It basicall
| |
1048 // Fill the caller function to return to with one-shot break points. | 1060 StandardFrame* caller_frame = frames_it.frame(); |
1049 Handle<JSFunction> caller_function(frames_it.frame()->function()); | 1061 if (caller_frame->is_wasm()) { |
1050 FloodWithOneShot(caller_function); | 1062 // TODO(clemensh): Implement stepping out from JS to WASM. |
1051 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); | 1063 } else { |
1064 JavaScriptFrame* js_caller_frame = | |
1065 JavaScriptFrame::cast(caller_frame); | |
1066 // Fill the caller function to return to with one-shot break points. | |
1067 Handle<JSFunction> caller_function(js_caller_frame->function()); | |
1068 FloodWithOneShot(caller_function); | |
1069 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); | |
1070 } | |
1052 } | 1071 } |
1053 // Clear last position info. For stepping out it does not matter. | 1072 // Clear last position info. For stepping out it does not matter. |
1054 thread_local_.last_statement_position_ = kNoSourcePosition; | 1073 thread_local_.last_statement_position_ = kNoSourcePosition; |
1055 thread_local_.last_fp_ = 0; | 1074 thread_local_.last_fp_ = 0; |
1056 break; | 1075 break; |
1057 case StepNext: | 1076 case StepNext: |
1058 thread_local_.target_fp_ = frame->UnpaddedFP(); | 1077 thread_local_.target_fp_ = frame->UnpaddedFP(); |
1059 FloodWithOneShot(function); | 1078 FloodWithOneShot(function); |
1060 break; | 1079 break; |
1061 case StepIn: | 1080 case StepIn: |
1081 // TODO(clemensh): Implement stepping from JS into WASM. | |
1062 FloodWithOneShot(function); | 1082 FloodWithOneShot(function); |
1063 break; | 1083 break; |
1064 case StepFrame: | 1084 case StepFrame: |
1085 // TODO(clemensh): Implement stepping from JS into WASM or vice versa. | |
1065 // No point in setting one-shot breaks at places where we are not about | 1086 // No point in setting one-shot breaks at places where we are not about |
1066 // to leave the current frame. | 1087 // to leave the current frame. |
1067 FloodWithOneShot(function, CALLS_AND_RETURNS); | 1088 FloodWithOneShot(function, CALLS_AND_RETURNS); |
1068 break; | 1089 break; |
1069 } | 1090 } |
1070 } | 1091 } |
1071 | 1092 |
1072 // Simple function for returning the source positions for active break points. | 1093 // Simple function for returning the source positions for active break points. |
1073 Handle<Object> Debug::GetSourceBreakLocations( | 1094 Handle<Object> Debug::GetSourceBreakLocations( |
1074 Handle<SharedFunctionInfo> shared, | 1095 Handle<SharedFunctionInfo> shared, |
(...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2665 logger_->DebugEvent("Put", message.text()); | 2686 logger_->DebugEvent("Put", message.text()); |
2666 } | 2687 } |
2667 | 2688 |
2668 void LockingCommandMessageQueue::Clear() { | 2689 void LockingCommandMessageQueue::Clear() { |
2669 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2690 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2670 queue_.Clear(); | 2691 queue_.Clear(); |
2671 } | 2692 } |
2672 | 2693 |
2673 } // namespace internal | 2694 } // namespace internal |
2674 } // namespace v8 | 2695 } // namespace v8 |
OLD | NEW |