Commit 2f3de27e authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Set and store breakpoints in wasm

Store breakpoint positions in the WasmSharedModuleData in order to set
them on new instantiations. Also redirect them to all live instances at
the time the breakpoint is set.

Inside the WasmDebugInfo, we store the BreakPointInfo objects to find
hit breakpoints.

R=titzer@chromium.org, yangguo@chromium.org
BUG=v8:5822

Review-Url: https://codereview.chromium.org/2626253002
Cr-Commit-Position: refs/heads/master@{#42443}
parent 7634b0eb
......@@ -29,6 +29,7 @@
#include "src/messages.h"
#include "src/snapshot/natives.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"
#include "include/v8-debug.h"
......@@ -516,30 +517,18 @@ void Debug::Break(JavaScriptFrame* frame) {
// Postpone interrupt during breakpoint processing.
PostponeInterruptsScope postpone(isolate_);
// Return if we fail to retrieve debug info for javascript frames.
if (frame->is_java_script()) {
JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
// Get the debug info (create it if it does not exist).
Handle<JSFunction> function(js_frame->function());
Handle<SharedFunctionInfo> shared(function->shared());
if (!EnsureDebugInfo(shared, function)) return;
}
// Return if we fail to retrieve debug info.
Handle<JSFunction> function(frame->function());
Handle<SharedFunctionInfo> shared(function->shared());
if (!EnsureDebugInfo(shared, function)) return;
BreakLocation location = BreakLocation::FromFrame(frame);
// Find actual break points, if any, and trigger debug break event.
MaybeHandle<FixedArray> break_points_hit;
if (!break_points_active()) {
// Don't try to find hit breakpoints.
} else if (frame->is_wasm_interpreter_entry()) {
// TODO(clemensh): Find hit breakpoints for wasm.
UNIMPLEMENTED();
} else {
if (break_points_active()) {
// Get the debug info, which must exist if we reach here.
Handle<DebugInfo> debug_info(
JavaScriptFrame::cast(frame)->function()->shared()->GetDebugInfo(),
isolate_);
Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
break_points_hit = CheckBreakPoints(debug_info, &location);
}
......@@ -722,9 +711,12 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
int* source_position,
BreakPositionAlignment alignment) {
if (script->type() == Script::TYPE_WASM) {
// TODO(clemensh): set breakpoint for wasm.
return false;
Handle<WasmCompiledModule> compiled_module(
WasmCompiledModule::cast(script->wasm_compiled_module()), isolate_);
return WasmCompiledModule::SetBreakPoint(compiled_module, source_position,
break_point_object);
}
HandleScope scope(isolate_);
// Obtain shared function info for the function.
......
......@@ -2478,6 +2478,13 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
return debug_info;
}
Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
Handle<BreakPointInfo> new_break_point_info =
Handle<BreakPointInfo>::cast(NewStruct(BREAK_POINT_INFO_TYPE));
new_break_point_info->set_source_position(source_position);
new_break_point_info->set_break_point_objects(*undefined_value());
return new_break_point_info;
}
Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
int length) {
......
......@@ -326,6 +326,8 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<Script> NewScript(Handle<String> source);
Handle<BreakPointInfo> NewBreakPointInfo(int source_position);
// Foreign objects are pretenured when allocated by the bootstrapper.
Handle<Foreign> NewForeign(Address addr,
PretenureFlag pretenure = NOT_TENURED);
......
......@@ -18599,11 +18599,8 @@ void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
DCHECK(index != kNoBreakPointInfo);
// Allocate new BreakPointInfo object and set the break point.
Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast(
isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE));
new_break_point_info->set_source_position(source_position);
new_break_point_info->set_break_point_objects(
isolate->heap()->undefined_value());
Handle<BreakPointInfo> new_break_point_info =
isolate->factory()->NewBreakPointInfo(source_position);
BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
debug_info->break_points()->set(index, *new_break_point_info);
}
......
......@@ -1430,6 +1430,13 @@ class WasmInstanceBuilder {
v8::WeakCallbackType::kFinalizer);
}
}
//--------------------------------------------------------------------------
// Set all breakpoints that were set on the shared module.
//--------------------------------------------------------------------------
WasmSharedModuleData::SetBreakpointsOnNewInstance(
compiled_module_->shared(), instance);
//--------------------------------------------------------------------------
// Run the start function if one was specified.
//--------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -5,6 +5,7 @@
#ifndef V8_WASM_OBJECTS_H_
#define V8_WASM_OBJECTS_H_
#include "src/debug/debug.h"
#include "src/debug/interface-types.h"
#include "src/objects-inl.h"
#include "src/trap-handler/trap-handler.h"
......@@ -36,6 +37,10 @@ class WasmInstanceWrapper;
bool has_##name(); \
DECLARE_ACCESSORS(name, type)
#define DECLARE_OPTIONAL_GETTER(name, type) \
bool has_##name(); \
DECLARE_GETTER(name, type)
// Representation of a WebAssembly.Module JavaScript-level object.
class WasmModuleObject : public JSObject {
public:
......@@ -158,6 +163,7 @@ class WasmSharedModuleData : public FixedArray {
kModuleBytes,
kScript,
kAsmJsOffsetTable,
kBreakPointInfos,
kFieldCount
};
......@@ -168,6 +174,7 @@ class WasmSharedModuleData : public FixedArray {
DECLARE_OPTIONAL_ACCESSORS(module_bytes, SeqOneByteString);
DECLARE_GETTER(script, Script);
DECLARE_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray);
DECLARE_OPTIONAL_GETTER(breakpoint_infos, FixedArray);
static Handle<WasmSharedModuleData> New(
Isolate* isolate, Handle<Foreign> module_wrapper,
......@@ -179,6 +186,12 @@ class WasmSharedModuleData : public FixedArray {
// Recreate the ModuleWrapper from the module bytes after deserialization.
static void RecreateModuleWrapper(Isolate*, Handle<WasmSharedModuleData>);
static void AddBreakpoint(Handle<WasmSharedModuleData>, int position,
Handle<Object> break_point_object);
static void SetBreakpointsOnNewInstance(Handle<WasmSharedModuleData>,
Handle<WasmInstanceObject>);
};
class WasmCompiledModule : public FixedArray {
......@@ -374,6 +387,15 @@ class WasmCompiledModule : public FixedArray {
const debug::Location& end,
std::vector<debug::Location>* locations);
// Set a breakpoint on the given byte position inside the given module.
// This will affect all live and future instances of the module.
// The passed position might be modified to point to the next breakable
// location inside the same function.
// If it points outside a function, or behind the last breakable location,
// this function returns false and does not set any breakpoint.
static bool SetBreakPoint(Handle<WasmCompiledModule>, int* position,
Handle<Object> break_point_object);
private:
void InitId();
......
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