Make stack visitor location for bad roots more verbose.

Change-Id: Ib2f3f48ccf1f5b2f3a4d1a61df553ad1a5c29d38
diff --git a/src/gc/mark_sweep.cc b/src/gc/mark_sweep.cc
index 1ccceaa..e0ecc99 100644
--- a/src/gc/mark_sweep.cc
+++ b/src/gc/mark_sweep.cc
@@ -260,19 +260,18 @@
 }
 
 void MarkSweep::VerifyRootCallback(const Object* root, void* arg, size_t vreg,
-                                   const AbstractMethod* method) {
-  reinterpret_cast<MarkSweep*>(arg)->VerifyRoot(root, vreg, method);
+                                   const StackVisitor* visitor) {
+  reinterpret_cast<MarkSweep*>(arg)->VerifyRoot(root, vreg, visitor);
 }
 
-void MarkSweep::VerifyRoot(const Object* root, size_t vreg, const AbstractMethod* method) {
+void MarkSweep::VerifyRoot(const Object* root, size_t vreg, const StackVisitor* visitor) {
   // See if the root is on any space bitmap.
   if (GetHeap()->GetLiveBitmap()->GetSpaceBitmap(root) == NULL) {
     LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
     if (!large_object_space->Contains(root)) {
       LOG(ERROR) << "Found invalid root: " << root;
-      LOG(ERROR) << "VReg: " << vreg;
-      if (method != NULL) {
-        LOG(ERROR) << "In method " << PrettyMethod(method, true);
+      if (visitor != NULL) {
+        LOG(ERROR) << visitor->DescribeLocation() << " in VReg: " << vreg;
       }
     }
   }
diff --git a/src/gc/mark_sweep.h b/src/gc/mark_sweep.h
index 98445d4..0fee24f 100644
--- a/src/gc/mark_sweep.h
+++ b/src/gc/mark_sweep.h
@@ -295,9 +295,9 @@
   void ExpandMarkStack();
 
   static void VerifyRootCallback(const Object* root, void* arg, size_t vreg,
-                                 const AbstractMethod* method);
+                                 const StackVisitor *visitor);
 
-  void VerifyRoot(const Object* root, size_t vreg, const AbstractMethod* method)
+  void VerifyRoot(const Object* root, size_t vreg, const StackVisitor* visitor)
       NO_THREAD_SAFETY_ANALYSIS;
 
   template <typename Visitor>
diff --git a/src/heap.h b/src/heap.h
index 22b009c..67d8c05 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -53,6 +53,7 @@
 class Object;
 class Space;
 class SpaceTest;
+class StackVisitor;
 class Thread;
 class TimingLogger;
 
@@ -107,7 +108,7 @@
 
   typedef void (RootVisitor)(const Object* root, void* arg);
   typedef void (VerifyRootVisitor)(const Object* root, void* arg, size_t vreg,
-      const AbstractMethod* method);
+      const StackVisitor* visitor);
   typedef bool (IsMarkedTester)(const Object* object, void* arg);
 
   // Create a heap with the requested sizes. The possible empty
diff --git a/src/stack.cc b/src/stack.cc
index f712652..be737ac 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -149,6 +149,16 @@
   return visitor.frames;
 }
 
+std::string StackVisitor::DescribeLocation() const {
+  std::string result("Visiting method '");
+  result += PrettyMethod(GetMethod());
+  result += StringPrintf("' at dex PC 0x%04zx", GetDexPc());
+  if (!IsShadowFrame()) {
+    result += StringPrintf(" (native PC %p)", reinterpret_cast<void*>(GetCurrentQuickFramePc()));
+  }
+  return result;
+}
+
 void StackVisitor::SanityCheckFrame() const {
 #ifndef NDEBUG
   AbstractMethod* method = GetMethod();
diff --git a/src/stack.h b/src/stack.h
index 5b5609c..1dfd5b6 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -25,6 +25,7 @@
 #include "oat/runtime/context.h"
 
 #include <stdint.h>
+#include <string>
 
 namespace art {
 
@@ -477,6 +478,8 @@
     return reinterpret_cast<StackIndirectReferenceTable*>(sp);
   }
 
+  std::string DescribeLocation() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
  private:
   size_t ComputeNumFrames() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
diff --git a/src/thread.cc b/src/thread.cc
index 943fdcb..744a8aa 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1838,12 +1838,12 @@
   return object->GetThinLockId() == thin_lock_id_;
 }
 
-// Visitor parameters are: (const Object* obj, size_t vreg, const AbstractMethod* method).
-template <typename Visitor>
+// RootVisitor parameters are: (const Object* obj, size_t vreg, const StackVisitor* visitor).
+template <typename RootVisitor>
 class ReferenceMapVisitor : public StackVisitor {
  public:
   ReferenceMapVisitor(const ManagedStack* stack, const std::vector<InstrumentationStackFrame>* instrumentation_stack,
-                      Context* context, const Visitor& visitor)
+                      Context* context, const RootVisitor& visitor)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       : StackVisitor(stack, instrumentation_stack, context), visitor_(visitor) {}
 
@@ -1854,7 +1854,7 @@
     }
     ShadowFrame* shadow_frame = GetCurrentShadowFrame();
     if (shadow_frame != NULL) {
-      WrapperVisitor wrapperVisitor(visitor_, shadow_frame->GetMethod());
+      WrapperVisitor wrapperVisitor(visitor_, this);
       shadow_frame->VisitRoots(wrapperVisitor);
     } else {
       AbstractMethod* m = GetMethod();
@@ -1893,7 +1893,7 @@
               }
 
               if (ref != NULL) {
-                visitor_(ref, reg, m);
+                visitor_(ref, reg, this);
               }
             }
           }
@@ -1907,19 +1907,16 @@
 
   class WrapperVisitor {
    public:
-    WrapperVisitor(const Visitor& visitor, AbstractMethod* method)
-        : visitor_(visitor),
-          method_(method) {
-
-    }
+    WrapperVisitor(const RootVisitor& root_visitor, const StackVisitor* stack_visitor)
+      : root_visitor_(root_visitor), stack_visitor_(stack_visitor) {}
 
     void operator()(const Object* obj, size_t offset) const {
-      visitor_(obj, offset, method_);
+      root_visitor_(obj, offset, stack_visitor_);
     }
 
    private:
-    const Visitor& visitor_;
-    AbstractMethod* method_;
+    const RootVisitor& root_visitor_;
+    const StackVisitor* const stack_visitor_;
   };
 
   static bool TestBitmap(int reg, const uint8_t* reg_vector) {
@@ -1927,7 +1924,7 @@
   }
 
   // Visitor for when we visit a root.
-  const Visitor& visitor_;
+  const RootVisitor& visitor_;
 
   // A method helper we keep around to avoid dex file/cache re-computations.
   MethodHelper mh_;
@@ -1939,7 +1936,7 @@
 
   }
 
-  void operator()(const Object* obj, size_t, const AbstractMethod*) const {
+  void operator()(const Object* obj, size_t, const StackVisitor*) const {
     visitor_(obj, arg_);
   }
 
@@ -1953,16 +1950,15 @@
   VerifyCallbackVisitor(Heap::VerifyRootVisitor* visitor, void* arg)
       : visitor_(visitor),
         arg_(arg) {
-
   }
 
-  void operator()(const Object* obj, size_t vreg, const AbstractMethod* method) const  {
-    visitor_(obj, arg_, vreg, method);
+  void operator()(const Object* obj, size_t vreg, const StackVisitor* visitor) const {
+    visitor_(obj, arg_, vreg, visitor);
   }
 
  private:
-  Heap::VerifyRootVisitor* visitor_;
-  void* arg_;
+  Heap::VerifyRootVisitor* const visitor_;
+  void* const arg_;
 };
 
 struct VerifyRootWrapperArg {