Commit 7d43d533 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Move break point info list from module to Script.

This moves the list of {BreakPointInfo} objects from {WasmModuleObject}
to the corresponding {Script} object. Breakpoints are expected to affect
all modules/instances for a given script, hence the new placement of the
list is a preparation to fully support per-script breakpoints.

R=clemensb@chromium.org
BUG=v8:6847,chromium:893069

Change-Id: Id97058be5ed79cfdba2cecac5733ba161a6021d5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1852127Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64213}
parent c4063276
...@@ -9268,9 +9268,9 @@ bool debug::Script::GetPossibleBreakpoints( ...@@ -9268,9 +9268,9 @@ bool debug::Script::GetPossibleBreakpoints(
i::Handle<i::Script> script = Utils::OpenHandle(this); i::Handle<i::Script> script = Utils::OpenHandle(this);
if (script->type() == i::Script::TYPE_WASM && if (script->type() == i::Script::TYPE_WASM &&
this->SourceMappingURL().IsEmpty()) { this->SourceMappingURL().IsEmpty()) {
i::WasmModuleObject module_object = i::wasm::NativeModule* native_module = script->wasm_native_module();
i::WasmModuleObject::cast(script->wasm_module_object()); return i::WasmModuleObject::GetPossibleBreakpoints(native_module, start,
return module_object.GetPossibleBreakpoints(start, end, locations); end, locations);
} }
i::Script::InitLineEnds(script); i::Script::InitLineEnds(script);
......
...@@ -1594,7 +1594,6 @@ extern class WasmModuleObject extends JSObject { ...@@ -1594,7 +1594,6 @@ extern class WasmModuleObject extends JSObject {
export_wrappers: FixedArray; export_wrappers: FixedArray;
script: Script; script: Script;
asm_js_offset_table: ByteArray | Undefined; asm_js_offset_table: ByteArray | Undefined;
break_point_infos: FixedArray | Undefined;
} }
extern class WasmTableObject extends JSObject { extern class WasmTableObject extends JSObject {
......
...@@ -622,9 +622,7 @@ bool Debug::SetBreakPointForScript(Handle<Script> script, ...@@ -622,9 +622,7 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
Handle<BreakPoint> break_point = Handle<BreakPoint> break_point =
isolate_->factory()->NewBreakPoint(*id, condition); isolate_->factory()->NewBreakPoint(*id, condition);
if (script->type() == Script::TYPE_WASM) { if (script->type() == Script::TYPE_WASM) {
Handle<WasmModuleObject> module_object( return WasmModuleObject::SetBreakPoint(script, source_position,
WasmModuleObject::cast(script->wasm_module_object()), isolate_);
return WasmModuleObject::SetBreakPoint(module_object, source_position,
break_point); break_point);
} }
......
...@@ -1916,9 +1916,6 @@ void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) { // NOLINT ...@@ -1916,9 +1916,6 @@ void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) { // NOLINT
if (has_asm_js_offset_table()) { if (has_asm_js_offset_table()) {
os << "\n - asm_js_offset_table: " << Brief(asm_js_offset_table()); os << "\n - asm_js_offset_table: " << Brief(asm_js_offset_table());
} }
if (has_breakpoint_infos()) {
os << "\n - breakpoint_infos: " << Brief(breakpoint_infos());
}
os << "\n"; os << "\n";
} }
...@@ -2151,6 +2148,9 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT ...@@ -2151,6 +2148,9 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT
os << "\n - wrapped arguments: " << Brief(wrapped_arguments()); os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
} }
os << "\n - eval from position: " << eval_from_position(); os << "\n - eval from position: " << eval_from_position();
if (has_wasm_breakpoint_infos()) {
os << "\n - wasm_breakpoint_infos: " << Brief(wasm_breakpoint_infos());
}
os << "\n - shared function infos: " << Brief(shared_function_infos()); os << "\n - shared function infos: " << Brief(shared_function_infos());
os << "\n"; os << "\n";
} }
......
...@@ -40,7 +40,7 @@ SMI_ACCESSORS(Script, flags, kFlagsOffset) ...@@ -40,7 +40,7 @@ SMI_ACCESSORS(Script, flags, kFlagsOffset)
ACCESSORS(Script, source_url, Object, kSourceUrlOffset) ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset) ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
ACCESSORS(Script, host_defined_options, FixedArray, kHostDefinedOptionsOffset) ACCESSORS(Script, host_defined_options, FixedArray, kHostDefinedOptionsOffset)
ACCESSORS_CHECKED(Script, wasm_module_object, Object, ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray,
kEvalFromSharedOrWrappedArgumentsOffset, kEvalFromSharedOrWrappedArgumentsOffset,
this->type() == TYPE_WASM) this->type() == TYPE_WASM)
ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object, ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object,
...@@ -91,6 +91,10 @@ void Script::set_shared_function_infos(WeakFixedArray value, ...@@ -91,6 +91,10 @@ void Script::set_shared_function_infos(WeakFixedArray value,
CONDITIONAL_WRITE_BARRIER(*this, kSharedFunctionInfosOffset, value, mode); CONDITIONAL_WRITE_BARRIER(*this, kSharedFunctionInfosOffset, value, mode);
} }
bool Script::has_wasm_breakpoint_infos() const {
return type() == TYPE_WASM && wasm_breakpoint_infos().length() > 0;
}
wasm::NativeModule* Script::wasm_native_module() const { wasm::NativeModule* Script::wasm_native_module() const {
return Managed<wasm::NativeModule>::cast(wasm_managed_native_module()).raw(); return Managed<wasm::NativeModule>::cast(wasm_managed_native_module()).raw();
} }
......
...@@ -103,9 +103,11 @@ class Script : public Struct { ...@@ -103,9 +103,11 @@ class Script : public Struct {
// [source_mapping_url]: sourceMappingURL magic comment // [source_mapping_url]: sourceMappingURL magic comment
DECL_ACCESSORS(source_mapping_url, Object) DECL_ACCESSORS(source_mapping_url, Object)
// [wasm_module_object]: the wasm module object this script belongs to. // [wasm_breakpoint_infos]: the list of {BreakPointInfo} objects describing
// all WebAssembly breakpoints for modules/instances managed via this script.
// This must only be called if the type of this script is TYPE_WASM. // This must only be called if the type of this script is TYPE_WASM.
DECL_ACCESSORS(wasm_module_object, Object) DECL_ACCESSORS(wasm_breakpoint_infos, FixedArray)
inline bool has_wasm_breakpoint_infos() const;
// [wasm_native_module]: the wasm {NativeModule} this script belongs to. // [wasm_native_module]: the wasm {NativeModule} this script belongs to.
// This must only be called if the type of this script is TYPE_WASM. // This must only be called if the type of this script is TYPE_WASM.
......
...@@ -536,7 +536,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -536,7 +536,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
// Debugging support. // Debugging support.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Set all breakpoints that were set on the shared module. // Set all breakpoints that were set on the shared module.
WasmModuleObject::SetBreakpointsOnNewInstance(module_object_, instance); WasmModuleObject::SetBreakpointsOnNewInstance(
handle(module_object_->script(), isolate_), instance);
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Create a wrapper for the start function. // Create a wrapper for the start function.
......
...@@ -277,9 +277,10 @@ class InterpreterHandle { ...@@ -277,9 +277,10 @@ class InterpreterHandle {
if (isolate_->debug()->break_points_active()) { if (isolate_->debug()->break_points_active()) {
Handle<WasmModuleObject> module_object( Handle<WasmModuleObject> module_object(
GetInstanceObject()->module_object(), isolate_); GetInstanceObject()->module_object(), isolate_);
Handle<Script> script(module_object->script(), isolate_);
int position = GetTopPosition(module_object); int position = GetTopPosition(module_object);
Handle<FixedArray> breakpoints; Handle<FixedArray> breakpoints;
if (WasmModuleObject::CheckBreakPoints(isolate_, module_object, position) if (WasmModuleObject::CheckBreakPoints(isolate_, script, position)
.ToHandle(&breakpoints)) { .ToHandle(&breakpoints)) {
// We hit one or several breakpoints. Clear stepping, notify the // We hit one or several breakpoints. Clear stepping, notify the
// listeners and return. // listeners and return.
......
...@@ -90,8 +90,6 @@ ACCESSORS(WasmModuleObject, export_wrappers, FixedArray, kExportWrappersOffset) ...@@ -90,8 +90,6 @@ ACCESSORS(WasmModuleObject, export_wrappers, FixedArray, kExportWrappersOffset)
ACCESSORS(WasmModuleObject, script, Script, kScriptOffset) ACCESSORS(WasmModuleObject, script, Script, kScriptOffset)
OPTIONAL_ACCESSORS(WasmModuleObject, asm_js_offset_table, ByteArray, OPTIONAL_ACCESSORS(WasmModuleObject, asm_js_offset_table, ByteArray,
kAsmJsOffsetTableOffset) kAsmJsOffsetTableOffset)
OPTIONAL_ACCESSORS(WasmModuleObject, breakpoint_infos, FixedArray,
kBreakPointInfosOffset)
wasm::NativeModule* WasmModuleObject::native_module() const { wasm::NativeModule* WasmModuleObject::native_module() const {
return managed_native_module().raw(); return managed_native_module().raw();
} }
...@@ -103,10 +101,6 @@ const wasm::WasmModule* WasmModuleObject::module() const { ...@@ -103,10 +101,6 @@ const wasm::WasmModule* WasmModuleObject::module() const {
// TODO(clemensb): Remove this helper (inline in callers). // TODO(clemensb): Remove this helper (inline in callers).
return native_module()->module(); return native_module()->module();
} }
void WasmModuleObject::reset_breakpoint_infos() {
WRITE_FIELD(*this, kBreakPointInfosOffset,
GetReadOnlyRoots().undefined_value());
}
bool WasmModuleObject::is_asm_js() { bool WasmModuleObject::is_asm_js() {
bool asm_js = is_asmjs_module(module()); bool asm_js = is_asmjs_module(module());
DCHECK_EQ(asm_js, script().IsUserJavaScript()); DCHECK_EQ(asm_js, script().IsUserJavaScript());
......
...@@ -242,7 +242,8 @@ Handle<WasmModuleObject> WasmModuleObject::New( ...@@ -242,7 +242,8 @@ Handle<WasmModuleObject> WasmModuleObject::New(
isolate->factory()->NewJSObject(isolate->wasm_module_constructor())); isolate->factory()->NewJSObject(isolate->wasm_module_constructor()));
module_object->set_export_wrappers(*export_wrappers); module_object->set_export_wrappers(*export_wrappers);
if (script->type() == Script::TYPE_WASM) { if (script->type() == Script::TYPE_WASM) {
script->set_wasm_module_object(*module_object); script->set_wasm_breakpoint_infos(
ReadOnlyRoots(isolate).empty_fixed_array());
script->set_wasm_managed_native_module(*managed_native_module); script->set_wasm_managed_native_module(*managed_native_module);
script->set_wasm_weak_instance_list( script->set_wasm_weak_instance_list(
ReadOnlyRoots(isolate).empty_weak_array_list()); ReadOnlyRoots(isolate).empty_weak_array_list());
...@@ -253,13 +254,12 @@ Handle<WasmModuleObject> WasmModuleObject::New( ...@@ -253,13 +254,12 @@ Handle<WasmModuleObject> WasmModuleObject::New(
} }
// static // static
bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object, bool WasmModuleObject::SetBreakPoint(Handle<Script> script, int* position,
int* position,
Handle<BreakPoint> break_point) { Handle<BreakPoint> break_point) {
Isolate* isolate = module_object->GetIsolate(); Isolate* isolate = script->GetIsolate();
// Find the function for this breakpoint. // Find the function for this breakpoint.
const WasmModule* module = module_object->module(); const WasmModule* module = script->wasm_native_module()->module();
int func_index = GetContainingWasmFunction(module, *position); int func_index = GetContainingWasmFunction(module, *position);
if (func_index < 0) return false; if (func_index < 0) return false;
const WasmFunction& func = module->functions[func_index]; const WasmFunction& func = module->functions[func_index];
...@@ -267,16 +267,16 @@ bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object, ...@@ -267,16 +267,16 @@ bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object,
// According to the current design, we should only be called with valid // According to the current design, we should only be called with valid
// breakable positions. // breakable positions.
DCHECK(IsBreakablePosition(module_object->native_module(), func_index, DCHECK(IsBreakablePosition(script->wasm_native_module(), func_index,
offset_in_func)); offset_in_func));
// Insert new break point into break_positions of module object. // Insert new break point into break_positions of module object.
WasmModuleObject::AddBreakpointToInfo(module_object, *position, break_point); WasmModuleObject::AddBreakpointToInfo(script, *position, break_point);
// Iterate over all instances and tell them to set this new breakpoint. // Iterate over all instances and tell them to set this new breakpoint.
// We do this using the weak list of all instances from the script. // We do this using the weak list of all instances from the script.
Handle<WeakArrayList> weak_instance_list( Handle<WeakArrayList> weak_instance_list(script->wasm_weak_instance_list(),
module_object->script().wasm_weak_instance_list(), isolate); isolate);
for (int i = 0; i < weak_instance_list->length(); ++i) { for (int i = 0; i < weak_instance_list->length(); ++i) {
MaybeObject maybe_instance = weak_instance_list->Get(i); MaybeObject maybe_instance = weak_instance_list->Get(i);
if (maybe_instance->IsWeak()) { if (maybe_instance->IsWeak()) {
...@@ -293,27 +293,26 @@ bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object, ...@@ -293,27 +293,26 @@ bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object,
} }
// static // static
bool WasmModuleObject::ClearBreakPoint(Handle<WasmModuleObject> module_object, bool WasmModuleObject::ClearBreakPoint(Handle<Script> script, int position,
int position,
Handle<BreakPoint> break_point) { Handle<BreakPoint> break_point) {
Isolate* isolate = module_object->GetIsolate(); Isolate* isolate = script->GetIsolate();
// Find the function for this breakpoint. // Find the function for this breakpoint.
const WasmModule* module = module_object->module(); const WasmModule* module = script->wasm_native_module()->module();
int func_index = GetContainingWasmFunction(module, position); int func_index = GetContainingWasmFunction(module, position);
if (func_index < 0) return false; if (func_index < 0) return false;
const WasmFunction& func = module->functions[func_index]; const WasmFunction& func = module->functions[func_index];
int offset_in_func = position - func.code.offset(); int offset_in_func = position - func.code.offset();
if (!WasmModuleObject::RemoveBreakpointFromInfo(module_object, position, if (!WasmModuleObject::RemoveBreakpointFromInfo(script, position,
break_point)) { break_point)) {
return false; return false;
} }
// Iterate over all instances and tell them to remove this breakpoint. // Iterate over all instances and tell them to remove this breakpoint.
// We do this using the weak list of all instances from the script. // We do this using the weak list of all instances from the script.
Handle<WeakArrayList> weak_instance_list( Handle<WeakArrayList> weak_instance_list(script->wasm_weak_instance_list(),
module_object->script().wasm_weak_instance_list(), isolate); isolate);
for (int i = 0; i < weak_instance_list->length(); ++i) { for (int i = 0; i < weak_instance_list->length(); ++i) {
MaybeObject maybe_instance = weak_instance_list->Get(i); MaybeObject maybe_instance = weak_instance_list->Get(i);
if (maybe_instance->IsWeak()) { if (maybe_instance->IsWeak()) {
...@@ -362,17 +361,16 @@ int FindBreakpointInfoInsertPos(Isolate* isolate, ...@@ -362,17 +361,16 @@ int FindBreakpointInfoInsertPos(Isolate* isolate,
} // namespace } // namespace
// static // static
void WasmModuleObject::AddBreakpointToInfo( void WasmModuleObject::AddBreakpointToInfo(Handle<Script> script, int position,
Handle<WasmModuleObject> module_object, int position, Handle<BreakPoint> break_point) {
Handle<BreakPoint> break_point) { Isolate* isolate = script->GetIsolate();
Isolate* isolate = module_object->GetIsolate();
Handle<FixedArray> breakpoint_infos; Handle<FixedArray> breakpoint_infos;
if (module_object->has_breakpoint_infos()) { if (script->has_wasm_breakpoint_infos()) {
breakpoint_infos = handle(module_object->breakpoint_infos(), isolate); breakpoint_infos = handle(script->wasm_breakpoint_infos(), isolate);
} else { } else {
breakpoint_infos = breakpoint_infos =
isolate->factory()->NewFixedArray(4, AllocationType::kOld); isolate->factory()->NewFixedArray(4, AllocationType::kOld);
module_object->set_breakpoint_infos(*breakpoint_infos); script->set_wasm_breakpoint_infos(*breakpoint_infos);
} }
int insert_pos = int insert_pos =
...@@ -396,7 +394,7 @@ void WasmModuleObject::AddBreakpointToInfo( ...@@ -396,7 +394,7 @@ void WasmModuleObject::AddBreakpointToInfo(
if (need_realloc) { if (need_realloc) {
new_breakpoint_infos = isolate->factory()->NewFixedArray( new_breakpoint_infos = isolate->factory()->NewFixedArray(
2 * breakpoint_infos->length(), AllocationType::kOld); 2 * breakpoint_infos->length(), AllocationType::kOld);
module_object->set_breakpoint_infos(*new_breakpoint_infos); script->set_wasm_breakpoint_infos(*new_breakpoint_infos);
// Copy over the entries [0, insert_pos). // Copy over the entries [0, insert_pos).
for (int i = 0; i < insert_pos; ++i) for (int i = 0; i < insert_pos; ++i)
new_breakpoint_infos->set(i, breakpoint_infos->get(i)); new_breakpoint_infos->set(i, breakpoint_infos->get(i));
...@@ -420,13 +418,11 @@ void WasmModuleObject::AddBreakpointToInfo( ...@@ -420,13 +418,11 @@ void WasmModuleObject::AddBreakpointToInfo(
// static // static
bool WasmModuleObject::RemoveBreakpointFromInfo( bool WasmModuleObject::RemoveBreakpointFromInfo(
Handle<WasmModuleObject> module_object, int position, Handle<Script> script, int position, Handle<BreakPoint> break_point) {
Handle<BreakPoint> break_point) { if (!script->has_wasm_breakpoint_infos()) return false;
if (!module_object->has_breakpoint_infos()) return false;
Isolate* isolate = module_object->GetIsolate(); Isolate* isolate = script->GetIsolate();
Handle<FixedArray> breakpoint_infos(module_object->breakpoint_infos(), Handle<FixedArray> breakpoint_infos(script->wasm_breakpoint_infos(), isolate);
isolate);
int pos = FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position); int pos = FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position);
...@@ -452,15 +448,13 @@ bool WasmModuleObject::RemoveBreakpointFromInfo( ...@@ -452,15 +448,13 @@ bool WasmModuleObject::RemoveBreakpointFromInfo(
} }
void WasmModuleObject::SetBreakpointsOnNewInstance( void WasmModuleObject::SetBreakpointsOnNewInstance(
Handle<WasmModuleObject> module_object, Handle<Script> script, Handle<WasmInstanceObject> instance) {
Handle<WasmInstanceObject> instance) { if (!script->has_wasm_breakpoint_infos()) return;
if (!module_object->has_breakpoint_infos()) return; Isolate* isolate = script->GetIsolate();
Isolate* isolate = module_object->GetIsolate();
Handle<WasmDebugInfo> debug_info = Handle<WasmDebugInfo> debug_info =
WasmInstanceObject::GetOrCreateDebugInfo(instance); WasmInstanceObject::GetOrCreateDebugInfo(instance);
Handle<FixedArray> breakpoint_infos(module_object->breakpoint_infos(), Handle<FixedArray> breakpoint_infos(script->wasm_breakpoint_infos(), isolate);
isolate);
// If the array exists, it should not be empty. // If the array exists, it should not be empty.
DCHECK_LT(0, breakpoint_infos->length()); DCHECK_LT(0, breakpoint_infos->length());
...@@ -476,7 +470,7 @@ void WasmModuleObject::SetBreakpointsOnNewInstance( ...@@ -476,7 +470,7 @@ void WasmModuleObject::SetBreakpointsOnNewInstance(
int position = breakpoint_info->source_position(); int position = breakpoint_info->source_position();
// Find the function for this breakpoint, and set the breakpoint. // Find the function for this breakpoint, and set the breakpoint.
const WasmModule* module = module_object->module(); const WasmModule* module = script->wasm_native_module()->module();
int func_index = GetContainingWasmFunction(module, position); int func_index = GetContainingWasmFunction(module, position);
DCHECK_LE(0, func_index); DCHECK_LE(0, func_index);
const WasmFunction& func = module->functions[func_index]; const WasmFunction& func = module->functions[func_index];
...@@ -602,12 +596,15 @@ int WasmModuleObject::GetSourcePosition(Handle<WasmModuleObject> module_object, ...@@ -602,12 +596,15 @@ int WasmModuleObject::GetSourcePosition(Handle<WasmModuleObject> module_object,
return offset_table->get_int(kOTESize * left + idx); return offset_table->get_int(kOTESize * left + idx);
} }
// static
bool WasmModuleObject::GetPossibleBreakpoints( bool WasmModuleObject::GetPossibleBreakpoints(
const v8::debug::Location& start, const v8::debug::Location& end, wasm::NativeModule* native_module, const v8::debug::Location& start,
const v8::debug::Location& end,
std::vector<v8::debug::BreakLocation>* locations) { std::vector<v8::debug::BreakLocation>* locations) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
const std::vector<WasmFunction>& functions = module()->functions; const std::vector<WasmFunction>& functions =
native_module->module()->functions;
if (start.GetLineNumber() < 0 || start.GetColumnNumber() < 0 || if (start.GetLineNumber() < 0 || start.GetColumnNumber() < 0 ||
(!end.IsEmpty() && (!end.IsEmpty() &&
(end.GetLineNumber() < 0 || end.GetColumnNumber() < 0))) (end.GetLineNumber() < 0 || end.GetColumnNumber() < 0)))
...@@ -649,7 +646,7 @@ bool WasmModuleObject::GetPossibleBreakpoints( ...@@ -649,7 +646,7 @@ bool WasmModuleObject::GetPossibleBreakpoints(
AccountingAllocator alloc; AccountingAllocator alloc;
Zone tmp(&alloc, ZONE_NAME); Zone tmp(&alloc, ZONE_NAME);
const byte* module_start = native_module()->wire_bytes().begin(); const byte* module_start = native_module->wire_bytes().begin();
for (uint32_t func_idx = start_func_index; func_idx <= end_func_index; for (uint32_t func_idx = start_func_index; func_idx <= end_func_index;
++func_idx) { ++func_idx) {
...@@ -674,12 +671,12 @@ bool WasmModuleObject::GetPossibleBreakpoints( ...@@ -674,12 +671,12 @@ bool WasmModuleObject::GetPossibleBreakpoints(
return true; return true;
} }
// static
MaybeHandle<FixedArray> WasmModuleObject::CheckBreakPoints( MaybeHandle<FixedArray> WasmModuleObject::CheckBreakPoints(
Isolate* isolate, Handle<WasmModuleObject> module_object, int position) { Isolate* isolate, Handle<Script> script, int position) {
if (!module_object->has_breakpoint_infos()) return {}; if (!script->has_wasm_breakpoint_infos()) return {};
Handle<FixedArray> breakpoint_infos(module_object->breakpoint_infos(), Handle<FixedArray> breakpoint_infos(script->wasm_breakpoint_infos(), isolate);
isolate);
int insert_pos = int insert_pos =
FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position); FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position);
if (insert_pos >= breakpoint_infos->length()) return {}; if (insert_pos >= breakpoint_infos->length()) return {};
......
...@@ -127,12 +127,10 @@ class WasmModuleObject : public JSObject { ...@@ -127,12 +127,10 @@ class WasmModuleObject : public JSObject {
DECL_ACCESSORS(export_wrappers, FixedArray) DECL_ACCESSORS(export_wrappers, FixedArray)
DECL_ACCESSORS(script, Script) DECL_ACCESSORS(script, Script)
DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray) DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray)
DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray)
inline wasm::NativeModule* native_module() const; inline wasm::NativeModule* native_module() const;
inline const std::shared_ptr<wasm::NativeModule>& shared_native_module() inline const std::shared_ptr<wasm::NativeModule>& shared_native_module()
const; const;
inline const wasm::WasmModule* module() const; inline const wasm::WasmModule* module() const;
inline void reset_breakpoint_infos();
// Dispatched behavior. // Dispatched behavior.
DECL_PRINTER(WasmModuleObject) DECL_PRINTER(WasmModuleObject)
...@@ -154,26 +152,28 @@ class WasmModuleObject : public JSObject { ...@@ -154,26 +152,28 @@ class WasmModuleObject : public JSObject {
Handle<Script> script, Handle<FixedArray> export_wrappers, Handle<Script> script, Handle<FixedArray> export_wrappers,
size_t code_size_estimate); size_t code_size_estimate);
// TODO(mstarzinger): The below breakpoint handling methods taking a {Script}
// instead of a {WasmModuleObject} as first argument should be moved onto a
// separate {WasmScript} class, implementation move to wasm-debug.cc then.
// Set a breakpoint on the given byte position inside the given module. // Set a breakpoint on the given byte position inside the given module.
// This will affect all live and future instances of the module. // This will affect all live and future instances of the module.
// The passed position might be modified to point to the next breakable // The passed position might be modified to point to the next breakable
// location inside the same function. // location inside the same function.
// If it points outside a function, or behind the last breakable location, // If it points outside a function, or behind the last breakable location,
// this function returns false and does not set any breakpoint. // this function returns false and does not set any breakpoint.
V8_EXPORT_PRIVATE static bool SetBreakPoint(Handle<WasmModuleObject>, V8_EXPORT_PRIVATE static bool SetBreakPoint(Handle<Script>, int* position,
int* position,
Handle<BreakPoint> break_point); Handle<BreakPoint> break_point);
// Remove a previously set breakpoint at the given byte position inside the // Remove a previously set breakpoint at the given byte position inside the
// given module. If this breakpoint is not found this function returns false. // given module. If this breakpoint is not found this function returns false.
V8_EXPORT_PRIVATE static bool ClearBreakPoint(Handle<WasmModuleObject>, V8_EXPORT_PRIVATE static bool ClearBreakPoint(Handle<Script>, int position,
int position,
Handle<BreakPoint> break_point); Handle<BreakPoint> break_point);
// Check whether this module was generated from asm.js source. // Check whether this module was generated from asm.js source.
inline bool is_asm_js(); inline bool is_asm_js();
static void SetBreakpointsOnNewInstance(Handle<WasmModuleObject>, static void SetBreakpointsOnNewInstance(Handle<Script>,
Handle<WasmInstanceObject>); Handle<WasmInstanceObject>);
// Get the module name, if set. Returns an empty handle otherwise. // Get the module name, if set. Returns an empty handle otherwise.
...@@ -215,24 +215,23 @@ class WasmModuleObject : public JSObject { ...@@ -215,24 +215,23 @@ class WasmModuleObject : public JSObject {
wasm::WireBytesRef ref); wasm::WireBytesRef ref);
// Get a list of all possible breakpoints within a given range of this module. // Get a list of all possible breakpoints within a given range of this module.
V8_EXPORT_PRIVATE bool GetPossibleBreakpoints( V8_EXPORT_PRIVATE static bool GetPossibleBreakpoints(
const debug::Location& start, const debug::Location& end, wasm::NativeModule* native_module, const debug::Location& start,
std::vector<debug::BreakLocation>* locations); const debug::Location& end, std::vector<debug::BreakLocation>* locations);
// Return an empty handle if no breakpoint is hit at that location, or a // Return an empty handle if no breakpoint is hit at that location, or a
// FixedArray with all hit breakpoint objects. // FixedArray with all hit breakpoint objects.
static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, Handle<Script>,
Handle<WasmModuleObject>,
int position); int position);
OBJECT_CONSTRUCTORS(WasmModuleObject, JSObject); OBJECT_CONSTRUCTORS(WasmModuleObject, JSObject);
private: private:
// Helper functions that update the breakpoint info list. // Helper functions that update the breakpoint info list.
static void AddBreakpointToInfo(Handle<WasmModuleObject>, int position, static void AddBreakpointToInfo(Handle<Script>, int position,
Handle<BreakPoint> break_point); Handle<BreakPoint> break_point);
static bool RemoveBreakpointFromInfo(Handle<WasmModuleObject>, int position, static bool RemoveBreakpointFromInfo(Handle<Script>, int position,
Handle<BreakPoint> break_point); Handle<BreakPoint> break_point);
}; };
......
...@@ -22,10 +22,11 @@ namespace wasm { ...@@ -22,10 +22,11 @@ namespace wasm {
namespace { namespace {
void CheckLocations( void CheckLocations(
WasmModuleObject module_object, debug::Location start, debug::Location end, NativeModule* native_module, debug::Location start, debug::Location end,
std::initializer_list<debug::Location> expected_locations_init) { std::initializer_list<debug::Location> expected_locations_init) {
std::vector<debug::BreakLocation> locations; std::vector<debug::BreakLocation> locations;
bool success = module_object.GetPossibleBreakpoints(start, end, &locations); bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start,
end, &locations);
CHECK(success); CHECK(success);
printf("got %d locations: ", static_cast<int>(locations.size())); printf("got %d locations: ", static_cast<int>(locations.size()));
...@@ -45,10 +46,11 @@ void CheckLocations( ...@@ -45,10 +46,11 @@ void CheckLocations(
} }
} }
void CheckLocationsFail(WasmModuleObject module_object, debug::Location start, void CheckLocationsFail(NativeModule* native_module, debug::Location start,
debug::Location end) { debug::Location end) {
std::vector<debug::BreakLocation> locations; std::vector<debug::BreakLocation> locations;
bool success = module_object.GetPossibleBreakpoints(start, end, &locations); bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start,
end, &locations);
CHECK(!success); CHECK(!success);
} }
...@@ -125,14 +127,13 @@ Handle<BreakPoint> SetBreakpoint(WasmRunnerBase* runner, int function_index, ...@@ -125,14 +127,13 @@ Handle<BreakPoint> SetBreakpoint(WasmRunnerBase* runner, int function_index,
int code_offset = func_offset + byte_offset; int code_offset = func_offset + byte_offset;
if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset; if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset;
Handle<WasmInstanceObject> instance = runner->builder().instance_object(); Handle<WasmInstanceObject> instance = runner->builder().instance_object();
Handle<WasmModuleObject> module_object(instance->module_object(), Handle<Script> script(instance->module_object().script(),
runner->main_isolate()); runner->main_isolate());
static int break_index = 0; static int break_index = 0;
Handle<BreakPoint> break_point = Handle<BreakPoint> break_point =
runner->main_isolate()->factory()->NewBreakPoint( runner->main_isolate()->factory()->NewBreakPoint(
break_index++, runner->main_isolate()->factory()->empty_string()); break_index++, runner->main_isolate()->factory()->empty_string());
CHECK(WasmModuleObject::SetBreakPoint(module_object, &code_offset, CHECK(WasmModuleObject::SetBreakPoint(script, &code_offset, break_point));
break_point));
int set_byte_offset = code_offset - func_offset; int set_byte_offset = code_offset - func_offset;
CHECK_EQ(expected_set_byte_offset, set_byte_offset); CHECK_EQ(expected_set_byte_offset, set_byte_offset);
// Also set breakpoint on the debug info of the instance directly, since the // Also set breakpoint on the debug info of the instance directly, since the
...@@ -150,10 +151,9 @@ void ClearBreakpoint(WasmRunnerBase* runner, int function_index, ...@@ -150,10 +151,9 @@ void ClearBreakpoint(WasmRunnerBase* runner, int function_index,
runner->builder().GetFunctionAt(function_index)->code.offset(); runner->builder().GetFunctionAt(function_index)->code.offset();
int code_offset = func_offset + byte_offset; int code_offset = func_offset + byte_offset;
Handle<WasmInstanceObject> instance = runner->builder().instance_object(); Handle<WasmInstanceObject> instance = runner->builder().instance_object();
Handle<WasmModuleObject> module_object(instance->module_object(), Handle<Script> script(instance->module_object().script(),
runner->main_isolate()); runner->main_isolate());
CHECK(WasmModuleObject::ClearBreakPoint(module_object, code_offset, CHECK(WasmModuleObject::ClearBreakPoint(script, code_offset, break_point));
break_point));
// Also clear breakpoint on the debug info of the instance directly, since the // Also clear breakpoint on the debug info of the instance directly, since the
// instance chain is not setup properly in tests. // instance chain is not setup properly in tests.
Handle<WasmDebugInfo> debug_info = Handle<WasmDebugInfo> debug_info =
...@@ -271,25 +271,25 @@ WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) { ...@@ -271,25 +271,25 @@ WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) {
BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE)); BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE));
WasmInstanceObject instance = *runner.builder().instance_object(); WasmInstanceObject instance = *runner.builder().instance_object();
WasmModuleObject module_object = instance.module_object(); NativeModule* native_module = instance.module_object().native_module();
std::vector<debug::Location> locations; std::vector<debug::Location> locations;
// Check all locations for function 0. // Check all locations for function 0.
CheckLocations(module_object, {0, 0}, {1, 0}, CheckLocations(native_module, {0, 0}, {1, 0},
{{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}}); {{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}});
// Check a range ending at an instruction. // Check a range ending at an instruction.
CheckLocations(module_object, {0, 2}, {0, 4}, {{0, 2}}); CheckLocations(native_module, {0, 2}, {0, 4}, {{0, 2}});
// Check a range ending one behind an instruction. // Check a range ending one behind an instruction.
CheckLocations(module_object, {0, 2}, {0, 5}, {{0, 2}, {0, 4}}); CheckLocations(native_module, {0, 2}, {0, 5}, {{0, 2}, {0, 4}});
// Check a range starting at an instruction. // Check a range starting at an instruction.
CheckLocations(module_object, {0, 7}, {0, 8}, {{0, 7}}); CheckLocations(native_module, {0, 7}, {0, 8}, {{0, 7}});
// Check from an instruction to beginning of next function. // Check from an instruction to beginning of next function.
CheckLocations(module_object, {0, 7}, {1, 0}, {{0, 7}}); CheckLocations(native_module, {0, 7}, {1, 0}, {{0, 7}});
// Check from end of one function (no valid instruction position) to beginning // Check from end of one function (no valid instruction position) to beginning
// of next function. Must be empty, but not fail. // of next function. Must be empty, but not fail.
CheckLocations(module_object, {0, 8}, {1, 0}, {}); CheckLocations(native_module, {0, 8}, {1, 0}, {});
// Check from one after the end of the function. Must fail. // Check from one after the end of the function. Must fail.
CheckLocationsFail(module_object, {0, 9}, {1, 0}); CheckLocationsFail(native_module, {0, 9}, {1, 0});
} }
WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) { WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) {
......
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