Commit 97e72bbf authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm][memory64] Prepare memory tracing for i64 addresses

The index to be traced can be a full (platform-dependent) pointer sized
integer now. This CL prepares memory tracing for that.
As a drive-by, the "address" field is renamed to "offset", or
"effective_offset", depending on the situation.

R=manoskouk@chromium.org

Bug: v8:10949
Change-Id: I1fabfdb57835f041e1310a4eb4024d6254c08752
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465825Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70477}
parent bc4a94d3
......@@ -3827,14 +3827,14 @@ Node* WasmGraphBuilder::TraceMemoryOperation(bool is_store,
TNode<RawPtrT> info =
gasm_->StackSlot(sizeof(wasm::MemoryTracingInfo), kAlign);
Node* address = gasm_->IntAdd(gasm_->UintPtrConstant(offset), index);
Node* effective_offset = gasm_->IntAdd(gasm_->UintPtrConstant(offset), index);
auto store = [&](int field_offset, MachineRepresentation rep, Node* data) {
gasm_->Store(StoreRepresentation(rep, kNoWriteBarrier), info,
gasm_->Int32Constant(field_offset), data);
};
// Store address, is_store, and mem_rep.
store(offsetof(wasm::MemoryTracingInfo, address),
MachineRepresentation::kWord32, address);
// Store effective_offset, is_store, and mem_rep.
store(offsetof(wasm::MemoryTracingInfo, offset),
MachineType::PointerRepresentation(), effective_offset);
store(offsetof(wasm::MemoryTracingInfo, is_store),
MachineRepresentation::kWord8,
mcgraph()->Int32Constant(is_store ? 1 : 0));
......
......@@ -2185,25 +2185,36 @@ class LiftoffCompiler {
__ SpillAllRegisters();
LiftoffRegList pinned = LiftoffRegList::ForRegs(index);
// Get one register for computing the address (offset + index).
LiftoffRegister address = pinned.set(__ GetUnusedRegister(kGpReg, pinned));
// Compute offset+index in address.
__ LoadConstant(address, WasmValue(offset));
__ emit_i32_add(address.gp(), address.gp(), index);
// Get one register for computing the effective offset (offset + index).
LiftoffRegister effective_offset =
pinned.set(__ GetUnusedRegister(kGpReg, pinned));
__ LoadConstant(effective_offset, WasmValue(offset));
__ emit_i32_add(effective_offset.gp(), effective_offset.gp(), index);
// Get a register to hold the stack slot for MemoryTracingInfo.
LiftoffRegister info = pinned.set(__ GetUnusedRegister(kGpReg, pinned));
// Allocate stack slot for MemoryTracingInfo.
__ AllocateStackSlot(info.gp(), sizeof(MemoryTracingInfo));
// Reuse the {effective_offset} register for all information to be stored in
// the MemoryTracingInfo struct.
LiftoffRegister data = effective_offset;
// Now store all information into the MemoryTracingInfo struct.
__ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, address), address,
StoreType::kI32Store, pinned);
__ LoadConstant(address, WasmValue(is_store ? 1 : 0));
__ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, is_store), address,
if (kSystemPointerSize == 8) {
// Zero-extend the effective offset to u64.
CHECK(__ emit_type_conversion(kExprI64UConvertI32, data, effective_offset,
nullptr));
}
__ Store(
info.gp(), no_reg, offsetof(MemoryTracingInfo, offset), data,
kSystemPointerSize == 8 ? StoreType::kI64Store : StoreType::kI32Store,
pinned);
__ LoadConstant(data, WasmValue(is_store ? 1 : 0));
__ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, is_store), data,
StoreType::kI32Store8, pinned);
__ LoadConstant(address, WasmValue(static_cast<int>(rep)));
__ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, mem_rep), address,
__ LoadConstant(data, WasmValue(static_cast<int>(rep)));
__ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, mem_rep), data,
StoreType::kI32Store8, pinned);
WasmTraceMemoryDescriptor descriptor;
......
......@@ -19,14 +19,13 @@ void TraceMemoryOperation(base::Optional<ExecutionTier> tier,
int position, uint8_t* mem_start) {
EmbeddedVector<char, 91> value;
auto mem_rep = static_cast<MachineRepresentation>(info->mem_rep);
Address address = reinterpret_cast<Address>(mem_start) + info->offset;
switch (mem_rep) {
#define TRACE_TYPE(rep, str, format, ctype1, ctype2) \
case MachineRepresentation::rep: \
SNPrintF(value, str ":" format, \
base::ReadLittleEndianValue<ctype1>( \
reinterpret_cast<Address>(mem_start) + info->address), \
base::ReadLittleEndianValue<ctype2>( \
reinterpret_cast<Address>(mem_start) + info->address)); \
#define TRACE_TYPE(rep, str, format, ctype1, ctype2) \
case MachineRepresentation::rep: \
SNPrintF(value, str ":" format, \
base::ReadLittleEndianValue<ctype1>(address), \
base::ReadLittleEndianValue<ctype2>(address)); \
break;
TRACE_TYPE(kWord8, " i8", "%d / %02x", uint8_t, uint8_t)
TRACE_TYPE(kWord16, "i16", "%d / %04x", uint16_t, uint16_t)
......@@ -37,30 +36,22 @@ void TraceMemoryOperation(base::Optional<ExecutionTier> tier,
#undef TRACE_TYPE
case MachineRepresentation::kSimd128:
SNPrintF(value, "s128:%d %d %d %d / %08x %08x %08x %08x",
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address + 4),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address + 8),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address + 12),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address + 4),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address + 8),
base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(mem_start) + info->address + 12));
base::ReadLittleEndianValue<uint32_t>(address),
base::ReadLittleEndianValue<uint32_t>(address + 4),
base::ReadLittleEndianValue<uint32_t>(address + 8),
base::ReadLittleEndianValue<uint32_t>(address + 12),
base::ReadLittleEndianValue<uint32_t>(address),
base::ReadLittleEndianValue<uint32_t>(address + 4),
base::ReadLittleEndianValue<uint32_t>(address + 8),
base::ReadLittleEndianValue<uint32_t>(address + 12));
break;
default:
SNPrintF(value, "???");
}
const char* eng =
tier.has_value() ? ExecutionTierToString(tier.value()) : "?";
printf("%-11s func:%6d+0x%-6x%s %08x val: %s\n", eng, func_index, position,
info->is_store ? " store to" : "load from", info->address,
printf("%-11s func:%6d+0x%-6x%s %016" PRIuPTR " val: %s\n", eng, func_index,
position, info->is_store ? " store to" : "load from", info->offset,
value.begin());
}
......
......@@ -17,7 +17,7 @@ namespace wasm {
// This struct is create in generated code, hence use low-level types.
struct MemoryTracingInfo {
uint32_t address;
uintptr_t offset;
uint8_t is_store; // 0 or 1
uint8_t mem_rep;
static_assert(
......@@ -25,8 +25,10 @@ struct MemoryTracingInfo {
std::underlying_type<MachineRepresentation>::type>::value,
"MachineRepresentation uses uint8_t");
MemoryTracingInfo(uint32_t addr, bool is_store, MachineRepresentation rep)
: address(addr), is_store(is_store), mem_rep(static_cast<uint8_t>(rep)) {}
MemoryTracingInfo(uintptr_t offset, bool is_store, MachineRepresentation rep)
: offset(offset),
is_store(is_store),
mem_rep(static_cast<uint8_t>(rep)) {}
};
// Callback for tracing a memory operation for debugging.
......
liftoff func: 0+0x3 load from 00000004 val: i32:0 / 00000000
liftoff func: 1+0x3 load from 00000001 val: i8:0 / 00
liftoff func: 3+0x5 store to 00000004 val: i32:305419896 / 12345678
liftoff func: 0+0x3 load from 00000002 val: i32:1450704896 / 56780000
liftoff func: 1+0x3 load from 00000006 val: i8:52 / 34
liftoff func: 2+0x3 load from 00000002 val: f32:68169720922112.000000 / 56780000
liftoff func: 4+0x5 store to 00000004 val: i8:171 / ab
liftoff func: 0+0x3 load from 00000002 val: i32:1454047232 / 56ab0000
liftoff func: 2+0x3 load from 00000002 val: f32:94008244174848.000000 / 56ab0000
liftoff func: 6+0x7 store to 00000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef
liftoff func: 5+0x3 load from 00000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000
liftoff func: 7+0x3 load from 00000004 val: i16:48879 / beef
liftoff func: 8+0x3 load from 00000002 val: i64:-4688528683866062848 / beef0000beef0000
liftoff func: 9+0x3 load from 00000002 val: f64:-0.000015 / beef0000beef0000
liftoff func: 0+0x3 load from 0000000000000004 val: i32:0 / 00000000
liftoff func: 1+0x3 load from 0000000000000001 val: i8:0 / 00
liftoff func: 3+0x5 store to 0000000000000004 val: i32:305419896 / 12345678
liftoff func: 0+0x3 load from 0000000000000002 val: i32:1450704896 / 56780000
liftoff func: 1+0x3 load from 0000000000000006 val: i8:52 / 34
liftoff func: 2+0x3 load from 0000000000000002 val: f32:68169720922112.000000 / 56780000
liftoff func: 4+0x5 store to 0000000000000004 val: i8:171 / ab
liftoff func: 0+0x3 load from 0000000000000002 val: i32:1454047232 / 56ab0000
liftoff func: 2+0x3 load from 0000000000000002 val: f32:94008244174848.000000 / 56ab0000
liftoff func: 6+0x7 store to 0000000000000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef
liftoff func: 5+0x3 load from 0000000000000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000
liftoff func: 7+0x3 load from 0000000000000004 val: i16:48879 / beef
liftoff func: 8+0x3 load from 0000000000000002 val: i64:-4688528683866062848 / beef0000beef0000
liftoff func: 9+0x3 load from 0000000000000002 val: f64:-0.000015 / beef0000beef0000
turbofan func: 0+0x3 load from 00000004 val: i32:0 / 00000000
turbofan func: 1+0x3 load from 00000001 val: i8:0 / 00
turbofan func: 3+0x5 store to 00000004 val: i32:305419896 / 12345678
turbofan func: 0+0x3 load from 00000002 val: i32:1450704896 / 56780000
turbofan func: 1+0x3 load from 00000006 val: i8:52 / 34
turbofan func: 2+0x3 load from 00000002 val: f32:68169720922112.000000 / 56780000
turbofan func: 4+0x5 store to 00000004 val: i8:171 / ab
turbofan func: 0+0x3 load from 00000002 val: i32:1454047232 / 56ab0000
turbofan func: 2+0x3 load from 00000002 val: f32:94008244174848.000000 / 56ab0000
turbofan func: 6+0x7 store to 00000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef
turbofan func: 5+0x3 load from 00000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000
turbofan func: 7+0x3 load from 00000004 val: i16:48879 / beef
turbofan func: 8+0x3 load from 00000002 val: i64:-4688528683866062848 / beef0000beef0000
turbofan func: 9+0x3 load from 00000002 val: f64:-0.000015 / beef0000beef0000
turbofan func: 0+0x3 load from 0000000000000004 val: i32:0 / 00000000
turbofan func: 1+0x3 load from 0000000000000001 val: i8:0 / 00
turbofan func: 3+0x5 store to 0000000000000004 val: i32:305419896 / 12345678
turbofan func: 0+0x3 load from 0000000000000002 val: i32:1450704896 / 56780000
turbofan func: 1+0x3 load from 0000000000000006 val: i8:52 / 34
turbofan func: 2+0x3 load from 0000000000000002 val: f32:68169720922112.000000 / 56780000
turbofan func: 4+0x5 store to 0000000000000004 val: i8:171 / ab
turbofan func: 0+0x3 load from 0000000000000002 val: i32:1454047232 / 56ab0000
turbofan func: 2+0x3 load from 0000000000000002 val: f32:94008244174848.000000 / 56ab0000
turbofan func: 6+0x7 store to 0000000000000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef
turbofan func: 5+0x3 load from 0000000000000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000
turbofan func: 7+0x3 load from 0000000000000004 val: i16:48879 / beef
turbofan func: 8+0x3 load from 0000000000000002 val: i64:-4688528683866062848 / beef0000beef0000
turbofan func: 9+0x3 load from 0000000000000002 val: f64:-0.000015 / beef0000beef0000
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