Update native gc-roots separately in compaction pause

The concurrent compaction algorithm requires all GC roots to be updated
to post-compact addresses before resuming mutators for concurrent
compaction. Therefore, unlike CC, we cannot update native roots in
classes/dex-caches/class-loaders while visiting references
(VisitReferences) on heap objects.

This CL separates the two and updates all the gc-roots in the compaction
pause.

Bug: 160737021
Test: art/test/testrunner/testrunner.py
Change-Id: I8a57472ba49b9dc30bc0f41a7db3f5efa7eafd9a
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 51870a7..8921577 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -10177,6 +10177,18 @@
   }
 }
 
+void ClassLinker::VisitDexCaches(DexCacheVisitor* visitor) const {
+  Thread* const self = Thread::Current();
+  for (const auto& it : dex_caches_) {
+    // Need to use DecodeJObject so that we get null for cleared JNI weak globals.
+    ObjPtr<mirror::DexCache> dex_cache = ObjPtr<mirror::DexCache>::DownCast(
+        self->DecodeJObject(it.second.weak_root));
+    if (dex_cache != nullptr) {
+      visitor->Visit(dex_cache);
+    }
+  }
+}
+
 void ClassLinker::VisitAllocators(AllocatorVisitor* visitor) const {
   for (const ClassLoaderData& data : class_loaders_) {
     LinearAlloc* alloc = data.allocator;