Commit f47c6a5a authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Print debug side table together with code

For debugging (either with --print-wasm-code, or inspecting the current
code object in a debugger) it's helpful to also see the debug side
table, if available.

This CL adds print support for that, and uses it when printing wasm
code, and after generating a new debug side table.

R=thibaudm@chromium.org

Bug: v8:10359
Change-Id: I700b6eacb80f015212115e91b94c513e88c04288
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2202902
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67848}
parent 5ccf1bf9
......@@ -327,6 +327,12 @@ void WasmCode::Print(const char* name) const {
StdoutStream os;
os << "--- WebAssembly code ---\n";
Disassemble(name, os);
if (native_module_->HasDebugInfo()) {
if (auto* debug_side_table =
native_module_->GetDebugInfo()->GetDebugSideTableIfExists(this)) {
debug_side_table->Print(os);
}
}
os << "--- End code ---\n";
}
......@@ -923,7 +929,7 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
WasmCode::kFunction, // kind
ExecutionTier::kNone, // tier
kNoDebugging}}; // for_debugging
new_code->MaybePrint(nullptr);
new_code->MaybePrint();
new_code->Validate();
return PublishCode(std::move(new_code));
......@@ -1881,6 +1887,11 @@ size_t NativeModule::GetNumberOfCodeSpacesForTesting() const {
return code_allocator_.GetNumCodeSpaces();
}
bool NativeModule::HasDebugInfo() const {
base::MutexGuard guard(&allocation_mutex_);
return debug_info_ != nullptr;
}
DebugInfo* NativeModule::GetDebugInfo() {
base::MutexGuard guard(&allocation_mutex_);
if (!debug_info_) debug_info_ = std::make_unique<DebugInfo>(this);
......
......@@ -623,6 +623,9 @@ class V8_EXPORT_PRIVATE NativeModule final {
// Retrieve the number of separately reserved code spaces for this module.
size_t GetNumberOfCodeSpacesForTesting() const;
// Check whether there is DebugInfo for this NativeModule.
bool HasDebugInfo() const;
// Get or create the debug info for this NativeModule.
DebugInfo* GetDebugInfo();
......
......@@ -4,6 +4,7 @@
#include "src/wasm/wasm-debug.h"
#include <iomanip>
#include <unordered_map>
#include "src/base/optional.h"
......@@ -15,7 +16,6 @@
#include "src/execution/frames-inl.h"
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
#include "src/utils/identity-map.h"
#include "src/wasm/baseline/liftoff-compiler.h"
#include "src/wasm/baseline/liftoff-register.h"
#include "src/wasm/module-decoder.h"
......@@ -304,6 +304,32 @@ Address FindNewPC(WasmCode* wasm_code, int byte_offset,
} // namespace
void DebugSideTable::Print(std::ostream& os) const {
os << "Debug side table (" << num_locals_ << " locals, " << entries_.size()
<< " entries):\n";
for (auto& entry : entries_) entry.Print(os);
os << "\n";
}
void DebugSideTable::Entry::Print(std::ostream& os) const {
os << std::setw(6) << std::hex << pc_offset_ << std::dec << " [";
for (auto& value : values_) {
os << " " << value.type.type_name() << ":";
switch (value.kind) {
case kConstant:
os << "const#" << value.i32_const;
break;
case kRegister:
os << "reg#" << value.reg_code;
break;
case kStack:
os << "stack#" << value.stack_offset;
break;
}
}
os << " ]\n";
}
Handle<JSObject> GetModuleScopeObject(Handle<WasmInstanceObject> instance) {
Isolate* isolate = instance->GetIsolate();
......@@ -619,6 +645,12 @@ class DebugInfoImpl {
}
}
DebugSideTable* GetDebugSideTableIfExists(const WasmCode* code) const {
base::MutexGuard guard(&mutex_);
auto it = debug_side_tables_.find(code);
return it == debug_side_tables_.end() ? nullptr : it->second.get();
}
private:
struct FrameInspectionScope {
FrameInspectionScope(DebugInfoImpl* debug_info, Isolate* isolate,
......@@ -672,6 +704,9 @@ class DebugInfoImpl {
base::MutexGuard guard(&mutex_);
debug_side_tables_[code] = std::move(debug_side_table);
}
// Print the code together with the debug table, if requested.
code->MaybePrint();
return ret;
}
......@@ -794,7 +829,7 @@ class DebugInfoImpl {
mutable base::Mutex mutex_;
// DebugSideTable per code object, lazily initialized.
std::unordered_map<WasmCode*, std::unique_ptr<DebugSideTable>>
std::unordered_map<const WasmCode*, std::unique_ptr<DebugSideTable>>
debug_side_tables_;
// Names of locals, lazily decoded from the wire bytes.
......@@ -874,6 +909,11 @@ void DebugInfo::RemoveDebugSideTables(Vector<WasmCode* const> code) {
impl_->RemoveDebugSideTables(code);
}
DebugSideTable* DebugInfo::GetDebugSideTableIfExists(
const WasmCode* code) const {
return impl_->GetDebugSideTableIfExists(code);
}
} // namespace wasm
Handle<WasmDebugInfo> WasmDebugInfo::New(Handle<WasmInstanceObject> instance) {
......
......@@ -91,6 +91,8 @@ class DebugSideTable {
return values_[index].reg_code;
}
void Print(std::ostream&) const;
private:
int pc_offset_;
std::vector<Value> values_;
......@@ -120,6 +122,8 @@ class DebugSideTable {
int num_locals() const { return num_locals_; }
void Print(std::ostream&) const;
private:
struct EntryPositionLess {
bool operator()(const Entry& a, const Entry& b) const {
......@@ -172,6 +176,10 @@ class V8_EXPORT_PRIVATE DebugInfo {
void RemoveDebugSideTables(Vector<WasmCode* const>);
// Return the debug side table for the given code object, but only if it has
// already been created. This will never trigger generation of the table.
DebugSideTable* GetDebugSideTableIfExists(const WasmCode*) const;
private:
std::unique_ptr<DebugInfoImpl> impl_;
};
......
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