[liftoff][debug] Implement StepOver at return locations
A StepOver at a return (either explicit return instruction, or implicit return at the end of the function) should stop again in the caller frame. R=thibaudm@chromium.org Bug: v8:10321 Change-Id: I313e6b612ac52e73b33ef07c6da1ced2aa0db600 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2110250 Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#66852}
This commit is contained in:
parent
8f68e39214
commit
04774ffaaa
@ -709,6 +709,15 @@ class DebugInfoImpl {
|
|||||||
DCHECK(!it.done());
|
DCHECK(!it.done());
|
||||||
DCHECK(it.frame()->is_wasm_compiled());
|
DCHECK(it.frame()->is_wasm_compiled());
|
||||||
WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame());
|
WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame());
|
||||||
|
|
||||||
|
// If we are at a return instruction, then any stepping action is equivalent
|
||||||
|
// to StepOut, and we need to flood the parent function.
|
||||||
|
if (IsAtReturn(frame)) {
|
||||||
|
it.Advance();
|
||||||
|
if (it.done() || !it.frame()->is_wasm_compiled()) return;
|
||||||
|
frame = WasmCompiledFrame::cast(it.frame());
|
||||||
|
}
|
||||||
|
|
||||||
if (static_cast<int>(frame->function_index()) != flooded_function_index_) {
|
if (static_cast<int>(frame->function_index()) != flooded_function_index_) {
|
||||||
FloodWithBreakpoints(frame->function_index(), isolate);
|
FloodWithBreakpoints(frame->function_index(), isolate);
|
||||||
flooded_function_index_ = frame->function_index();
|
flooded_function_index_ = frame->function_index();
|
||||||
@ -862,6 +871,19 @@ class DebugInfoImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsAtReturn(WasmCompiledFrame* frame) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
|
int position = frame->position();
|
||||||
|
NativeModule* native_module =
|
||||||
|
frame->wasm_instance().module_object().native_module();
|
||||||
|
uint8_t opcode = native_module->wire_bytes()[position];
|
||||||
|
if (opcode == kExprReturn) return true;
|
||||||
|
// Another implicit return is at the last kExprEnd in the function body.
|
||||||
|
int func_index = frame->function_index();
|
||||||
|
WireBytesRef code = native_module->module()->functions[func_index].code;
|
||||||
|
return static_cast<size_t>(position) == code.end_offset() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
NativeModule* const native_module_;
|
NativeModule* const native_module_;
|
||||||
|
|
||||||
// {mutex_} protects all fields below.
|
// {mutex_} protects all fields below.
|
||||||
|
@ -25,9 +25,33 @@ Paused at wasm://wasm/42af3c82:0:53
|
|||||||
Debugger.stepOver called
|
Debugger.stepOver called
|
||||||
Paused at wasm://wasm/42af3c82:0:54
|
Paused at wasm://wasm/42af3c82:0:54
|
||||||
Debugger.stepOver called
|
Debugger.stepOver called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:75
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:59
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:61
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:63
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:65
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:67
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:68
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:70
|
||||||
|
Debugger.stepInto called
|
||||||
Paused at wasm://wasm/42af3c82:0:73
|
Paused at wasm://wasm/42af3c82:0:73
|
||||||
Debugger.resume called
|
Debugger.stepInto called
|
||||||
Paused at wasm://wasm/42af3c82:0:52
|
Paused at wasm://wasm/42af3c82:0:52
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:53
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:54
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:75
|
||||||
|
Debugger.stepInto called
|
||||||
|
Paused at wasm://wasm/42af3c82:0:59
|
||||||
Debugger.resume called
|
Debugger.resume called
|
||||||
Paused at :0:24
|
Paused at :0:24
|
||||||
Debugger.resume called
|
Debugger.resume called
|
||||||
|
@ -102,11 +102,14 @@ function instantiate(bytes) {
|
|||||||
// Step out of wasm_A, back to wasm_B.
|
// Step out of wasm_A, back to wasm_B.
|
||||||
// TODO(clemensb/thibaudm): Replace by an actual 'stepOut'.
|
// TODO(clemensb/thibaudm): Replace by an actual 'stepOut'.
|
||||||
for (let i = 0; i < 3; ++i) await waitForPauseAndStep('stepOver');
|
for (let i = 0; i < 3; ++i) await waitForPauseAndStep('stepOver');
|
||||||
// Step over 10 times.
|
// Now step 10 times, until we are in wasm_A again.
|
||||||
// TODO(clemensb/thibaudm): Reenable once stepping over return works.
|
for (let i = 0; i < 10; ++i) await waitForPauseAndStep('stepInto');
|
||||||
//for (let i = 0; i < 10; ++i) await waitForPauseAndStep('stepOver');
|
// 3 more times, back to wasm_B.
|
||||||
// Resume three more times to continue over other breakpoints.
|
for (let i = 0; i < 3; ++i) await waitForPauseAndStep('stepInto');
|
||||||
for (let i = 0; i < 3; ++i) await waitForPauseAndStep('resume');
|
// Then just resume.
|
||||||
|
await waitForPauseAndStep('resume');
|
||||||
|
// TODO(clemensb/thibaudm): Figure out what this last break is (at ":0:24").
|
||||||
|
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');
|
||||||
|
Loading…
Reference in New Issue
Block a user