From a34e760fa5cc3102ce1998f10816d380c37f43aa Mon Sep 17 00:00:00 2001 From: Zheng Xu Date: Tue, 3 Feb 2015 12:03:15 +0800 Subject: [PATCH] ARM/ARM64: Dump thread offset. Dump thread offset in compiler verbose log for arm32/arm64 and oatdump for arm64. Before patch : 0x4e: ldr lr, [rSELF, #604] After patch : 0x4e: ldr lr, [rSELF, #604] ; pTestSuspend Change-Id: I514e69dc44b1cf4c8a8fa085b31f93cf6a1b7c91 --- compiler/dex/quick/arm/target_arm.cc | 19 +++++++++++++ compiler/dex/quick/arm64/target_arm64.cc | 19 +++++++++++++ disassembler/disassembler_arm64.cc | 49 +++++++++++++++++--------------- disassembler/disassembler_arm64.h | 9 ++++-- 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc index 5538d798b..13f9072bb 100644 --- a/compiler/dex/quick/arm/target_arm.cc +++ b/compiler/dex/quick/arm/target_arm.cc @@ -19,6 +19,7 @@ #include #include +#include #include "backend_arm.h" #include "base/logging.h" @@ -490,6 +491,24 @@ std::string ArmMir2Lir::BuildInsnString(const char* fmt, LIR* lir, unsigned char buf += *fmt++; } } + // Dump thread offset. + std::string fmt_str = GetTargetInstFmt(lir->opcode); + if (std::string::npos != fmt_str.find(", [!1C, #!2") && rARM_SELF == lir->operands[1] && + std::string::npos != buf.find(", [")) { + int offset = lir->operands[2]; + if (std::string::npos != fmt_str.find("#!2d")) { + } else if (std::string::npos != fmt_str.find("#!2E")) { + offset *= 4; + } else if (std::string::npos != fmt_str.find("#!2F")) { + offset *= 2; + } else { + LOG(FATAL) << "Should not reach here"; + } + std::ostringstream tmp_stream; + Thread::DumpThreadOffset<4>(tmp_stream, offset); + buf += " ; "; + buf += tmp_stream.str(); + } return buf; } diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index 34662f27f..136be946f 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -19,6 +19,7 @@ #include #include +#include #include "backend_arm64.h" #include "base/logging.h" @@ -522,6 +523,24 @@ std::string Arm64Mir2Lir::BuildInsnString(const char* fmt, LIR* lir, unsigned ch buf += *fmt++; } } + // Dump thread offset. + std::string fmt_str = GetTargetInstFmt(lir->opcode); + if (std::string::npos != fmt_str.find(", [!1X, #!2") && rxSELF == lir->operands[1] && + std::string::npos != buf.find(", [")) { + int offset = lir->operands[2]; + if (std::string::npos != fmt_str.find("#!2d")) { + } else if (std::string::npos != fmt_str.find("#!2D")) { + offset *= (IS_WIDE(lir->opcode)) ? 8 : 4; + } else if (std::string::npos != fmt_str.find("#!2F")) { + offset *= 2; + } else { + LOG(FATAL) << "Should not reach here"; + } + std::ostringstream tmp_stream; + Thread::DumpThreadOffset<8>(tmp_stream, offset); + buf += " ; "; + buf += tmp_stream.str(); + } return buf; } diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc index bd3bebf20..4ff44b47c 100644 --- a/disassembler/disassembler_arm64.cc +++ b/disassembler/disassembler_arm64.cc @@ -18,7 +18,7 @@ #include -#include +#include #include "base/logging.h" #include "base/stringprintf.h" @@ -27,22 +27,23 @@ namespace art { namespace arm64 { +// This enumeration should mirror the declarations in +// runtime/arch/arm64/registers_arm64.h. We do not include that file to +// avoid a dependency on libart. +enum { + TR = 18, + ETR = 21, + IP0 = 16, + IP1 = 17, + FP = 29, + LR = 30 +}; + void CustomDisassembler::AppendRegisterNameToOutput( const vixl::Instruction* instr, const vixl::CPURegister& reg) { USE(instr); if (reg.IsRegister()) { - // This enumeration should mirror the declarations in - // runtime/arch/arm64/registers_arm64.h. We do not include that file to - // avoid a dependency on libart. - enum { - TR = 18, - ETR = 21, - IP0 = 16, - IP1 = 17, - FP = 29, - LR = 30 - }; switch (reg.code()) { case IP0: AppendToOutput(reg.Is64Bits() ? "ip0" : "wip0"); return; case IP1: AppendToOutput(reg.Is64Bits() ? "ip1" : "wip1"); return; @@ -66,16 +67,7 @@ void CustomDisassembler::VisitLoadLiteral(const vixl::Instruction* instr) { return; } - char* buffer = buffer_; - char* buffer_end = buffer_ + buffer_size_; - - // Find the end position in the buffer. - while ((*buffer != 0) && (buffer < buffer_end)) { - ++buffer; - } - void* data_address = instr->LiteralAddress(); - ptrdiff_t buf_size_remaining = buffer_end - buffer; vixl::Instr op = instr->Mask(vixl::LoadLiteralMask); switch (op) { @@ -84,14 +76,14 @@ void CustomDisassembler::VisitLoadLiteral(const vixl::Instruction* instr) { case vixl::LDRSW_x_lit: { int64_t data = op == vixl::LDR_x_lit ? *reinterpret_cast(data_address) : *reinterpret_cast(data_address); - snprintf(buffer, buf_size_remaining, " (0x%" PRIx64 " / %" PRId64 ")", data, data); + AppendToOutput(" (0x%" PRIx64 " / %" PRId64 ")", data, data); break; } case vixl::LDR_s_lit: case vixl::LDR_d_lit: { double data = (op == vixl::LDR_s_lit) ? *reinterpret_cast(data_address) : *reinterpret_cast(data_address); - snprintf(buffer, buf_size_remaining, " (%g)", data); + AppendToOutput(" (%g)", data); break; } default: @@ -99,6 +91,17 @@ void CustomDisassembler::VisitLoadLiteral(const vixl::Instruction* instr) { } } +void CustomDisassembler::VisitLoadStoreUnsignedOffset(const vixl::Instruction* instr) { + Disassembler::VisitLoadStoreUnsignedOffset(instr); + + if (instr->Rn() == TR) { + int64_t offset = instr->ImmLSUnsigned() << instr->SizeLS(); + std::ostringstream tmp_stream; + Thread::DumpThreadOffset<8>(tmp_stream, static_cast(offset)); + AppendToOutput(" (%s)", tmp_stream.str().c_str()); + } +} + size_t DisassemblerArm64::Dump(std::ostream& os, const uint8_t* begin) { const vixl::Instruction* instr = reinterpret_cast(begin); decoder.Decode(instr); diff --git a/disassembler/disassembler_arm64.h b/disassembler/disassembler_arm64.h index a370b8ded..57f11c822 100644 --- a/disassembler/disassembler_arm64.h +++ b/disassembler/disassembler_arm64.h @@ -34,11 +34,14 @@ class CustomDisassembler FINAL : public vixl::Disassembler { vixl::Disassembler(), read_literals_(read_literals) {} // Use register aliases in the disassembly. - virtual void AppendRegisterNameToOutput(const vixl::Instruction* instr, - const vixl::CPURegister& reg) OVERRIDE; + void AppendRegisterNameToOutput(const vixl::Instruction* instr, + const vixl::CPURegister& reg) OVERRIDE; // Improve the disassembly of literal load instructions. - virtual void VisitLoadLiteral(const vixl::Instruction* instr) OVERRIDE; + void VisitLoadLiteral(const vixl::Instruction* instr) OVERRIDE; + + // Improve the disassembly of thread offset. + void VisitLoadStoreUnsignedOffset(const vixl::Instruction* instr) OVERRIDE; private: // Indicate if the disassembler should read data loaded from literal pools. -- 2.11.0