From b8ad5145308fef542507188c4371c27b0bd2995c Mon Sep 17 00:00:00 2001 From: Tess Strickland Date: Wed, 19 Nov 2025 07:56:49 -0800 Subject: [PATCH] [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 Commit-Queue: Tess Strickland --- .../vm/compiler/assembler/disassembler_kbc.cc | 3 ++- .../vm/compiler/assembler/disassembler_kbc.h | 23 +++++++++++++++---- runtime/vm/interpreter.cc | 9 +++++--- runtime/vm/interpreter.h | 2 +- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc index 0e1498d4668..112895b5f69 100644 --- a/runtime/vm/compiler/assembler/disassembler_kbc.cc +++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc @@ -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 diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.h b/runtime/vm/compiler/assembler/disassembler_kbc.h index 2bea8fe93f4..f320e9acfc6 100644 --- a/runtime/vm/compiler/assembler/disassembler_kbc.h +++ b/runtime/vm/compiler/assembler/disassembler_kbc.h @@ -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 diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc index 6dc2fc6f57c..de350190527 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc @@ -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(pc), - reinterpret_cast(KernelBytecode::Next(pc))); + reinterpret_cast(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); \ diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h index cd173b95252..994a1860d2f 100644 --- a/runtime/vm/interpreter.h +++ b/runtime/vm/interpreter.h @@ -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();