Commit 19e8abbb authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Store full type in the debug side table

In https://crrev.com/c/2707170, Liftoff was changed to only store the
ValueKind instead of the ValueType, because we only need to know kind
for code emission. For debugging though, the whole type is useful.
This CL changes the debug sidetable back to store the full type, and
retrieves this information from the decoder.

R=jkummerow@chromium.org

Bug: v8:11477
Change-Id: I08a512d24cdf0955c95f3b9261d68a02a39b9b4e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2720302
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73068}
parent dc0a1b40
This diff is collapsed.
......@@ -95,7 +95,7 @@ void DebugSideTable::Entry::Print(std::ostream& os) const {
os << std::setw(6) << std::hex << pc_offset_ << std::dec << " stack height "
<< stack_height_ << " [";
for (auto& value : changed_values_) {
os << " " << name(value.kind) << ":";
os << " " << value.type.name() << ":";
switch (value.storage) {
case kConstant:
os << "const#" << value.i32_const;
......@@ -510,9 +510,9 @@ class DebugInfoImpl {
const auto* value =
debug_side_table->FindValue(debug_side_table_entry, index);
if (value->is_constant()) {
DCHECK(value->kind == kI32 || value->kind == kI64);
return value->kind == kI32 ? WasmValue(value->i32_const)
: WasmValue(int64_t{value->i32_const});
DCHECK(value->type == kWasmI32 || value->type == kWasmI64);
return value->type == kWasmI32 ? WasmValue(value->i32_const)
: WasmValue(int64_t{value->i32_const});
}
if (value->is_register()) {
......@@ -523,14 +523,14 @@ class DebugInfoImpl {
reg.code());
};
if (reg.is_gp_pair()) {
DCHECK_EQ(kI64, value->kind);
DCHECK_EQ(kWasmI64, value->type);
uint32_t low_word = ReadUnalignedValue<uint32_t>(gp_addr(reg.low_gp()));
uint32_t high_word =
ReadUnalignedValue<uint32_t>(gp_addr(reg.high_gp()));
return WasmValue((uint64_t{high_word} << 32) | low_word);
}
if (reg.is_gp()) {
return value->kind == kI32
return value->type == kWasmI32
? WasmValue(ReadUnalignedValue<uint32_t>(gp_addr(reg.gp())))
: WasmValue(ReadUnalignedValue<uint64_t>(gp_addr(reg.gp())));
}
......@@ -544,11 +544,11 @@ class DebugInfoImpl {
Address spilled_addr =
debug_break_fp +
WasmDebugBreakFrameConstants::GetPushedFpRegisterOffset(code);
if (value->kind == kF32) {
if (value->type == kWasmF32) {
return WasmValue(ReadUnalignedValue<float>(spilled_addr));
} else if (value->kind == kF64) {
} else if (value->type == kWasmF64) {
return WasmValue(ReadUnalignedValue<double>(spilled_addr));
} else if (value->kind == kS128) {
} else if (value->type == kWasmS128) {
return WasmValue(Simd128(ReadUnalignedValue<int16>(spilled_addr)));
} else {
// All other cases should have been handled above.
......@@ -558,7 +558,7 @@ class DebugInfoImpl {
// Otherwise load the value from the stack.
Address stack_address = stack_frame_base - value->stack_offset;
switch (value->kind) {
switch (value->type.kind()) {
case kI32:
return WasmValue(ReadUnalignedValue<int32_t>(stack_address));
case kI64:
......
......@@ -43,7 +43,7 @@ class DebugSideTable {
enum Storage : int8_t { kConstant, kRegister, kStack };
struct Value {
int index;
ValueKind kind;
ValueType type;
Storage storage;
union {
int32_t i32_const; // if kind == kConstant
......@@ -53,7 +53,7 @@ class DebugSideTable {
bool operator==(const Value& other) const {
if (index != other.index) return false;
if (kind != other.kind) return false;
if (type != other.type) return false;
if (storage != other.storage) return false;
switch (storage) {
case kConstant:
......
......@@ -177,7 +177,7 @@ struct DebugSideTableEntry {
// Check for equality, but ignore exact register and stack offset.
static bool CheckValueEquals(const DebugSideTable::Entry::Value& a,
const DebugSideTable::Entry::Value& b) {
return a.index == b.index && a.kind == b.kind && a.kind == b.kind &&
return a.index == b.index && a.type == b.type && a.storage == b.storage &&
(a.storage != DebugSideTable::Entry::kConstant ||
a.i32_const == b.i32_const);
}
......@@ -189,7 +189,7 @@ std::ostream& operator<<(std::ostream& out, const DebugSideTableEntry& entry) {
out << "stack height " << entry.stack_height << ", changed: {";
const char* comma = "";
for (auto& v : entry.changed_values) {
out << comma << v.index << ":" << name(v.kind) << " ";
out << comma << v.index << ":" << v.type.name() << " ";
switch (v.storage) {
case DebugSideTable::Entry::kConstant:
out << "const:" << v.i32_const;
......@@ -213,26 +213,26 @@ std::ostream& operator<<(std::ostream& out,
#endif // DEBUG
// Named constructors to make the tests more readable.
DebugSideTable::Entry::Value Constant(int index, ValueKind kind,
DebugSideTable::Entry::Value Constant(int index, ValueType type,
int32_t constant) {
DebugSideTable::Entry::Value value;
value.index = index;
value.kind = kind;
value.type = type;
value.storage = DebugSideTable::Entry::kConstant;
value.i32_const = constant;
return value;
}
DebugSideTable::Entry::Value Register(int index, ValueKind kind) {
DebugSideTable::Entry::Value Register(int index, ValueType type) {
DebugSideTable::Entry::Value value;
value.index = index;
value.kind = kind;
value.type = type;
value.storage = DebugSideTable::Entry::kRegister;
return value;
}
DebugSideTable::Entry::Value Stack(int index, ValueKind kind) {
DebugSideTable::Entry::Value Stack(int index, ValueType type) {
DebugSideTable::Entry::Value value;
value.index = index;
value.kind = kind;
value.type = type;
value.storage = DebugSideTable::Entry::kStack;
return value;
}
......@@ -296,9 +296,9 @@ TEST(Liftoff_debug_side_table_simple) {
CheckDebugSideTable(
{
// function entry, locals in registers.
{2, {Register(0, kI32), Register(1, kI32)}},
{2, {Register(0, kWasmI32), Register(1, kWasmI32)}},
// OOL stack check, locals spilled, stack still empty.
{2, {Stack(0, kI32), Stack(1, kI32)}},
{2, {Stack(0, kWasmI32), Stack(1, kWasmI32)}},
},
debug_side_table.get());
}
......@@ -312,9 +312,9 @@ TEST(Liftoff_debug_side_table_call) {
CheckDebugSideTable(
{
// function entry, local in register.
{1, {Register(0, kI32)}},
{1, {Register(0, kWasmI32)}},
// call, local spilled, stack empty.
{1, {Stack(0, kI32)}},
{1, {Stack(0, kWasmI32)}},
// OOL stack check, local spilled as before, stack empty.
{1, {}},
},
......@@ -332,11 +332,11 @@ TEST(Liftoff_debug_side_table_call_const) {
CheckDebugSideTable(
{
// function entry, local in register.
{1, {Register(0, kI32)}},
{1, {Register(0, kWasmI32)}},
// call, local is kConst.
{1, {Constant(0, kI32, kConst)}},
{1, {Constant(0, kWasmI32, kConst)}},
// OOL stack check, local spilled.
{1, {Stack(0, kI32)}},
{1, {Stack(0, kWasmI32)}},
},
debug_side_table.get());
}
......@@ -351,13 +351,13 @@ TEST(Liftoff_debug_side_table_indirect_call) {
CheckDebugSideTable(
{
// function entry, local in register.
{1, {Register(0, kI32)}},
{1, {Register(0, kWasmI32)}},
// indirect call, local spilled, stack empty.
{1, {Stack(0, kI32)}},
{1, {Stack(0, kWasmI32)}},
// OOL stack check, local still spilled.
{1, {}},
// OOL trap (invalid index), local still spilled, stack has {kConst}.
{2, {Constant(1, kI32, kConst)}},
{2, {Constant(1, kWasmI32, kConst)}},
// OOL trap (sig mismatch), stack unmodified.
{2, {}},
},
......@@ -373,11 +373,11 @@ TEST(Liftoff_debug_side_table_loop) {
CheckDebugSideTable(
{
// function entry, local in register.
{1, {Register(0, kI32)}},
{1, {Register(0, kWasmI32)}},
// OOL stack check, local spilled, stack empty.
{1, {Stack(0, kI32)}},
{1, {Stack(0, kWasmI32)}},
// OOL loop stack check, local still spilled, stack has {kConst}.
{2, {Constant(1, kI32, kConst)}},
{2, {Constant(1, kWasmI32, kConst)}},
},
debug_side_table.get());
}
......@@ -390,9 +390,9 @@ TEST(Liftoff_debug_side_table_trap) {
CheckDebugSideTable(
{
// function entry, locals in registers.
{2, {Register(0, kI32), Register(1, kI32)}},
{2, {Register(0, kWasmI32), Register(1, kWasmI32)}},
// OOL stack check, local spilled, stack empty.
{2, {Stack(0, kI32), Stack(1, kI32)}},
{2, {Stack(0, kWasmI32), Stack(1, kWasmI32)}},
// OOL trap (div by zero), stack as before.
{2, {}},
// OOL trap (unrepresentable), stack as before.
......@@ -414,11 +414,11 @@ TEST(Liftoff_breakpoint_simple) {
CheckDebugSideTable(
{
// First break point, locals in registers.
{2, {Register(0, kI32), Register(1, kI32)}},
{2, {Register(0, kWasmI32), Register(1, kWasmI32)}},
// Second break point, locals unchanged, two register stack values.
{4, {Register(2, kI32), Register(3, kI32)}},
{4, {Register(2, kWasmI32), Register(3, kWasmI32)}},
// OOL stack check, locals spilled, stack empty.
{2, {Stack(0, kI32), Stack(1, kI32)}},
{2, {Stack(0, kWasmI32), Stack(1, kWasmI32)}},
},
debug_side_table.get());
}
......
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