Print more info in MarkSweep::VerifyRoot

Refactored old root callback to use a new class called RootInfo.
RootInfo contains all the relevant info related to the root
associated with the callback. The MarkSweep::VerifyRoot function
now uses this info to print the StackVisitor's described location
if the GC root is of the type kRootJavaFrame.

Some other cleanup.

Example output:
E/art     (12167): Tried to mark 0x123 not contained by any spaces
E/art     (12167): Attempting see if it's a bad root
E/art     (12167): Found invalid root: 0x123 with type RootJavaFrame
E/art     (12167): Location=Visiting method
'void java.lang.Runtime.gc()' at dex PC 0xffffffff (native PC 0x0)
vreg=0

(cherry picked from commit 12f7423a2bb4bfab76700d84eb6d4338d211983a)

Bug: 18588862
Change-Id: Ic5a2781f704e931265ffb3621c2eab4b2e25f60f
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 377a3c3..05b6b1d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1748,23 +1748,23 @@
   WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   if ((flags & kVisitRootFlagAllRoots) != 0) {
     for (GcRoot<mirror::Class>& root : class_table_) {
-      root.VisitRoot(callback, arg, 0, kRootStickyClass);
+      root.VisitRoot(callback, arg, RootInfo(kRootStickyClass));
     }
     for (GcRoot<mirror::Class>& root : pre_zygote_class_table_) {
-      root.VisitRoot(callback, arg, 0, kRootStickyClass);
+      root.VisitRoot(callback, arg, RootInfo(kRootStickyClass));
     }
   } else if ((flags & kVisitRootFlagNewRoots) != 0) {
     for (auto& root : new_class_roots_) {
       mirror::Class* old_ref = root.Read<kWithoutReadBarrier>();
-      root.VisitRoot(callback, arg, 0, kRootStickyClass);
+      root.VisitRoot(callback, arg, RootInfo(kRootStickyClass));
       mirror::Class* new_ref = root.Read<kWithoutReadBarrier>();
       if (UNLIKELY(new_ref != old_ref)) {
         // Uh ohes, GC moved a root in the log. Need to search the class_table and update the
         // corresponding object. This is slow, but luckily for us, this may only happen with a
         // concurrent moving GC.
         auto it = class_table_.Find(GcRoot<mirror::Class>(old_ref));
-        class_table_.Erase(it);
-        class_table_.Insert(GcRoot<mirror::Class>(new_ref));
+        DCHECK(it != class_table_.end());
+        *it = GcRoot<mirror::Class>(new_ref);
       }
     }
   }
@@ -1784,17 +1784,17 @@
 // reinit references to when reinitializing a ClassLinker from a
 // mapped image.
 void ClassLinker::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags flags) {
-  class_roots_.VisitRoot(callback, arg, 0, kRootVMInternal);
+  class_roots_.VisitRoot(callback, arg, RootInfo(kRootVMInternal));
   Thread* self = Thread::Current();
   {
     ReaderMutexLock mu(self, dex_lock_);
     if ((flags & kVisitRootFlagAllRoots) != 0) {
       for (GcRoot<mirror::DexCache>& dex_cache : dex_caches_) {
-        dex_cache.VisitRoot(callback, arg, 0, kRootVMInternal);
+        dex_cache.VisitRoot(callback, arg, RootInfo(kRootVMInternal));
       }
     } else if ((flags & kVisitRootFlagNewRoots) != 0) {
       for (size_t index : new_dex_cache_roots_) {
-        dex_caches_[index].VisitRoot(callback, arg, 0, kRootVMInternal);
+        dex_caches_[index].VisitRoot(callback, arg, RootInfo(kRootVMInternal));
       }
     }
     if ((flags & kVisitRootFlagClearRootLog) != 0) {
@@ -1807,12 +1807,10 @@
     }
   }
   VisitClassRoots(callback, arg, flags);
-  array_iftable_.VisitRoot(callback, arg, 0, kRootVMInternal);
+  array_iftable_.VisitRoot(callback, arg, RootInfo(kRootVMInternal));
   DCHECK(!array_iftable_.IsNull());
   for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
-    if (!find_array_class_cache_[i].IsNull()) {
-      find_array_class_cache_[i].VisitRoot(callback, arg, 0, kRootVMInternal);
-    }
+    find_array_class_cache_[i].VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal));
   }
 }