Refactor ClassRoot/GetClassRoot().

Move it outside the ClassLinker, into its own header file,
and add retrieval based on a mirror class template argument.
Keep the SetClassRoot() as a private member of ClassLinker.

Make the new GetClassRoot()s return ObjPtr<>.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 31113334
Change-Id: Icbc6b62b41f6ffd65b437297a21eadbb0454e2b7
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index ffa000e..6900cd8 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -20,6 +20,7 @@
 #include "base/enums.h"
 #include "builder.h"
 #include "class_linker.h"
+#include "class_root.h"
 #include "constant_folding.h"
 #include "data_type-inl.h"
 #include "dead_code_elimination.h"
@@ -537,7 +538,7 @@
   Handle<mirror::ObjectArray<mirror::Class>> inline_cache = hs->NewHandle(
       mirror::ObjectArray<mirror::Class>::Alloc(
           self,
-          class_linker->GetClassRoot(ClassLinker::kClassArrayClass),
+          GetClassRoot<mirror::ObjectArray<mirror::Class>>(class_linker),
           InlineCache::kIndividualCacheSize));
   if (inline_cache == nullptr) {
     // We got an OOME. Just clear the exception, and don't inline.
@@ -777,7 +778,7 @@
 HInstanceFieldGet* HInliner::BuildGetReceiverClass(ClassLinker* class_linker,
                                                    HInstruction* receiver,
                                                    uint32_t dex_pc) const {
-  ArtField* field = class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0);
+  ArtField* field = GetClassRoot<mirror::Object>(class_linker)->GetInstanceField(0);
   DCHECK_EQ(std::string(field->GetName()), "shadow$_klass_");
   HInstanceFieldGet* result = new (graph_->GetAllocator()) HInstanceFieldGet(
       receiver,
@@ -2120,9 +2121,8 @@
         return true;
       } else if (return_replacement->IsInstanceFieldGet()) {
         HInstanceFieldGet* field_get = return_replacement->AsInstanceFieldGet();
-        ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
         if (field_get->GetFieldInfo().GetField() ==
-              class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0)) {
+                GetClassRoot<mirror::Object>()->GetInstanceField(0)) {
           return true;
         }
       }
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index ca84d42..63704a4 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -18,6 +18,7 @@
 
 #include "art_method-inl.h"
 #include "class_linker-inl.h"
+#include "class_root.h"
 #include "data_type-inl.h"
 #include "escape.h"
 #include "intrinsics.h"
@@ -1563,8 +1564,7 @@
 
   {
     ScopedObjectAccess soa(Thread::Current());
-    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-    ArtField* field = class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0);
+    ArtField* field = GetClassRoot<mirror::Object>()->GetInstanceField(0);
     DCHECK_EQ(std::string(field->GetName()), "shadow$_klass_");
     if (field_get->GetFieldInfo().GetField() != field) {
       return false;
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 7f78dc2..99b0b18 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -22,6 +22,7 @@
 #include "base/bit_vector-inl.h"
 #include "base/stl_util.h"
 #include "class_linker-inl.h"
+#include "class_root.h"
 #include "code_generator.h"
 #include "common_dominator.h"
 #include "intrinsics.h"
@@ -40,9 +41,8 @@
 void HGraph::InitializeInexactObjectRTI(VariableSizedHandleScope* handles) {
   ScopedObjectAccess soa(Thread::Current());
   // Create the inexact Object reference type and store it in the HGraph.
-  ClassLinker* linker = Runtime::Current()->GetClassLinker();
   inexact_object_rti_ = ReferenceTypeInfo::Create(
-      handles->NewHandle(linker->GetClassRoot(ClassLinker::kJavaLangObject)),
+      handles->NewHandle(GetClassRoot<mirror::Object>()),
       /* is_exact */ false);
 }
 
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index c4977de..79ac6b9 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -31,6 +31,7 @@
 #include "base/scoped_arena_allocator.h"
 #include "base/timing_logger.h"
 #include "builder.h"
+#include "class_root.h"
 #include "code_generator.h"
 #include "compiled_method.h"
 #include "compiler.h"
@@ -1309,13 +1310,12 @@
   size_t method_info_size = 0;
   codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size);
   size_t number_of_roots = codegen->GetNumberOfJitRoots();
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   // We allocate an object array to ensure the JIT roots that we will collect in EmitJitRoots
   // will be visible by the GC between EmitLiterals and CommitCode. Once CommitCode is
   // executed, this array is not needed.
   Handle<mirror::ObjectArray<mirror::Object>> roots(
       hs.NewHandle(mirror::ObjectArray<mirror::Object>::Alloc(
-          self, class_linker->GetClassRoot(ClassLinker::kObjectArrayClass), number_of_roots)));
+          self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(), number_of_roots)));
   if (roots == nullptr) {
     // Out of memory, just clear the exception to avoid any Java exception uncaught problems.
     MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kJitOutOfMemoryForCommit);
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index ecfa790..f3fe625 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -22,6 +22,7 @@
 #include "base/scoped_arena_containers.h"
 #include "base/enums.h"
 #include "class_linker-inl.h"
+#include "class_root.h"
 #include "handle_scope-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/dex_cache.h"
@@ -40,43 +41,40 @@
 }
 
 static inline ReferenceTypeInfo::TypeHandle GetRootHandle(VariableSizedHandleScope* handles,
-                                                          ClassLinker::ClassRoot class_root,
+                                                          ClassRoot class_root,
                                                           ReferenceTypeInfo::TypeHandle* cache) {
   if (!ReferenceTypeInfo::IsValidHandle(*cache)) {
     // Mutator lock is required for NewHandle.
-    ClassLinker* linker = Runtime::Current()->GetClassLinker();
     ScopedObjectAccess soa(Thread::Current());
-    *cache = handles->NewHandle(linker->GetClassRoot(class_root));
+    *cache = handles->NewHandle(GetClassRoot(class_root));
   }
   return *cache;
 }
 
 ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetObjectClassHandle() {
-  return GetRootHandle(handles_, ClassLinker::kJavaLangObject, &object_class_handle_);
+  return GetRootHandle(handles_, ClassRoot::kJavaLangObject, &object_class_handle_);
 }
 
 ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetClassClassHandle() {
-  return GetRootHandle(handles_, ClassLinker::kJavaLangClass, &class_class_handle_);
+  return GetRootHandle(handles_, ClassRoot::kJavaLangClass, &class_class_handle_);
 }
 
 ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetMethodHandleClassHandle() {
   return GetRootHandle(handles_,
-                       ClassLinker::kJavaLangInvokeMethodHandleImpl,
+                       ClassRoot::kJavaLangInvokeMethodHandleImpl,
                        &method_handle_class_handle_);
 }
 
 ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetMethodTypeClassHandle() {
-  return GetRootHandle(handles_,
-                       ClassLinker::kJavaLangInvokeMethodType,
-                       &method_type_class_handle_);
+  return GetRootHandle(handles_, ClassRoot::kJavaLangInvokeMethodType, &method_type_class_handle_);
 }
 
 ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetStringClassHandle() {
-  return GetRootHandle(handles_, ClassLinker::kJavaLangString, &string_class_handle_);
+  return GetRootHandle(handles_, ClassRoot::kJavaLangString, &string_class_handle_);
 }
 
 ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetThrowableClassHandle() {
-  return GetRootHandle(handles_, ClassLinker::kJavaLangThrowable, &throwable_class_handle_);
+  return GetRootHandle(handles_, ClassRoot::kJavaLangThrowable, &throwable_class_handle_);
 }
 
 class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor {
@@ -341,8 +339,7 @@
 
   {
     ScopedObjectAccess soa(Thread::Current());
-    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-    ArtField* field = class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0);
+    ArtField* field = GetClassRoot<mirror::Object>()->GetInstanceField(0);
     DCHECK_EQ(std::string(field->GetName()), "shadow$_klass_");
     if (field_get->GetFieldInfo().GetField() != field) {
       return;