Commit 11fa409a authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Add {wasm::DebugInfo} class for Liftoff inspection

This adds a {wasm::DebugInfo} struct which will hold the
{wasm::DebugSideTable}s for individual Liftoff functions, and will use
them to construct local scope information.

R=jkummerow@chromium.org, bmeurer@chromium.org

Bug: v8:10019
Change-Id: I7869cec5000e9b126c891a242fcccfc53c67662e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1975758
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65563}
parent 15ec4a09
......@@ -143,9 +143,7 @@ bool DebugWasmScopeIterator::Done() {
void DebugWasmScopeIterator::Advance() {
DCHECK(!Done());
// Local scope information is only available for interpreted frames currently.
if (type_ == debug::ScopeIterator::ScopeTypeGlobal &&
frame_->is_wasm_interpreter_entry()) {
if (type_ == debug::ScopeIterator::ScopeTypeGlobal) {
type_ = debug::ScopeIterator::ScopeTypeLocal;
} else {
// We use ScopeTypeWith type as marker for done.
......@@ -167,15 +165,22 @@ v8::Local<v8::Object> DebugWasmScopeIterator::GetObject() {
return Utils::ToLocal(wasm::GetGlobalScopeObject(instance));
}
case debug::ScopeIterator::ScopeTypeLocal: {
Handle<WasmDebugInfo> debug_info(
WasmInterpreterEntryFrame::cast(frame_)->debug_info(), isolate_);
return Utils::ToLocal(WasmDebugInfo::GetLocalScopeObject(
debug_info, frame_->fp(), inlined_frame_index_));
if (frame_->is_wasm_interpreter_entry()) {
Handle<WasmDebugInfo> debug_info(
WasmInterpreterEntryFrame::cast(frame_)->debug_info(), isolate_);
return Utils::ToLocal(WasmDebugInfo::GetLocalScopeObject(
debug_info, frame_->fp(), inlined_frame_index_));
}
// Compiled code.
DCHECK(frame_->is_wasm_compiled());
wasm::DebugInfo* debug_info =
WasmCompiledFrame::cast(frame_)->native_module()->GetDebugInfo();
return Utils::ToLocal(debug_info->GetLocalScopeObject(
isolate_, frame_->pc(), frame_->fp()));
}
default:
return v8::Local<v8::Object>();
return {};
}
return v8::Local<v8::Object>();
}
int DebugWasmScopeIterator::GetScriptId() {
......
......@@ -1903,6 +1903,10 @@ WasmInstanceObject WasmCompiledFrame::wasm_instance() const {
return WasmInstanceObject::cast(instance);
}
wasm::NativeModule* WasmCompiledFrame::native_module() const {
return module_object().native_module();
}
WasmModuleObject WasmCompiledFrame::module_object() const {
return wasm_instance().module_object();
}
......
......@@ -950,6 +950,7 @@ class WasmCompiledFrame : public StandardFrame {
// Accessors.
WasmInstanceObject wasm_instance() const;
wasm::NativeModule* native_module() const;
wasm::WasmCode* wasm_code() const;
uint32_t function_index() const;
Script script() const override;
......
......@@ -24,6 +24,7 @@
#include "src/wasm/compilation-environment.h"
#include "src/wasm/function-compiler.h"
#include "src/wasm/jump-table-assembler.h"
#include "src/wasm/wasm-debug.h"
#include "src/wasm/wasm-import-wrapper-cache.h"
#include "src/wasm/wasm-module-sourcemap.h"
#include "src/wasm/wasm-module.h"
......@@ -1854,6 +1855,12 @@ size_t NativeModule::GetNumberOfCodeSpacesForTesting() const {
return code_allocator_.GetNumCodeSpaces();
}
DebugInfo* NativeModule::GetDebugInfo() {
base::MutexGuard guard(&allocation_mutex_);
if (!debug_info_) debug_info_ = std::make_unique<DebugInfo>(this);
return debug_info_.get();
}
void WasmCodeManager::FreeNativeModule(Vector<VirtualMemory> owned_code_space,
size_t committed_size) {
base::MutexGuard lock(&native_modules_mutex_);
......
......@@ -35,6 +35,7 @@ class Isolate;
namespace wasm {
class DebugInfo;
class NativeModule;
class WasmCodeManager;
struct WasmCompilationResult;
......@@ -566,6 +567,9 @@ class V8_EXPORT_PRIVATE NativeModule final {
// Retrieve the number of separately reserved code spaces for this module.
size_t GetNumberOfCodeSpacesForTesting() const;
// Get or create the debug info for this NativeModule.
DebugInfo* GetDebugInfo();
private:
friend class WasmCode;
friend class WasmCodeAllocator;
......@@ -691,7 +695,15 @@ class V8_EXPORT_PRIVATE NativeModule final {
// Data (especially jump table) per code space.
std::vector<CodeSpaceData> code_space_data_;
// Whether we want all code to be Liftoff for debugging.
bool tier_down_ = false;
// Debug information for this module. You only need to hold the allocation
// mutex while getting the {DebugInfo} pointer, or initializing this field.
// Further accesses to the {DebugInfo} do not need to be protected by the
// mutex.
std::unique_ptr<DebugInfo> debug_info_;
// End of fields protected by {allocation_mutex_}.
//////////////////////////////////////////////////////////////////////////////
......
......@@ -494,6 +494,38 @@ Handle<JSObject> GetGlobalScopeObject(Handle<WasmInstanceObject> instance) {
return global_scope_object;
}
class DebugInfoImpl {
public:
explicit DebugInfoImpl(NativeModule* native_module)
: native_module_(native_module) {}
Handle<JSObject> GetLocalScopeObject(Isolate* isolate, Address pc,
Address fp) {
Handle<JSObject> local_scope_object =
isolate->factory()->NewJSObjectWithNullProto();
// TODO(clemensb): Fill this with actual values.
USE(native_module_);
return local_scope_object;
}
private:
NativeModule* const native_module_;
DISALLOW_COPY_AND_ASSIGN(DebugInfoImpl);
};
DebugInfo::DebugInfo(NativeModule* native_module)
: impl_(std::make_unique<DebugInfoImpl>(native_module)) {}
DebugInfo::~DebugInfo() = default;
Handle<JSObject> DebugInfo::GetLocalScopeObject(Isolate* isolate, Address pc,
Address fp) {
return impl_->GetLocalScopeObject(isolate, pc, fp);
}
} // namespace wasm
namespace {
......
......@@ -6,8 +6,10 @@
#define V8_WASM_WASM_DEBUG_H_
#include <algorithm>
#include <memory>
#include <vector>
#include "include/v8-internal.h"
#include "src/base/iterator.h"
#include "src/base/logging.h"
#include "src/base/macros.h"
......@@ -22,6 +24,9 @@ class WasmInstanceObject;
namespace wasm {
class DebugInfoImpl;
class NativeModule;
// Side table storing information used to inspect Liftoff frames at runtime.
// This table is only created on demand for debugging, so it is not optimized
// for memory size.
......@@ -106,6 +111,19 @@ class DebugSideTable {
// (if the instance has a memory) and the values of all globals.
Handle<JSObject> GetGlobalScopeObject(Handle<WasmInstanceObject>);
// Debug info per NativeModule, created lazily on demand.
// Implementation in {wasm-debug.cc} using PIMPL.
class DebugInfo {
public:
explicit DebugInfo(NativeModule*);
~DebugInfo();
Handle<JSObject> GetLocalScopeObject(Isolate*, Address pc, Address fp);
private:
std::unique_ptr<DebugInfoImpl> impl_;
};
} // namespace wasm
} // namespace internal
} // namespace v8
......
......@@ -801,6 +801,8 @@ class WasmJSFunctionData : public Struct {
OBJECT_CONSTRUCTORS(WasmJSFunctionData, Struct);
};
// Debug info used for wasm debugging in the interpreter. For Liftoff debugging,
// all information is held off-heap in {wasm::DebugInfo}.
class WasmDebugInfo : public Struct {
public:
NEVER_READ_ONLY_SPACE
......
......@@ -25,6 +25,7 @@ at func (2:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -44,6 +45,7 @@ at func (3:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -63,6 +65,7 @@ at func (4:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -82,6 +85,7 @@ at func (5:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -101,6 +105,7 @@ at func (6:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -120,6 +125,7 @@ at func (7:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -139,6 +145,7 @@ at func (8:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -158,6 +165,7 @@ at func (9:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -177,6 +185,7 @@ at func (10:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -196,6 +205,7 @@ at func (11:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -215,6 +225,7 @@ at func (12:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -234,6 +245,7 @@ at func (13:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -253,6 +265,7 @@ at func (14:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -272,6 +285,7 @@ at func (15:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -291,6 +305,7 @@ at func (16:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -310,6 +325,7 @@ at func (17:2):
at call_func (5:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -329,6 +345,7 @@ at func (18:0):
at call_func (5:2):
- scope (global):
globals: "global#0": 15 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......
......@@ -26,9 +26,11 @@ at C (interpreted) (2:2):
at B (liftoff) (7:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at A (liftoff) (2:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -48,9 +50,11 @@ at C (interpreted) (3:2):
at B (liftoff) (7:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at A (liftoff) (2:2):
- scope (global):
globals: "global#0": 0 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -70,9 +74,11 @@ at C (interpreted) (4:2):
at B (liftoff) (7:2):
- scope (global):
globals: "global#0": 42 (number)
- scope (local):
at A (liftoff) (2:2):
- scope (global):
globals: "global#0": 42 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -92,9 +98,11 @@ at C (interpreted) (5:2):
at B (liftoff) (7:2):
- scope (global):
globals: "global#0": 42 (number)
- scope (local):
at A (liftoff) (2:2):
- scope (global):
globals: "global#0": 42 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......@@ -114,9 +122,11 @@ at C (interpreted) (6:0):
at B (liftoff) (7:2):
- scope (global):
globals: "global#0": 42 (number)
- scope (local):
at A (liftoff) (2:2):
- scope (global):
globals: "global#0": 42 (number)
- scope (local):
at (anonymous) (0:17):
- scope (global):
-- skipped globals
......
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