Initialize array classes in pre-fence visitor.

Rewrite array class initialization to make it easier to
reason about memory visibility. Initialize all members in
the pre-fence visitor for the normal use case. Refactor
initialization of core array classes without boot image to
avoid special-casing in ClassLinker::CreateArrayClass().

Note that the Class::object_size_alloc_fast_path_ field
of primitive classes (instances of which cannot be
allocated) will be kept at numeric_limits<uint32_t>::max().
The boot image before and after is otherwise identical.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Change-Id: I570e3af011c8d3383ce46c81eb6f2fa60c5a4b0f
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 8269aaa..a724685 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -800,10 +800,19 @@
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
 
-  // For early bootstrapping by Init.
   // If we do not allow moving classes (`art::kMovingClass` is false) or if
   // parameter `kMovable` is false (or both), the class object is allocated in
   // the non-moving space.
+  template <bool kMovable = true, class PreFenceVisitor>
+  ObjPtr<mirror::Class> AllocClass(Thread* self,
+                                   ObjPtr<mirror::Class> java_lang_Class,
+                                   uint32_t class_size,
+                                   const PreFenceVisitor& pre_fence_visitor)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Roles::uninterruptible_);
+
+  // Convenience AllocClass() overload that uses mirror::Class::InitializeClassVisitor
+  // for the class initialization.
   template <bool kMovable = true>
   ObjPtr<mirror::Class> AllocClass(Thread* self,
                                    ObjPtr<mirror::Class> java_lang_Class,
@@ -811,16 +820,28 @@
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
-  // Alloc* convenience functions to avoid needing to pass in ObjPtr<mirror::Class>
-  // values that are known to the ClassLinker such as classes corresponding to
-  // ClassRoot::kObjectArrayClass and ClassRoot::kJavaLangString etc.
+  // Convenience AllocClass() overload that uses mirror::Class::InitializeClassVisitor
+  // for the class initialization and uses the `java_lang_Class` from class roots
+  // instead of an explicit argument.
   ObjPtr<mirror::Class> AllocClass(Thread* self, uint32_t class_size)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
-  // Allocate a primitive array class.
-  ObjPtr<mirror::Class> AllocPrimitiveArrayClass(Thread* self,
-                                                 ObjPtr<mirror::Class> java_lang_Class)
+  // Allocate a primitive array class and store it in appropriate class root.
+  void AllocPrimitiveArrayClass(Thread* self,
+                                ClassRoot primitive_root,
+                                ClassRoot array_root)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Roles::uninterruptible_);
+
+  // Finish setup of an array class.
+  void FinishArrayClassSetup(ObjPtr<mirror::Class> array_class)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Roles::uninterruptible_);
+
+  // Finish setup of a core array class (Object[], Class[], String[] and
+  // primitive arrays) and insert it into the class table.
+  void FinishCoreArrayClassSetup(ClassRoot array_root)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
@@ -838,7 +859,8 @@
       REQUIRES(!Locks::dex_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
-  ObjPtr<mirror::Class> CreatePrimitiveClass(Thread* self, Primitive::Type type)
+  // Create a primitive class and store it in the appropriate class root.
+  void CreatePrimitiveClass(Thread* self, Primitive::Type type, ClassRoot primitive_root)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
@@ -1251,20 +1273,6 @@
   void SetClassRoot(ClassRoot class_root, ObjPtr<mirror::Class> klass)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  // Allocate primitive array class for primitive with class root
-  // `primitive_class_root`, and associate it to class root
-  // `primitive_array_class_root`.
-  //
-  // Also check this class returned when searching system classes for
-  // `descriptor` matches the allocated class.
-  void AllocAndSetPrimitiveArrayClassRoot(Thread* self,
-                                          ObjPtr<mirror::Class> java_lang_Class,
-                                          ClassRoot primitive_array_class_root,
-                                          ClassRoot primitive_class_root,
-                                          const char* descriptor)
-      REQUIRES_SHARED(Locks::mutator_lock_)
-      REQUIRES(!Roles::uninterruptible_);
-
   // Return the quick generic JNI stub for testing.
   const void* GetRuntimeQuickGenericJniStub() const;