Remove static GcRoot<>s from Field, Method, Constructor.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 31113334
Change-Id: I648b88339995761fb81180286ef48a42bbd2f83d
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 0587245..028de34 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -778,8 +778,11 @@
       return;
     }
 
+    ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
+        Runtime::Current()->GetClassLinker()->GetClassRoots();
     ObjPtr<mirror::Class> klass = ref->IsClass() ? ref->AsClass() : ref->GetClass();
-    if (klass == mirror::Method::StaticClass() || klass == mirror::Constructor::StaticClass()) {
+    if (klass == GetClassRoot<mirror::Method>(class_roots) ||
+        klass == GetClassRoot<mirror::Constructor>(class_roots)) {
       // Prune all classes using reflection because the content they held will not be fixup.
       *result_ = true;
     }
@@ -2402,7 +2405,10 @@
   if (orig->IsClass()) {
     FixupClass(orig->AsClass<kVerifyNone>(), down_cast<mirror::Class*>(copy));
   } else {
-    if (klass == mirror::Method::StaticClass() || klass == mirror::Constructor::StaticClass()) {
+    ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
+        Runtime::Current()->GetClassLinker()->GetClassRoots();
+    if (klass == GetClassRoot<mirror::Method>(class_roots) ||
+        klass == GetClassRoot<mirror::Constructor>(class_roots)) {
       // Need to go update the ArtMethod.
       auto* dest = down_cast<mirror::Executable*>(copy);
       auto* src = down_cast<mirror::Executable*>(orig);
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index dc9d990..a6d3903 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -43,6 +43,7 @@
 #include "base/unix_file/fd_file.h"
 #include "base/unix_file/random_access_file_utils.h"
 #include "base/utils.h"
+#include "class_root.h"
 #include "elf_file.h"
 #include "elf_file_impl.h"
 #include "elf_utils.h"
@@ -1053,8 +1054,8 @@
                             native_visitor);
       }
     }
-  } else if (object->GetClass() == mirror::Method::StaticClass() ||
-             object->GetClass() == mirror::Constructor::StaticClass()) {
+  } else if (object->GetClass() == GetClassRoot<mirror::Method>() ||
+             object->GetClass() == GetClassRoot<mirror::Constructor>()) {
     // Need to go update the ArtMethod.
     auto* dest = down_cast<mirror::Executable*>(copy);
     auto* src = down_cast<mirror::Executable*>(object);
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index f8b977e..0ff55ae 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -31,6 +31,7 @@
 #include "base/time_utils.h"
 #include "class_linker-inl.h"
 #include "class_linker.h"
+#include "class_root.h"
 #include "dex/descriptors_names.h"
 #include "dex/dex_file-inl.h"
 #include "gc/space/space.h"
@@ -638,8 +639,11 @@
       AbortF("expected non-null method");
       return false;
     }
+    ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
+        Runtime::Current()->GetClassLinker()->GetClassRoots();
     ObjPtr<mirror::Class> c = method->GetClass();
-    if (mirror::Method::StaticClass() != c && mirror::Constructor::StaticClass() != c) {
+    if (c != GetClassRoot<mirror::Method>(class_roots) &&
+        c != GetClassRoot<mirror::Constructor>(class_roots)) {
       AbortF("expected java.lang.reflect.Method or "
           "java.lang.reflect.Constructor but got object of type %s: %p",
           method->PrettyTypeOf().c_str(), jmethod);
@@ -669,7 +673,7 @@
       return false;
     }
     ObjPtr<mirror::Class> c = field->GetClass();
-    if (mirror::Field::StaticClass() != c) {
+    if (GetClassRoot<mirror::Field>() != c) {
       AbortF("expected java.lang.reflect.Field but got object of type %s: %p",
              field->PrettyTypeOf().c_str(), jfield);
       return false;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index ea6d7cc..a2e2686 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -688,33 +688,27 @@
   auto* class_root = FindSystemClass(self, "Ljava/lang/reflect/Field;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kJavaLangReflectField, class_root);
-  mirror::Field::SetClass(class_root);
 
   // Create java.lang.reflect.Field array root.
   class_root = FindSystemClass(self, "[Ljava/lang/reflect/Field;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kJavaLangReflectFieldArrayClass, class_root);
-  mirror::Field::SetArrayClass(class_root);
 
   // Create java.lang.reflect.Constructor.class root and array root.
   class_root = FindSystemClass(self, "Ljava/lang/reflect/Constructor;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kJavaLangReflectConstructor, class_root);
-  mirror::Constructor::SetClass(class_root);
   class_root = FindSystemClass(self, "[Ljava/lang/reflect/Constructor;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kJavaLangReflectConstructorArrayClass, class_root);
-  mirror::Constructor::SetArrayClass(class_root);
 
   // Create java.lang.reflect.Method.class root and array root.
   class_root = FindSystemClass(self, "Ljava/lang/reflect/Method;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kJavaLangReflectMethod, class_root);
-  mirror::Method::SetClass(class_root);
   class_root = FindSystemClass(self, "[Ljava/lang/reflect/Method;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kJavaLangReflectMethodArrayClass, class_root);
-  mirror::Method::SetArrayClass(class_root);
 
   // Create java.lang.invoke.CallSite.class root
   class_root = FindSystemClass(self, "Ljava/lang/invoke/CallSite;");
@@ -1039,14 +1033,6 @@
       GcRoot<mirror::IfTable>(GetClassRoot(ClassRoot::kObjectArrayClass, this)->GetIfTable());
   DCHECK_EQ(array_iftable_.Read(), GetClassRoot(ClassRoot::kBooleanArrayClass, this)->GetIfTable());
   // String class root was set above
-  mirror::Field::SetClass(GetClassRoot(ClassRoot::kJavaLangReflectField, this));
-  mirror::Field::SetArrayClass(GetClassRoot(ClassRoot::kJavaLangReflectFieldArrayClass, this));
-  mirror::Constructor::SetClass(GetClassRoot(ClassRoot::kJavaLangReflectConstructor, this).Ptr());
-  mirror::Constructor::SetArrayClass(
-      GetClassRoot(ClassRoot::kJavaLangReflectConstructorArrayClass, this).Ptr());
-  mirror::Method::SetClass(GetClassRoot(ClassRoot::kJavaLangReflectMethod, this).Ptr());
-  mirror::Method::SetArrayClass(
-      GetClassRoot(ClassRoot::kJavaLangReflectMethodArrayClass, this).Ptr());
   mirror::Throwable::SetClass(GetClassRoot(ClassRoot::kJavaLangThrowable, this));
   mirror::StackTraceElement::SetClass(GetClassRoot(ClassRoot::kJavaLangStackTraceElement, this));
   mirror::EmulatedStackFrame::SetClass(
@@ -2130,15 +2116,9 @@
 
 ClassLinker::~ClassLinker() {
   mirror::Class::ResetClass();
-  mirror::Constructor::ResetClass();
-  mirror::Field::ResetClass();
-  mirror::Method::ResetClass();
   mirror::StackTraceElement::ResetClass();
   mirror::String::ResetClass();
   mirror::Throwable::ResetClass();
-  mirror::Constructor::ResetArrayClass();
-  mirror::Field::ResetArrayClass();
-  mirror::Method::ResetArrayClass();
   mirror::EmulatedStackFrame::ResetClass();
   Thread* const self = Thread::Current();
   for (const ClassLoaderData& data : class_loaders_) {
@@ -4391,7 +4371,7 @@
 
   // They have as many virtual methods as the array
   auto h_methods = hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Method>>(methods));
-  DCHECK_EQ(h_methods->GetClass(), mirror::Method::ArrayClass())
+  DCHECK_EQ(h_methods->GetClass(), GetClassRoot<mirror::ObjectArray<mirror::Method>>())
       << mirror::Class::PrettyClass(h_methods->GetClass());
   const size_t num_virtual_methods = h_methods->GetLength();
 
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index cf67517..987c8e9 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -489,7 +489,7 @@
     CHECK_NON_NULL_ARGUMENT(jlr_field);
     ScopedObjectAccess soa(env);
     ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field);
-    if (obj_field->GetClass() != mirror::Field::StaticClass()) {
+    if (obj_field->GetClass() != GetClassRoot<mirror::Field>()) {
       // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
       return nullptr;
     }
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index bcd2db4..2e263b9 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -21,6 +21,7 @@
 
 #include "art_field-inl.h"
 #include "class-inl.h"
+#include "class_root.h"
 #include "dex_cache-inl.h"
 
 namespace art {
@@ -48,7 +49,7 @@
       self->ClearException();
     }
   }
-  auto ret = hs.NewHandle(ObjPtr<Field>::DownCast(StaticClass()->AllocObject(self)));
+  auto ret = hs.NewHandle(ObjPtr<Field>::DownCast(GetClassRoot<Field>()->AllocObject(self)));
   if (UNLIKELY(ret == nullptr)) {
     self->AssertPendingOOMException();
     return nullptr;
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index b4d93b6..a2b51d8 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -24,36 +24,6 @@
 namespace art {
 namespace mirror {
 
-GcRoot<Class> Field::static_class_;
-GcRoot<Class> Field::array_class_;
-
-void Field::SetClass(ObjPtr<Class> klass) {
-  CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  static_class_ = GcRoot<Class>(klass);
-}
-
-void Field::ResetClass() {
-  CHECK(!static_class_.IsNull());
-  static_class_ = GcRoot<Class>(nullptr);
-}
-
-void Field::SetArrayClass(ObjPtr<Class> klass) {
-  CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  array_class_ = GcRoot<Class>(klass);
-}
-
-void Field::ResetArrayClass() {
-  CHECK(!array_class_.IsNull());
-  array_class_ = GcRoot<Class>(nullptr);
-}
-
-void Field::VisitRoots(RootVisitor* visitor) {
-  static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-  array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
 ArtField* Field::GetArtField() {
   mirror::Class* declaring_class = GetDeclaringClass();
   if (UNLIKELY(declaring_class->IsProxyClass())) {
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index 03fd031..3501e71 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -21,7 +21,6 @@
 #include "base/enums.h"
 #include "dex/modifiers.h"
 #include "dex/primitive.h"
-#include "gc_root.h"
 #include "obj_ptr.h"
 #include "object.h"
 #include "read_barrier_option.h"
@@ -39,14 +38,6 @@
 // C++ mirror of java.lang.reflect.Field.
 class MANAGED Field : public AccessibleObject {
  public:
-  static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return static_class_.Read();
-  }
-
-  static mirror::Class* ArrayClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return array_class_.Read();
-  }
-
   ALWAYS_INLINE uint32_t GetDexFieldIndex() REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, dex_field_index_));
   }
@@ -81,14 +72,6 @@
     return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_));
   }
 
-  static void SetClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
-  static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void SetArrayClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
-  static void ResetArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
-
   // Slow, try to use only for PrettyField and such.
   ArtField* GetArtField() REQUIRES_SHARED(Locks::mutator_lock_);
 
@@ -128,9 +111,6 @@
     SetField32<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, offset_), offset);
   }
 
-  static GcRoot<Class> static_class_;  // java.lang.reflect.Field.class.
-  static GcRoot<Class> array_class_;  // array of java.lang.reflect.Field.
-
   friend struct art::FieldOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(Field);
 };
diff --git a/runtime/mirror/method.cc b/runtime/mirror/method.cc
index 25cbdc1..e5d3403 100644
--- a/runtime/mirror/method.cc
+++ b/runtime/mirror/method.cc
@@ -17,6 +17,7 @@
 #include "method.h"
 
 #include "art_method.h"
+#include "class_root.h"
 #include "gc_root-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
@@ -24,37 +25,10 @@
 namespace art {
 namespace mirror {
 
-GcRoot<Class> Method::static_class_;
-GcRoot<Class> Method::array_class_;
-GcRoot<Class> Constructor::static_class_;
-GcRoot<Class> Constructor::array_class_;
-
-void Method::SetClass(Class* klass) {
-  CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  static_class_ = GcRoot<Class>(klass);
-}
-
-void Method::ResetClass() {
-  CHECK(!static_class_.IsNull());
-  static_class_ = GcRoot<Class>(nullptr);
-}
-
-void Method::SetArrayClass(Class* klass) {
-  CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  array_class_ = GcRoot<Class>(klass);
-}
-
-void Method::ResetArrayClass() {
-  CHECK(!array_class_.IsNull());
-  array_class_ = GcRoot<Class>(nullptr);
-}
-
 template <PointerSize kPointerSize, bool kTransactionActive>
 Method* Method::CreateFromArtMethod(Thread* self, ArtMethod* method) {
   DCHECK(!method->IsConstructor()) << method->PrettyMethod();
-  ObjPtr<Method> ret = ObjPtr<Method>::DownCast(StaticClass()->AllocObject(self));
+  ObjPtr<Method> ret = ObjPtr<Method>::DownCast(GetClassRoot<Method>()->AllocObject(self));
   if (LIKELY(ret != nullptr)) {
     ObjPtr<Executable>(ret)->
         CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
@@ -71,42 +45,11 @@
 template Method* Method::CreateFromArtMethod<PointerSize::k64, true>(Thread* self,
                                                                      ArtMethod* method);
 
-void Method::VisitRoots(RootVisitor* visitor) {
-  static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-  array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
-void Constructor::SetClass(Class* klass) {
-  CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  static_class_ = GcRoot<Class>(klass);
-}
-
-void Constructor::ResetClass() {
-  CHECK(!static_class_.IsNull());
-  static_class_ = GcRoot<Class>(nullptr);
-}
-
-void Constructor::SetArrayClass(Class* klass) {
-  CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  array_class_ = GcRoot<Class>(klass);
-}
-
-void Constructor::ResetArrayClass() {
-  CHECK(!array_class_.IsNull());
-  array_class_ = GcRoot<Class>(nullptr);
-}
-
-void Constructor::VisitRoots(RootVisitor* visitor) {
-  static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-  array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
 template <PointerSize kPointerSize, bool kTransactionActive>
 Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method) {
   DCHECK(method->IsConstructor()) << method->PrettyMethod();
-  ObjPtr<Constructor> ret = ObjPtr<Constructor>::DownCast(StaticClass()->AllocObject(self));
+  ObjPtr<Constructor> ret =
+      ObjPtr<Constructor>::DownCast(GetClassRoot<Constructor>()->AllocObject(self));
   if (LIKELY(ret != nullptr)) {
     ObjPtr<Executable>(ret)->
         CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
diff --git a/runtime/mirror/method.h b/runtime/mirror/method.h
index 61332e3..aea15a7 100644
--- a/runtime/mirror/method.h
+++ b/runtime/mirror/method.h
@@ -18,7 +18,6 @@
 #define ART_RUNTIME_MIRROR_METHOD_H_
 
 #include "executable.h"
-#include "gc_root.h"
 
 namespace art {
 namespace mirror {
@@ -32,28 +31,7 @@
   static Method* CreateFromArtMethod(Thread* self, ArtMethod* method)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return static_class_.Read();
-  }
-
-  static void SetClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static mirror::Class* ArrayClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return array_class_.Read();
-  }
-
-  static void SetArrayClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void ResetArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
-
  private:
-  static GcRoot<Class> static_class_;  // java.lang.reflect.Method.class.
-  static GcRoot<Class> array_class_;  // [java.lang.reflect.Method.class.
-
   DISALLOW_COPY_AND_ASSIGN(Method);
 };
 
@@ -64,28 +42,7 @@
   static Constructor* CreateFromArtMethod(Thread* self, ArtMethod* method)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return static_class_.Read();
-  }
-
-  static void SetClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static mirror::Class* ArrayClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return array_class_.Read();
-  }
-
-  static void SetArrayClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void ResetArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
-
-  static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
-
  private:
-  static GcRoot<Class> static_class_;  // java.lang.reflect.Constructor.class.
-  static GcRoot<Class> array_class_;  // [java.lang.reflect.Constructor.class.
-
   DISALLOW_COPY_AND_ASSIGN(Constructor);
 };
 
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index b7dad89..261178b 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -282,7 +282,7 @@
   }
   size_t array_idx = 0;
   auto object_array = hs.NewHandle(mirror::ObjectArray<mirror::Field>::Alloc(
-      self, mirror::Field::ArrayClass(), array_size));
+      self, GetClassRoot<mirror::ObjectArray<mirror::Field>>(), array_size));
   if (object_array == nullptr) {
     return nullptr;
   }
@@ -539,7 +539,7 @@
     constructor_count += MethodMatchesConstructor(&m, public_only, enforce_hidden_api) ? 1u : 0u;
   }
   auto h_constructors = hs.NewHandle(mirror::ObjectArray<mirror::Constructor>::Alloc(
-      soa.Self(), mirror::Constructor::ArrayClass(), constructor_count));
+      soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Constructor>>(), constructor_count));
   if (UNLIKELY(h_constructors == nullptr)) {
     soa.Self()->AssertPendingException();
     return nullptr;
@@ -598,7 +598,7 @@
     }
   }
   auto ret = hs.NewHandle(mirror::ObjectArray<mirror::Method>::Alloc(
-      soa.Self(), mirror::Method::ArrayClass(), num_methods));
+      soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Method>>(), num_methods));
   if (ret == nullptr) {
     soa.Self()->AssertPendingOOMException();
     return nullptr;
@@ -702,7 +702,7 @@
   }
   ObjPtr<mirror::Object> method = annotations::GetEnclosingMethod(klass);
   if (method != nullptr) {
-    if (mirror::Constructor::StaticClass() == method->GetClass()) {
+    if (GetClassRoot<mirror::Constructor>() == method->GetClass()) {
       return soa.AddLocalReference<jobject>(method);
     }
   }
@@ -718,7 +718,7 @@
   }
   ObjPtr<mirror::Object> method = annotations::GetEnclosingMethod(klass);
   if (method != nullptr) {
-    if (mirror::Method::StaticClass() == method->GetClass()) {
+    if (GetClassRoot<mirror::Method>() == method->GetClass()) {
       return soa.AddLocalReference<jobject>(method);
     }
   }
diff --git a/runtime/proxy_test.h b/runtime/proxy_test.h
index 9836264..fa5a449 100644
--- a/runtime/proxy_test.h
+++ b/runtime/proxy_test.h
@@ -22,6 +22,7 @@
 
 #include "art_method-inl.h"
 #include "class_linker-inl.h"
+#include "class_root.h"
 #include "mirror/class-inl.h"
 #include "mirror/method.h"
 
@@ -59,7 +60,7 @@
     methods_count += interface->NumVirtualMethods();
   }
   jobjectArray proxyClassMethods = soa.Env()->NewObjectArray(
-      methods_count, soa.AddLocalReference<jclass>(mirror::Method::StaticClass()), nullptr);
+      methods_count, soa.AddLocalReference<jclass>(GetClassRoot<mirror::Method>()), nullptr);
   soa.Self()->AssertNoPendingException();
 
   jsize array_index = 0;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index e42bbc2..630053a 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -67,6 +67,7 @@
 #include "base/unix_file/fd_file.h"
 #include "base/utils.h"
 #include "class_linker-inl.h"
+#include "class_root.h"
 #include "compiler_callbacks.h"
 #include "debugger.h"
 #include "dex/art_dex_file_loader.h"
@@ -736,8 +737,9 @@
     ScopedObjectAccess soa(self);
     StackHandleScope<2> hs(soa.Self());
 
-    auto class_class(hs.NewHandle<mirror::Class>(mirror::Class::GetJavaLangClass()));
-    auto field_class(hs.NewHandle<mirror::Class>(mirror::Field::StaticClass()));
+    ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = GetClassLinker()->GetClassRoots();
+    auto class_class(hs.NewHandle<mirror::Class>(GetClassRoot<mirror::Class>(class_roots)));
+    auto field_class(hs.NewHandle<mirror::Class>(GetClassRoot<mirror::Field>(class_roots)));
 
     class_linker_->EnsureInitialized(soa.Self(), class_class, true, true);
     // Field class is needed for register_java_net_InetAddress in libcore, b/28153851.
@@ -1977,12 +1979,9 @@
   // Visit the classes held as static in mirror classes, these can be visited concurrently and only
   // need to be visited once per GC since they never change.
   mirror::Class::VisitRoots(visitor);
-  mirror::Constructor::VisitRoots(visitor);
-  mirror::Method::VisitRoots(visitor);
   mirror::StackTraceElement::VisitRoots(visitor);
   mirror::String::VisitRoots(visitor);
   mirror::Throwable::VisitRoots(visitor);
-  mirror::Field::VisitRoots(visitor);
   mirror::EmulatedStackFrame::VisitRoots(visitor);
   mirror::ClassExt::VisitRoots(visitor);
   // Visiting the roots of these ArtMethods is not currently required since all the GcRoots are