Remove ClassLinker::array_iftable_.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: Ie0d084945757ec8fcbaa5d02bbc24288f649bac7
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 526c685..941c7ec 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -376,7 +376,6 @@
     : boot_class_table_(new ClassTable()),
       failed_dex_cache_class_lookups_(0),
       class_roots_(nullptr),
-      array_iftable_(nullptr),
       find_array_class_cache_next_victim_(0),
       init_done_(false),
       log_new_roots_(false),
@@ -512,6 +511,10 @@
   // Fill in the empty iftable. Needs to be done after the kObjectArrayClass root is set.
   java_lang_Object->SetIfTable(AllocIfTable(self, 0));
 
+  // Create array interface entries to populate once we can load system classes.
+  object_array_class->SetIfTable(AllocIfTable(self, 2));
+  DCHECK_EQ(GetArrayIfTable(), object_array_class->GetIfTable());
+
   // Setup the primitive type classes.
   SetClassRoot(ClassRoot::kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
   SetClassRoot(ClassRoot::kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
@@ -523,9 +526,6 @@
   SetClassRoot(ClassRoot::kPrimitiveDouble, CreatePrimitiveClass(self, Primitive::kPrimDouble));
   SetClassRoot(ClassRoot::kPrimitiveVoid, CreatePrimitiveClass(self, Primitive::kPrimVoid));
 
-  // Create array interface entries to populate once we can load system classes.
-  array_iftable_ = GcRoot<mirror::IfTable>(AllocIfTable(self, 2));
-
   // Create int array type for native pointer arrays (for example vtables) on 32-bit archs.
   Handle<mirror::Class> int_array_class(hs.NewHandle(
       AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize(image_pointer_size_))));
@@ -639,8 +639,8 @@
   CHECK(java_io_Serializable != nullptr);
   // We assume that Cloneable/Serializable don't have superinterfaces -- normally we'd have to
   // crawl up and explicitly list all of the supers as well.
-  array_iftable_.Read()->SetInterface(0, java_lang_Cloneable.Get());
-  array_iftable_.Read()->SetInterface(1, java_io_Serializable.Get());
+  object_array_class->GetIfTable()->SetInterface(0, java_lang_Cloneable.Get());
+  object_array_class->GetIfTable()->SetInterface(1, java_io_Serializable.Get());
 
   // Sanity check Class[] and Object[]'s interfaces. GetDirectInterface may cause thread
   // suspension.
@@ -841,7 +841,7 @@
     // if possible add new checks there to catch errors early
   }
 
-  CHECK(!array_iftable_.IsNull());
+  CHECK(GetArrayIfTable() != nullptr);
 
   // disable the slow paths in FindClass and CreatePrimitiveClass now
   // that Object, Class, and Object[] are setup
@@ -1000,11 +1000,6 @@
   runtime->SetSentinel(heap->AllocNonMovableObject<true>(
       self, java_lang_Object, java_lang_Object->GetObjectSize(), VoidFunctor()));
 
-  // reinit array_iftable_ from any array class instance, they should be ==
-  array_iftable_ =
-      GcRoot<mirror::IfTable>(GetClassRoot(ClassRoot::kObjectArrayClass, this)->GetIfTable());
-  DCHECK_EQ(array_iftable_.Read(), GetClassRoot(ClassRoot::kBooleanArrayClass, this)->GetIfTable());
-
   for (gc::space::ImageSpace* image_space : spaces) {
     // Boot class loader, use a null handle.
     std::vector<std::unique_ptr<const DexFile>> dex_files;
@@ -1931,7 +1926,6 @@
 void ClassLinker::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) {
   class_roots_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
   VisitClassRoots(visitor, flags);
-  array_iftable_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
   // Instead of visiting the find_array_class_cache_ drop it so that it doesn't prevent class
   // unloading if we are marking roots.
   DropFindArrayClassCache();
@@ -3553,6 +3547,10 @@
   return h_class.Get();
 }
 
+inline ObjPtr<mirror::IfTable> ClassLinker::GetArrayIfTable() {
+  return GetClassRoot<mirror::ObjectArray<mirror::Object>>(this)->GetIfTable();
+}
+
 // Create an array class (i.e. the class object for the array, not the
 // array itself).  "descriptor" looks like "[C" or "[[[[B" or
 // "[Ljava/lang/String;".
@@ -3680,7 +3678,7 @@
   // Use the single, global copies of "interfaces" and "iftable"
   // (remember not to free them for arrays).
   {
-    ObjPtr<mirror::IfTable> array_iftable = array_iftable_.Read();
+    ObjPtr<mirror::IfTable> array_iftable = GetArrayIfTable();
     CHECK(array_iftable != nullptr);
     new_class->SetIfTable(array_iftable);
   }
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 85817ac..f129e0f 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -1275,6 +1275,8 @@
                                 ObjPtr<mirror::ClassLoader> class_loader)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  ObjPtr<mirror::IfTable> GetArrayIfTable() REQUIRES_SHARED(Locks::mutator_lock_);
+
   std::vector<const DexFile*> boot_class_path_;
   std::vector<std::unique_ptr<const DexFile>> boot_dex_files_;
 
@@ -1304,9 +1306,6 @@
   // Well known mirror::Class roots.
   GcRoot<mirror::ObjectArray<mirror::Class>> class_roots_;
 
-  // The interface table used by all arrays.
-  GcRoot<mirror::IfTable> array_iftable_;
-
   // A cache of the last FindArrayClass results. The cache serves to avoid creating array class
   // descriptors for the sake of performing FindClass.
   static constexpr size_t kFindArrayCacheSize = 16;