[pkg,dyn_modules] Use bytecode payload start for relative disassembly.

Add an additional argument to the base implementation of KernelBytecodeDisassembler::Disassemble that is the base address to use
when FLAG_disassemble_relative is enabled.

For the delegating versions of KernelBytecodeDisassembler::Disassemble
that take a Bytecode object, the payload start of the bytecode object
is retrieved and used as the base.

For the delegating versions of KernelBytecodeDisassembler::Disassemble
that take neither a base or a bytecode object, the start is used as
the base.

When tracing instructions in the interpreter, the bytecode is retrieved
via the frame pointer and then its payload start is passed in as the
base, so that the relative offset printed with the instructions match
the relative offsets printed when dumping function bytecode.

TEST=manual use of --disassemble-relative while tracing/dumping bytecode

Change-Id: I7f931037970acd950a330fa6be024df5beb144a7
Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/463022
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
Tess Strickland
2025-11-19 07:56:49 -08:00
committed by Commit Queue
parent a58a41c27e
commit b8ad514530
4 changed files with 28 additions and 9 deletions
@@ -330,6 +330,7 @@ void KernelBytecodeDisassembler::DecodeInstruction(char* hex_buffer,
void KernelBytecodeDisassembler::Disassemble(uword start,
uword end,
uword base,
DisassemblyFormatter* formatter,
const Bytecode& bytecode) {
#if !defined(PRODUCT)
@@ -347,7 +348,7 @@ void KernelBytecodeDisassembler::Disassemble(uword start,
&object, pc);
formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
sizeof(human_buffer), object,
FLAG_disassemble_relative ? pc - start : pc);
FLAG_disassemble_relative ? pc - base : pc);
pc += instruction_length;
}
#else
@@ -20,16 +20,27 @@ class KernelBytecodeDisassembler : public AllStatic {
// Return true if all instructions were successfully decoded, false otherwise.
static void Disassemble(uword start,
uword end,
uword base,
DisassemblyFormatter* formatter,
const Bytecode& bytecode);
static void Disassemble(uword start,
uword end,
uword base,
DisassemblyFormatter* formatter) {
Disassemble(start, end, formatter, Bytecode::Handle());
Disassemble(start, end, base, formatter, Bytecode::Handle());
}
static void Disassemble(uword start,
uword end,
DisassemblyFormatter* formatter,
const Bytecode& bytecode) {
ASSERT(!bytecode.IsNull());
Disassemble(start, end, bytecode.PayloadStart(), formatter, bytecode);
}
static void Disassemble(uword start, uword end, const Bytecode& bytecode) {
ASSERT(!bytecode.IsNull());
#if !defined(PRODUCT)
DisassembleToStdout stdout_formatter;
LogBlock lb;
@@ -39,16 +50,20 @@ class KernelBytecodeDisassembler : public AllStatic {
#endif
}
static void Disassemble(uword start, uword end) {
static void Disassemble(uword start, uword end, uword base) {
#if !defined(PRODUCT)
DisassembleToStdout stdout_formatter;
LogBlock lb;
Disassemble(start, end, &stdout_formatter);
Disassemble(start, end, base, &stdout_formatter);
#else
UNREACHABLE();
#endif
}
static void Disassemble(uword start, uword end) {
Disassemble(start, end, start);
}
static void Disassemble(uword start,
uword end,
char* buffer,
@@ -56,7 +71,7 @@ class KernelBytecodeDisassembler : public AllStatic {
#if !defined(PRODUCT)
DisassembleToMemory memory_formatter(buffer, buffer_size);
LogBlock lb;
Disassemble(start, end, &memory_formatter);
Disassemble(start, end, start, &memory_formatter);
#else
UNREACHABLE();
#endif
+6 -3
View File
@@ -432,12 +432,15 @@ DART_FORCE_INLINE bool Interpreter::IsTracingExecution() const {
}
// Prints bytecode instruction at given pc for instruction tracing.
DART_NOINLINE void Interpreter::TraceInstruction(const KBCInstr* pc) const {
DART_NOINLINE void Interpreter::TraceInstruction(const KBCInstr* pc,
ObjectPtr* FP) const {
THR_Print("%" Pu64 " ", icount_);
if (FLAG_support_disassembler) {
auto const bytecode = Function::GetBytecode(FrameFunction(FP));
KernelBytecodeDisassembler::Disassemble(
reinterpret_cast<uword>(pc),
reinterpret_cast<uword>(KernelBytecode::Next(pc)));
reinterpret_cast<uword>(KernelBytecode::Next(pc)),
Bytecode::PayloadStartOf(bytecode));
} else {
THR_Print("Disassembler not supported in this mode.\n");
}
@@ -849,7 +852,7 @@ DART_FORCE_INLINE bool Interpreter::InstanceCall(Thread* thread,
#if defined(DEBUG)
#define TRACE_INSTRUCTION \
if (IsTracingExecution()) { \
TraceInstruction(pc); \
TraceInstruction(pc, FP); \
} \
if (IsWritingTraceFile()) { \
WriteInstructionToTrace(pc); \
+1 -1
View File
@@ -255,7 +255,7 @@ class Interpreter {
bool IsTracingExecution() const;
// Prints bytecode instruction at given pc for instruction tracing.
void TraceInstruction(const KBCInstr* pc) const;
void TraceInstruction(const KBCInstr* pc, ObjectPtr* FP) const;
bool IsWritingTraceFile() const;
void FlushTraceBuffer();