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