Commit da647667 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[liftoff][debug] Implement StepIn

Update the "hook on function call" flag also in the wasm case, and
slightly change the {IsStepping} logic to stop in any frame if the last
step action was anything other than StepNext.
In future CLs, this has to be extended further for StepOut and for
StepOver at a return location.
When that is done, we can also reenable more stepping in the test.

R=thibaudm@chromium.org

Bug: v8:10321
Change-Id: Ib3aa8c2c2e137690140e5879a33e2bcc340821e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2108035
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66789}
parent 32b22fe9
...@@ -996,29 +996,6 @@ void Debug::PrepareStep(StepAction step_action) { ...@@ -996,29 +996,6 @@ void Debug::PrepareStep(StepAction step_action) {
StackTraceFrameIterator frames_it(isolate_, frame_id); StackTraceFrameIterator frames_it(isolate_, frame_id);
StandardFrame* frame = frames_it.frame(); StandardFrame* frame = frames_it.frame();
// Handle stepping in wasm functions via the wasm interpreter.
if (frame->is_wasm_interpreter_entry()) {
WasmInterpreterEntryFrame* wasm_frame =
WasmInterpreterEntryFrame::cast(frame);
if (wasm_frame->NumberOfActiveFrames() > 0) {
wasm_frame->debug_info().PrepareStep(step_action);
return;
}
}
// Handle stepping in Liftoff code.
if (FLAG_debug_in_liftoff && frame->is_wasm_compiled()) {
WasmCompiledFrame* wasm_frame = WasmCompiledFrame::cast(frame);
wasm::WasmCodeRefScope code_ref_scope;
wasm::WasmCode* code = wasm_frame->wasm_code();
if (code->is_liftoff()) {
wasm_frame->native_module()->GetDebugInfo()->PrepareStep(isolate_);
return;
}
}
// If this is wasm, but there are no interpreted frames on top, all we can do
// is step out.
if (frame->is_wasm()) step_action = StepOut;
BreakLocation location = BreakLocation::Invalid(); BreakLocation location = BreakLocation::Invalid();
Handle<SharedFunctionInfo> shared; Handle<SharedFunctionInfo> shared;
int current_frame_count = CurrentFrameCount(); int current_frame_count = CurrentFrameCount();
...@@ -1062,6 +1039,25 @@ void Debug::PrepareStep(StepAction step_action) { ...@@ -1062,6 +1039,25 @@ void Debug::PrepareStep(StepAction step_action) {
thread_local_.last_frame_count_ = current_frame_count; thread_local_.last_frame_count_ = current_frame_count;
// No longer perform the current async step. // No longer perform the current async step.
clear_suspended_generator(); clear_suspended_generator();
} else if (frame->is_wasm_interpreter_entry()) {
// Handle stepping in wasm functions via the wasm interpreter.
WasmInterpreterEntryFrame* wasm_frame =
WasmInterpreterEntryFrame::cast(frame);
if (wasm_frame->NumberOfActiveFrames() > 0) {
wasm_frame->debug_info().PrepareStep(step_action);
return;
}
} else if (FLAG_debug_in_liftoff && frame->is_wasm_compiled()) {
// Handle stepping in Liftoff code.
WasmCompiledFrame* wasm_frame = WasmCompiledFrame::cast(frame);
wasm::WasmCodeRefScope code_ref_scope;
wasm::WasmCode* code = wasm_frame->wasm_code();
if (code->is_liftoff()) {
wasm_frame->native_module()->GetDebugInfo()->PrepareStep(isolate_);
}
// In case the wasm code returns, prepare the next frame (if JS) to break.
step_action = StepOut;
UpdateHookOnFunctionCall();
} }
switch (step_action) { switch (step_action) {
......
...@@ -698,7 +698,9 @@ class DebugInfoImpl { ...@@ -698,7 +698,9 @@ class DebugInfoImpl {
bool IsStepping(WasmCompiledFrame* frame) { bool IsStepping(WasmCompiledFrame* frame) {
DCHECK_IMPLIES(stepping_frame_ != NO_ID, flooded_function_index_ != -1); DCHECK_IMPLIES(stepping_frame_ != NO_ID, flooded_function_index_ != -1);
return stepping_frame_ == frame->id(); Isolate* isolate = frame->wasm_instance().GetIsolate();
StepAction last_step_action = isolate->debug()->last_step_action();
return last_step_action == StepIn || stepping_frame_ == frame->id();
} }
void RemoveDebugSideTables(Vector<WasmCode* const> codes) { void RemoveDebugSideTables(Vector<WasmCode* const> codes) {
......
...@@ -18,28 +18,18 @@ Debugger.stepOver called ...@@ -18,28 +18,18 @@ Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:59 Paused at wasm://wasm/42af3c82:0:59
Debugger.resume called Debugger.resume called
Paused at wasm://wasm/42af3c82:0:73 Paused at wasm://wasm/42af3c82:0:73
Debugger.stepInto called
Paused at wasm://wasm/42af3c82:0:52
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:75 Paused at wasm://wasm/42af3c82:0:53
Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:59
Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:61
Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:63
Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:65
Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:67
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:68 Paused at wasm://wasm/42af3c82:0:54
Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:70
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/42af3c82:0:73 Paused at wasm://wasm/42af3c82:0:73
Debugger.stepOver called Debugger.resume called
Paused at wasm://wasm/42af3c82:0:75 Paused at wasm://wasm/42af3c82:0:52
Debugger.stepOver called Debugger.resume called
Paused at wasm://wasm/42af3c82:0:59 Paused at :0:24
Debugger.resume called Debugger.resume called
exports.main returned! exports.main returned!
Test stepping over a recursive call Test stepping over a recursive call
......
...@@ -98,11 +98,15 @@ function instantiate(bytes) { ...@@ -98,11 +98,15 @@ function instantiate(bytes) {
await waitForPauseAndStep('stepOver'); // over call await waitForPauseAndStep('stepOver'); // over call
await waitForPauseAndStep('stepOver'); // over br await waitForPauseAndStep('stepOver'); // over br
await waitForPauseAndStep('resume'); // to next breakpoint (3rd iteration) await waitForPauseAndStep('resume'); // to next breakpoint (3rd iteration)
await waitForPauseAndStep('stepOver'); // over wasm_A await waitForPauseAndStep('stepInto'); // into wasm_A
// Step out of wasm_A, back to wasm_B.
// TODO(clemensb/thibaudm): Replace by an actual 'stepOut'.
for (let i = 0; i < 3; ++i) await waitForPauseAndStep('stepOver');
// Step over 10 times. // Step over 10 times.
for (let i = 0; i < 10; ++i) await waitForPauseAndStep('stepOver'); // TODO(clemensb/thibaudm): Reenable once stepping over return works.
// Then just resume. //for (let i = 0; i < 10; ++i) await waitForPauseAndStep('stepOver');
await waitForPauseAndStep('resume'); // Resume three more times to continue over other breakpoints.
for (let i = 0; i < 3; ++i) await waitForPauseAndStep('resume');
InspectorTest.log('exports.main returned!'); InspectorTest.log('exports.main returned!');
InspectorTest.log('Test stepping over a recursive call'); InspectorTest.log('Test stepping over a recursive call');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment