Commit 7e364f12 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Implement DebugBreak runtime function

This implements the runtime function for DebugBreak functionality in
Liftoff code. We find the Liftoff frame on the stack, get the position
within that frame, find breakpoints set at that position, and then call
{OnDebugBreak} with these breakpoints.

Note that one additional change is needed in order to make this actually
hit the right breakpoints. Once everything is in place, we will see a
change in the expected output in the wasm-set-breakpoint-liftoff test.

R=thibaudm@chromium.org

Bug: v8:10147
Change-Id: I5ca569a68aa436bbcf70739ea430efb9e459fad5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2036086
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66128}
parent a1e7895b
......@@ -28,15 +28,33 @@ namespace internal {
namespace {
template <typename FrameType, StackFrame::Type... skipped_frame_types>
class FrameFinder {
static_assert(sizeof...(skipped_frame_types) > 0,
"Specify at least one frame to skip");
public:
explicit FrameFinder(Isolate* isolate)
: frame_iterator_(isolate, isolate->thread_local_top()) {
for (auto type : {skipped_frame_types...}) {
DCHECK_EQ(type, frame_iterator_.frame()->type());
USE(type);
frame_iterator_.Advance();
}
// Type check the frame where the iterator stopped now.
DCHECK_NOT_NULL(frame());
}
FrameType* frame() { return FrameType::cast(frame_iterator_.frame()); }
private:
StackFrameIterator frame_iterator_;
};
WasmInstanceObject GetWasmInstanceOnStackTop(Isolate* isolate) {
StackFrameIterator it(isolate, isolate->thread_local_top());
// On top: C entry stub.
DCHECK_EQ(StackFrame::EXIT, it.frame()->type());
it.Advance();
// Next: the wasm compiled frame.
DCHECK(it.frame()->is_wasm_compiled());
WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame());
return frame->wasm_instance();
return FrameFinder<WasmCompiledFrame, StackFrame::EXIT>(isolate)
.frame()
->wasm_instance();
}
Context GetNativeContextFromWasmInstanceOnStackTop(Isolate* isolate) {
......@@ -194,15 +212,10 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
Handle<WasmInstanceObject> instance;
Address frame_pointer = 0;
{
StackFrameIterator it(isolate, isolate->thread_local_top());
// On top: C entry stub.
DCHECK_EQ(StackFrame::EXIT, it.frame()->type());
it.Advance();
// Next: the wasm interpreter entry.
DCHECK_EQ(StackFrame::WASM_INTERPRETER_ENTRY, it.frame()->type());
instance = handle(
WasmInterpreterEntryFrame::cast(it.frame())->wasm_instance(), isolate);
frame_pointer = it.frame()->fp();
FrameFinder<WasmInterpreterEntryFrame, StackFrame::EXIT> frame_finder(
isolate);
instance = handle(frame_finder.frame()->wasm_instance(), isolate);
frame_pointer = frame_finder.frame()->fp();
}
// Reserve buffers for argument and return values.
......@@ -333,13 +346,8 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) {
ClearThreadInWasmScope flag_scope;
#ifdef DEBUG
StackFrameIterator it(isolate, isolate->thread_local_top());
// On top: C entry stub.
DCHECK_EQ(StackFrame::EXIT, it.frame()->type());
it.Advance();
// Next: the wasm lazy compile frame.
DCHECK_EQ(StackFrame::WASM_COMPILE_LAZY, it.frame()->type());
DCHECK_EQ(*instance, WasmCompileLazyFrame::cast(it.frame())->wasm_instance());
FrameFinder<WasmCompileLazyFrame, StackFrame::EXIT> frame_finder(isolate);
DCHECK_EQ(*instance, frame_finder.frame()->wasm_instance());
#endif
DCHECK(isolate->context().is_null());
......@@ -606,8 +614,25 @@ RUNTIME_FUNCTION(Runtime_WasmNewMultiReturnJSArray) {
RUNTIME_FUNCTION(Runtime_WasmDebugBreak) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
FrameFinder<WasmCompiledFrame, StackFrame::EXIT, StackFrame::INTERNAL>
frame_finder(isolate);
auto instance = handle(frame_finder.frame()->wasm_instance(), isolate);
int position = frame_finder.frame()->position();
isolate->set_context(instance->native_context());
// TODO(clemensb): Implement.
// Enter the debugger.
DebugScope debug_scope(isolate->debug());
// Check whether we hit a breakpoint.
if (isolate->debug()->break_points_active()) {
Handle<Script> script(instance->module_object().script(), isolate);
Handle<FixedArray> breakpoints;
if (WasmScript::CheckBreakPoints(isolate, script, position)
.ToHandle(&breakpoints)) {
// We hit one or several breakpoints. Notify the debug listeners.
isolate->debug()->OnDebugBreak(breakpoints);
}
}
return ReadOnlyRoots(isolate).undefined_value();
}
......
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