Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1239)

Side by Side Diff: src/debug/debug.cc

Issue 2649533002: [wasm] Implement stepping in wasm code (Closed)
Patch Set: Add TODOs Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.cc ('k') | src/debug/debug.js » ('j') | src/debug/debug.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698