OSDN Git Service

ARM/ARM64: Dump thread offset.
authorZheng Xu <zheng.xu@arm.com>
Tue, 3 Feb 2015 04:03:15 +0000 (12:03 +0800)
committerZheng Xu <zheng.xu@arm.com>
Tue, 3 Feb 2015 10:39:12 +0000 (18:39 +0800)
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
compiler/dex/quick/arm64/target_arm64.cc
disassembler/disassembler_arm64.cc
disassembler/disassembler_arm64.h

index 5538d79..13f9072 100644 (file)
@@ -19,6 +19,7 @@
 #include <inttypes.h>
 
 #include <string>
+#include <sstream>
 
 #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;
 }
 
index 34662f2..136be94 100644 (file)
@@ -19,6 +19,7 @@
 #include <inttypes.h>
 
 #include <string>
+#include <sstream>
 
 #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;
 }
 
index bd3bebf..4ff44b4 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <inttypes.h>
 
-#include <ostream>
+#include <sstream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
 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<void*>();
-  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<int64_t*>(data_address)
                                            : *reinterpret_cast<int32_t*>(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<float*>(data_address)
                                             : *reinterpret_cast<double*>(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<uint32_t>(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<const vixl::Instruction*>(begin);
   decoder.Decode(instr);
index a370b8d..57f11c8 100644 (file)
@@ -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.