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;