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 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 DCHECK(in_debug_scope()); | 977 DCHECK(in_debug_scope()); |
978 | 978 |
979 // Get the frame where the execution has stopped and skip the debug frame if | 979 // Get the frame where the execution has stopped and skip the debug frame if |
980 // any. The debug frame will only be present if execution was stopped due to | 980 // any. The debug frame will only be present if execution was stopped due to |
981 // hitting a break point. In other situations (e.g. unhandled exception) the | 981 // hitting a break point. In other situations (e.g. unhandled exception) the |
982 // debug frame is not present. | 982 // debug frame is not present. |
983 StackFrame::Id frame_id = break_frame_id(); | 983 StackFrame::Id frame_id = break_frame_id(); |
984 // If there is no JavaScript stack don't do anything. | 984 // If there is no JavaScript stack don't do anything. |
985 if (frame_id == StackFrame::NO_ID) return; | 985 if (frame_id == StackFrame::NO_ID) return; |
986 | 986 |
987 JavaScriptFrameIterator frames_it(isolate_, frame_id); | 987 StackTraceFrameIterator frames_it(isolate_, frame_id); |
988 JavaScriptFrame* frame = frames_it.frame(); | 988 StandardFrame* frame = frames_it.frame(); |
989 | 989 |
990 feature_tracker()->Track(DebugFeatureTracker::kStepping); | 990 feature_tracker()->Track(DebugFeatureTracker::kStepping); |
991 | 991 |
992 thread_local_.last_step_action_ = step_action; | 992 thread_local_.last_step_action_ = step_action; |
993 UpdateHookOnFunctionCall(); | 993 UpdateHookOnFunctionCall(); |
994 | 994 |
| 995 // Handle stepping in wasm functions via the wasm interpreter. |
| 996 if (frame->is_wasm()) { |
| 997 // If the top frame is compiled, we cannot step. |
| 998 if (frame->is_wasm_compiled()) return; |
| 999 WasmInterpreterEntryFrame* wasm_frame = |
| 1000 WasmInterpreterEntryFrame::cast(frame); |
| 1001 wasm_frame->wasm_instance()->debug_info()->PrepareStep(step_action); |
| 1002 return; |
| 1003 } |
| 1004 |
| 1005 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); |
| 1006 |
995 // If the function on the top frame is unresolved perform step out. This will | 1007 // If the function on the top frame is unresolved perform step out. This will |
996 // be the case when calling unknown function and having the debugger stopped | 1008 // be the case when calling unknown function and having the debugger stopped |
997 // in an unhandled exception. | 1009 // in an unhandled exception. |
998 if (!frame->function()->IsJSFunction()) { | 1010 if (!js_frame->function()->IsJSFunction()) { |
999 // Step out: Find the calling JavaScript frame and flood it with | 1011 // Step out: Find the calling JavaScript frame and flood it with |
1000 // breakpoints. | 1012 // breakpoints. |
1001 frames_it.Advance(); | 1013 frames_it.Advance(); |
1002 // Fill the function to return to with one-shot break points. | 1014 // Fill the function to return to with one-shot break points. |
1003 JSFunction* function = frames_it.frame()->function(); | 1015 JSFunction* function = JavaScriptFrame::cast(frames_it.frame())->function(); |
1004 FloodWithOneShot(Handle<JSFunction>(function)); | 1016 FloodWithOneShot(handle(function, isolate_)); |
1005 return; | 1017 return; |
1006 } | 1018 } |
1007 | 1019 |
1008 // Get the debug info (create it if it does not exist). | 1020 // Get the debug info (create it if it does not exist). |
1009 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); | 1021 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); |
1010 Handle<JSFunction> function(summary.function()); | 1022 Handle<JSFunction> function(summary.function()); |
1011 Handle<SharedFunctionInfo> shared(function->shared()); | 1023 Handle<SharedFunctionInfo> shared(function->shared()); |
1012 if (!EnsureDebugInfo(shared, function)) { | 1024 if (!EnsureDebugInfo(shared, function)) { |
1013 // Return if ensuring debug info failed. | 1025 // Return if ensuring debug info failed. |
1014 return; | 1026 return; |
1015 } | 1027 } |
1016 | 1028 |
1017 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 1029 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
1018 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); | 1030 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame); |
1019 | 1031 |
1020 // Any step at a return is a step-out. | 1032 // Any step at a return is a step-out. |
1021 if (location.IsReturn()) step_action = StepOut; | 1033 if (location.IsReturn()) step_action = StepOut; |
1022 // A step-next at a tail call is a step-out. | 1034 // A step-next at a tail call is a step-out. |
1023 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; | 1035 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; |
1024 // A step-next in blackboxed function is a step-out. | 1036 // A step-next in blackboxed function is a step-out. |
1025 if (step_action == StepNext && IsBlackboxed(shared)) step_action = StepOut; | 1037 if (step_action == StepNext && IsBlackboxed(shared)) step_action = StepOut; |
1026 | 1038 |
1027 thread_local_.last_statement_position_ = | 1039 thread_local_.last_statement_position_ = |
1028 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); | 1040 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); |
1029 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1041 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1030 // No longer perform the current async step. | 1042 // No longer perform the current async step. |
1031 clear_suspended_generator(); | 1043 clear_suspended_generator(); |
1032 | 1044 |
1033 switch (step_action) { | 1045 switch (step_action) { |
1034 case StepNone: | 1046 case StepNone: |
1035 UNREACHABLE(); | 1047 UNREACHABLE(); |
1036 break; | 1048 break; |
1037 case StepOut: | 1049 case StepOut: |
1038 // Advance to caller frame. | 1050 // Advance to caller frame. |
1039 frames_it.Advance(); | 1051 frames_it.Advance(); |
1040 // Skip native and extension functions on the stack. | 1052 // Find top-most function which is subject to debugging. |
1041 while ( | 1053 while (!frames_it.done()) { |
1042 !frames_it.done() && | 1054 StandardFrame* caller_frame = frames_it.frame(); |
1043 (!frames_it.frame()->function()->shared()->IsSubjectToDebugging() || | 1055 if (caller_frame->is_wasm()) { |
1044 IsBlackboxed(frames_it.frame()->function()->shared()))) { | 1056 // TODO(clemensh): Implement stepping out from JS to WASM. |
| 1057 break; |
| 1058 } |
| 1059 Handle<JSFunction> js_caller_function( |
| 1060 JavaScriptFrame::cast(caller_frame)->function(), isolate_); |
| 1061 if (js_caller_function->shared()->IsSubjectToDebugging() && |
| 1062 !IsBlackboxed(js_caller_function->shared())) { |
| 1063 // Fill the caller function to return to with one-shot break points. |
| 1064 FloodWithOneShot(js_caller_function); |
| 1065 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); |
| 1066 break; |
| 1067 } |
1045 // Builtin functions are not subject to stepping, but need to be | 1068 // Builtin functions are not subject to stepping, but need to be |
1046 // deoptimized to include checks for step-in at call sites. | 1069 // deoptimized to include checks for step-in at call sites. |
1047 Deoptimizer::DeoptimizeFunction(frames_it.frame()->function()); | 1070 Deoptimizer::DeoptimizeFunction(*js_caller_function); |
1048 frames_it.Advance(); | 1071 frames_it.Advance(); |
1049 } | 1072 } |
1050 if (!frames_it.done()) { | |
1051 // Fill the caller function to return to with one-shot break points. | |
1052 Handle<JSFunction> caller_function(frames_it.frame()->function()); | |
1053 FloodWithOneShot(caller_function); | |
1054 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP(); | |
1055 } | |
1056 // Clear last position info. For stepping out it does not matter. | 1073 // Clear last position info. For stepping out it does not matter. |
1057 thread_local_.last_statement_position_ = kNoSourcePosition; | 1074 thread_local_.last_statement_position_ = kNoSourcePosition; |
1058 thread_local_.last_fp_ = 0; | 1075 thread_local_.last_fp_ = 0; |
1059 break; | 1076 break; |
1060 case StepNext: | 1077 case StepNext: |
1061 thread_local_.target_fp_ = frame->UnpaddedFP(); | 1078 thread_local_.target_fp_ = frame->UnpaddedFP(); |
1062 FloodWithOneShot(function); | 1079 FloodWithOneShot(function); |
1063 break; | 1080 break; |
1064 case StepIn: | 1081 case StepIn: |
| 1082 // TODO(clemensh): Implement stepping from JS into WASM. |
1065 FloodWithOneShot(function); | 1083 FloodWithOneShot(function); |
1066 break; | 1084 break; |
1067 case StepFrame: | 1085 case StepFrame: |
| 1086 // TODO(clemensh): Implement stepping from JS into WASM or vice versa. |
1068 // No point in setting one-shot breaks at places where we are not about | 1087 // No point in setting one-shot breaks at places where we are not about |
1069 // to leave the current frame. | 1088 // to leave the current frame. |
1070 FloodWithOneShot(function, CALLS_AND_RETURNS); | 1089 FloodWithOneShot(function, CALLS_AND_RETURNS); |
1071 break; | 1090 break; |
1072 } | 1091 } |
1073 } | 1092 } |
1074 | 1093 |
1075 // Simple function for returning the source positions for active break points. | 1094 // Simple function for returning the source positions for active break points. |
1076 Handle<Object> Debug::GetSourceBreakLocations( | 1095 Handle<Object> Debug::GetSourceBreakLocations( |
1077 Handle<SharedFunctionInfo> shared, | 1096 Handle<SharedFunctionInfo> shared, |
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2315 return v8::Utils::ToLocal(callback_data_); | 2334 return v8::Utils::ToLocal(callback_data_); |
2316 } | 2335 } |
2317 | 2336 |
2318 | 2337 |
2319 v8::Isolate* EventDetailsImpl::GetIsolate() const { | 2338 v8::Isolate* EventDetailsImpl::GetIsolate() const { |
2320 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); | 2339 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); |
2321 } | 2340 } |
2322 | 2341 |
2323 } // namespace internal | 2342 } // namespace internal |
2324 } // namespace v8 | 2343 } // namespace v8 |
OLD | NEW |