Merge "Check for null array assignments inline. Tidy asm macros." into ics-mr1-plus-art
diff --git a/src/disassembler_arm.cc b/src/disassembler_arm.cc
index 5211146..a243ecf 100644
--- a/src/disassembler_arm.cc
+++ b/src/disassembler_arm.cc
@@ -20,6 +20,7 @@
 
 #include "logging.h"
 #include "stringprintf.h"
+#include "thread.h"
 
 namespace art {
 namespace arm {
@@ -661,6 +662,10 @@
             uint32_t imm12 = instr & 0xFFF;
             opcode << "ldr.w";
             args << Rt << ", [" << Rn << ", #" << imm12 << "]";
+            if (Rn.r == 9) {
+              args << "  ; ";
+              Thread::DumpThreadOffset(args, imm12, 4);
+            }
           } else if (op4 == 0) {
             // LDR.W Rt, [Rn, Rm{, LSL #imm2}] - 111 11 00 00 101 nnnn tttt 000000iimmmm
             uint32_t imm2 = (instr >> 4) & 0xF;
@@ -875,11 +880,11 @@
       //uint16_t opB = (instr >> 9) & 7;
       switch (opA) {
         case 0x6: {
-          // STR Rt, Rn, #imm - 01100 iiiii nnn ttt
-          // LDR Rt, Rn, #imm - 01101 iiiii nnn ttt
+          // STR Rt, [Rn, #imm] - 01100 iiiii nnn ttt
+          // LDR Rt, [Rn, #imm] - 01101 iiiii nnn ttt
           uint16_t imm5 = (instr >> 6) & 0x1F;
           ThumbRegister Rn(instr, 3);
-          ThumbRegister Rt(instr, 7);
+          ThumbRegister Rt(instr, 0);
           opcode << ((instr & 0x800) == 0 ? "str" : "ldr");
           args << Rt << ", [" << Rn << ", #" << (imm5 << 2) << "]";
           break;
diff --git a/src/disassembler_x86.cc b/src/disassembler_x86.cc
index d7ee80b..48074b8 100644
--- a/src/disassembler_x86.cc
+++ b/src/disassembler_x86.cc
@@ -399,11 +399,11 @@
     }
     args << StringPrintf("%d (%p)", displacement, instr + displacement);
   }
-  os << StringPrintf("\t\t\t%p: ", begin_instr);
+  std::stringstream hex;
   for (size_t i = 0; begin_instr + i < instr; ++i) {
-    os << StringPrintf("%02X", begin_instr[i]);
+    hex << StringPrintf("%02X", begin_instr[i]);
   }
-  os << StringPrintf("\t%-7s ", opcode.str().c_str()) << args.str() << std::endl;
+  os << StringPrintf("\t\t\t%p: %22s    \t%-7s ", begin_instr, hex.str().c_str(), opcode.str().c_str()) << args.str() << '\n';
   return instr - begin_instr;
 }
 
diff --git a/src/thread.cc b/src/thread.cc
index b26928f..0a44b53 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1459,6 +1459,113 @@
 #endif
 }
 
+void Thread::DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers) {
+  CHECK_EQ(size_of_pointers, 4U); // TODO: support 64-bit targets.
+#define DO_THREAD_OFFSET(x) if (offset == static_cast<uint32_t>(OFFSETOF_MEMBER(Thread, x))) { os << # x; } else
+#define DO_THREAD_ENTRY_POINT_OFFSET(x) if (offset == ENTRYPOINT_OFFSET(x)) { os << # x; } else
+  DO_THREAD_OFFSET(card_table_)
+  DO_THREAD_OFFSET(exception_)
+  DO_THREAD_OFFSET(jni_env_)
+  DO_THREAD_OFFSET(self_)
+  DO_THREAD_OFFSET(stack_end_)
+  DO_THREAD_OFFSET(suspend_count_)
+  DO_THREAD_OFFSET(thin_lock_id_)
+  DO_THREAD_OFFSET(top_of_managed_stack_)
+  DO_THREAD_OFFSET(top_of_managed_stack_pc_)
+  DO_THREAD_OFFSET(top_sirt_)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocArrayFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocArrayFromCodeWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocObjectFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocObjectFromCodeWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckAndAllocArrayFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckAndAllocArrayFromCodeWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInstanceofNonTrivialFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCanPutArrayElementFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckCastFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDebugMe)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUpdateDebuggerFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInitializeStaticStorage)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInitializeTypeAndVerifyAccessFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInitializeTypeFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pResolveStringFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet32Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet32Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet64Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet64Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSetObjInstance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSetObjStatic)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet32Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet32Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet64Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet64Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGetObjInstance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGetObjStatic)
+  DO_THREAD_ENTRY_POINT_OFFSET(pHandleFillArrayDataFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDecodeJObjectInThread)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFindNativeMethod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLockObjectFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUnlockObjectFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmpgDouble)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmpgFloat)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmplDouble)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmplFloat)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDadd)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDmul)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDsub)
+  DO_THREAD_ENTRY_POINT_OFFSET(pF2d)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFmod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pI2d)
+  DO_THREAD_ENTRY_POINT_OFFSET(pL2d)
+  DO_THREAD_ENTRY_POINT_OFFSET(pD2f)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFadd)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFmodf)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFmul)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFsub)
+  DO_THREAD_ENTRY_POINT_OFFSET(pI2f)
+  DO_THREAD_ENTRY_POINT_OFFSET(pL2f)
+  DO_THREAD_ENTRY_POINT_OFFSET(pD2iz)
+  DO_THREAD_ENTRY_POINT_OFFSET(pF2iz)
+  DO_THREAD_ENTRY_POINT_OFFSET(pIdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pIdivmod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pD2l)
+  DO_THREAD_ENTRY_POINT_OFFSET(pF2l)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLdivmod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLmul)
+  DO_THREAD_ENTRY_POINT_OFFSET(pShlLong)
+  DO_THREAD_ENTRY_POINT_OFFSET(pShrLong)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUshrLong)
+  DO_THREAD_ENTRY_POINT_OFFSET(pIndexOf)
+  DO_THREAD_ENTRY_POINT_OFFSET(pMemcmp16)
+  DO_THREAD_ENTRY_POINT_OFFSET(pStringCompareTo)
+  DO_THREAD_ENTRY_POINT_OFFSET(pMemcpy)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFindInterfaceMethodInCache)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUnresolvedDirectMethodTrampolineFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeInterfaceTrampoline)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckSuspendFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pTestSuspendFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDeliverException)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowAbstractMethodErrorFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowArrayBoundsFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowDivZeroFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowNoSuchMethodFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowNullPointerFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowStackOverflowFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowVerificationErrorFromCode)
+  {
+    os << offset;
+  }
+#undef DO_THREAD_OFFSET
+#undef DO_THREAD_ENTRY_POINT_OFFSET
+}
+
 class CatchBlockStackVisitor : public Thread::StackVisitor {
  public:
   CatchBlockStackVisitor(Class* to_find, Context* ljc)
diff --git a/src/thread.h b/src/thread.h
index ad15c0f..37425ff 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -121,6 +121,9 @@
   static Thread* FromManagedThread(JNIEnv* env, jobject thread);
   static uint32_t LockOwnerFromThreadLock(Object* thread_lock);
 
+  // Translates 172 to pAllocArrayFromCode and so on.
+  static void DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers);
+
   // When full == true, dumps the detailed thread state and the thread stack (used for SIGQUIT).
   // When full == false, dumps a one-line summary of thread state (used for operator<<).
   void Dump(std::ostream& os, bool full = true) const;