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/runtime/Android.bp b/runtime/Android.bp
index 92607f5..9043866 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -40,6 +40,7 @@
"check_jni.cc",
"class_linker.cc",
"class_loader_context.cc",
+ "class_root.cc",
"class_table.cc",
"common_throws.cc",
"compiler_filter.cc",
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index ae06f8f..7a99d3d 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -365,14 +365,6 @@
return resolved_field;
}
-inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root) {
- DCHECK(!class_roots_.IsNull());
- mirror::ObjectArray<mirror::Class>* class_roots = class_roots_.Read();
- ObjPtr<mirror::Class> klass = class_roots->Get(class_root);
- DCHECK(klass != nullptr);
- return klass.Ptr();
-}
-
template <class Visitor>
inline void ClassLinker::VisitClassTables(const Visitor& visitor) {
Thread* const self = Thread::Current();
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b88aa5e..e2449f9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -51,6 +51,7 @@
#include "cha.h"
#include "class_linker-inl.h"
#include "class_loader_utils.h"
+#include "class_root.h"
#include "class_table-inl.h"
#include "compiler_callbacks.h"
#include "debug_print.h"
@@ -516,29 +517,30 @@
// Create storage for root classes, save away our work so far (requires descriptors).
class_roots_ = GcRoot<mirror::ObjectArray<mirror::Class>>(
- mirror::ObjectArray<mirror::Class>::Alloc(self, object_array_class.Get(),
- kClassRootsMax));
+ mirror::ObjectArray<mirror::Class>::Alloc(self,
+ object_array_class.Get(),
+ static_cast<int32_t>(ClassRoot::kMax)));
CHECK(!class_roots_.IsNull());
- SetClassRoot(kJavaLangClass, java_lang_Class.Get());
- SetClassRoot(kJavaLangObject, java_lang_Object.Get());
- SetClassRoot(kClassArrayClass, class_array_class.Get());
- SetClassRoot(kObjectArrayClass, object_array_class.Get());
- SetClassRoot(kCharArrayClass, char_array_class.Get());
- SetClassRoot(kJavaLangString, java_lang_String.Get());
- SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference.Get());
+ SetClassRoot(ClassRoot::kJavaLangClass, java_lang_Class.Get());
+ SetClassRoot(ClassRoot::kJavaLangObject, java_lang_Object.Get());
+ SetClassRoot(ClassRoot::kClassArrayClass, class_array_class.Get());
+ SetClassRoot(ClassRoot::kObjectArrayClass, object_array_class.Get());
+ SetClassRoot(ClassRoot::kCharArrayClass, char_array_class.Get());
+ SetClassRoot(ClassRoot::kJavaLangString, java_lang_String.Get());
+ SetClassRoot(ClassRoot::kJavaLangRefReference, java_lang_ref_Reference.Get());
// Fill in the empty iftable. Needs to be done after the kObjectArrayClass root is set.
java_lang_Object->SetIfTable(AllocIfTable(self, 0));
// Setup the primitive type classes.
- SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
- SetClassRoot(kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
- SetClassRoot(kPrimitiveShort, CreatePrimitiveClass(self, Primitive::kPrimShort));
- SetClassRoot(kPrimitiveInt, CreatePrimitiveClass(self, Primitive::kPrimInt));
- SetClassRoot(kPrimitiveLong, CreatePrimitiveClass(self, Primitive::kPrimLong));
- SetClassRoot(kPrimitiveFloat, CreatePrimitiveClass(self, Primitive::kPrimFloat));
- SetClassRoot(kPrimitiveDouble, CreatePrimitiveClass(self, Primitive::kPrimDouble));
- SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass(self, Primitive::kPrimVoid));
+ SetClassRoot(ClassRoot::kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
+ SetClassRoot(ClassRoot::kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
+ SetClassRoot(ClassRoot::kPrimitiveShort, CreatePrimitiveClass(self, Primitive::kPrimShort));
+ SetClassRoot(ClassRoot::kPrimitiveInt, CreatePrimitiveClass(self, Primitive::kPrimInt));
+ SetClassRoot(ClassRoot::kPrimitiveLong, CreatePrimitiveClass(self, Primitive::kPrimLong));
+ SetClassRoot(ClassRoot::kPrimitiveFloat, CreatePrimitiveClass(self, Primitive::kPrimFloat));
+ 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));
@@ -546,23 +548,23 @@
// Create int array type for AllocDexCache (done in AppendToBootClassPath).
Handle<mirror::Class> int_array_class(hs.NewHandle(
AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize(image_pointer_size_))));
- int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
+ int_array_class->SetComponentType(GetClassRoot(ClassRoot::kPrimitiveInt, this));
mirror::IntArray::SetArrayClass(int_array_class.Get());
- SetClassRoot(kIntArrayClass, int_array_class.Get());
+ SetClassRoot(ClassRoot::kIntArrayClass, int_array_class.Get());
// Create long array type for AllocDexCache (done in AppendToBootClassPath).
Handle<mirror::Class> long_array_class(hs.NewHandle(
AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize(image_pointer_size_))));
- long_array_class->SetComponentType(GetClassRoot(kPrimitiveLong));
+ long_array_class->SetComponentType(GetClassRoot(ClassRoot::kPrimitiveLong, this));
mirror::LongArray::SetArrayClass(long_array_class.Get());
- SetClassRoot(kLongArrayClass, long_array_class.Get());
+ SetClassRoot(ClassRoot::kLongArrayClass, long_array_class.Get());
// now that these are registered, we can use AllocClass() and AllocObjectArray
// Set up DexCache. This cannot be done later since AppendToBootClassPath calls AllocDexCache.
Handle<mirror::Class> java_lang_DexCache(hs.NewHandle(
AllocClass(self, java_lang_Class.Get(), mirror::DexCache::ClassSize(image_pointer_size_))));
- SetClassRoot(kJavaLangDexCache, java_lang_DexCache.Get());
+ SetClassRoot(ClassRoot::kJavaLangDexCache, java_lang_DexCache.Get());
java_lang_DexCache->SetDexCacheClass();
java_lang_DexCache->SetObjectSize(mirror::DexCache::InstanceSize());
mirror::Class::SetStatus(java_lang_DexCache, ClassStatus::kResolved, self);
@@ -571,7 +573,7 @@
// Setup dalvik.system.ClassExt
Handle<mirror::Class> dalvik_system_ClassExt(hs.NewHandle(
AllocClass(self, java_lang_Class.Get(), mirror::ClassExt::ClassSize(image_pointer_size_))));
- SetClassRoot(kDalvikSystemClassExt, dalvik_system_ClassExt.Get());
+ SetClassRoot(ClassRoot::kDalvikSystemClassExt, dalvik_system_ClassExt.Get());
mirror::ClassExt::SetClass(dalvik_system_ClassExt.Get());
mirror::Class::SetStatus(dalvik_system_ClassExt, ClassStatus::kResolved, self);
@@ -580,7 +582,7 @@
AllocClass(self, java_lang_Class.Get(),
mirror::ObjectArray<mirror::String>::ClassSize(image_pointer_size_))));
object_array_string->SetComponentType(java_lang_String.Get());
- SetClassRoot(kJavaLangStringArrayClass, object_array_string.Get());
+ SetClassRoot(ClassRoot::kJavaLangStringArrayClass, object_array_string.Get());
LinearAlloc* linear_alloc = runtime->GetLinearAlloc();
// Create runtime resolution and imt conflict methods.
@@ -608,7 +610,7 @@
// run char class through InitializePrimitiveClass to finish init
InitializePrimitiveClass(char_class.Get(), Primitive::kPrimChar);
- SetClassRoot(kPrimitiveChar, char_class.Get()); // needs descriptor
+ SetClassRoot(ClassRoot::kPrimitiveChar, char_class.Get()); // needs descriptor
// Set up GenericJNI entrypoint. That is mainly a hack for common_compiler_test.h so that
// we do not need friend classes or a publicly exposed setter.
@@ -634,25 +636,25 @@
CHECK_EQ(dalvik_system_ClassExt->GetObjectSize(), mirror::ClassExt::InstanceSize());
// Setup the primitive array type classes - can't be done until Object has a vtable.
- SetClassRoot(kBooleanArrayClass, FindSystemClass(self, "[Z"));
- mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
+ SetClassRoot(ClassRoot::kBooleanArrayClass, FindSystemClass(self, "[Z"));
+ mirror::BooleanArray::SetArrayClass(GetClassRoot(ClassRoot::kBooleanArrayClass, this));
- SetClassRoot(kByteArrayClass, FindSystemClass(self, "[B"));
- mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
+ SetClassRoot(ClassRoot::kByteArrayClass, FindSystemClass(self, "[B"));
+ mirror::ByteArray::SetArrayClass(GetClassRoot(ClassRoot::kByteArrayClass, this));
CheckSystemClass(self, char_array_class, "[C");
- SetClassRoot(kShortArrayClass, FindSystemClass(self, "[S"));
- mirror::ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
+ SetClassRoot(ClassRoot::kShortArrayClass, FindSystemClass(self, "[S"));
+ mirror::ShortArray::SetArrayClass(GetClassRoot(ClassRoot::kShortArrayClass, this));
CheckSystemClass(self, int_array_class, "[I");
CheckSystemClass(self, long_array_class, "[J");
- SetClassRoot(kFloatArrayClass, FindSystemClass(self, "[F"));
- mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
+ SetClassRoot(ClassRoot::kFloatArrayClass, FindSystemClass(self, "[F"));
+ mirror::FloatArray::SetArrayClass(GetClassRoot(ClassRoot::kFloatArrayClass, this));
- SetClassRoot(kDoubleArrayClass, FindSystemClass(self, "[D"));
- mirror::DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
+ SetClassRoot(ClassRoot::kDoubleArrayClass, FindSystemClass(self, "[D"));
+ mirror::DoubleArray::SetArrayClass(GetClassRoot(ClassRoot::kDoubleArrayClass, this));
// Run Class through FindSystemClass. This initializes the dex_cache_ fields and register it
// in class_table_.
@@ -683,102 +685,103 @@
mirror::Class::GetDirectInterface(self, object_array_class.Get(), 1));
CHECK_EQ(object_array_string.Get(),
- FindSystemClass(self, GetClassRootDescriptor(kJavaLangStringArrayClass)));
+ FindSystemClass(self, GetClassRootDescriptor(ClassRoot::kJavaLangStringArrayClass)));
// End of special init trickery, all subsequent classes may be loaded via FindSystemClass.
// Create java.lang.reflect.Proxy root.
- SetClassRoot(kJavaLangReflectProxy, FindSystemClass(self, "Ljava/lang/reflect/Proxy;"));
+ SetClassRoot(ClassRoot::kJavaLangReflectProxy,
+ FindSystemClass(self, "Ljava/lang/reflect/Proxy;"));
// Create java.lang.reflect.Field.class root.
auto* class_root = FindSystemClass(self, "Ljava/lang/reflect/Field;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangReflectField, class_root);
+ 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(kJavaLangReflectFieldArrayClass, class_root);
+ 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(kJavaLangReflectConstructor, class_root);
+ SetClassRoot(ClassRoot::kJavaLangReflectConstructor, class_root);
mirror::Constructor::SetClass(class_root);
class_root = FindSystemClass(self, "[Ljava/lang/reflect/Constructor;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangReflectConstructorArrayClass, class_root);
+ 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(kJavaLangReflectMethod, class_root);
+ SetClassRoot(ClassRoot::kJavaLangReflectMethod, class_root);
mirror::Method::SetClass(class_root);
class_root = FindSystemClass(self, "[Ljava/lang/reflect/Method;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangReflectMethodArrayClass, class_root);
+ 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;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeCallSite, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeCallSite, class_root);
mirror::CallSite::SetClass(class_root);
// Create java.lang.invoke.MethodType.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/MethodType;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeMethodType, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeMethodType, class_root);
mirror::MethodType::SetClass(class_root);
// Create java.lang.invoke.MethodHandleImpl.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/MethodHandleImpl;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeMethodHandleImpl, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeMethodHandleImpl, class_root);
mirror::MethodHandleImpl::SetClass(class_root);
// Create java.lang.invoke.MethodHandles.Lookup.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/MethodHandles$Lookup;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeMethodHandlesLookup, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeMethodHandlesLookup, class_root);
mirror::MethodHandlesLookup::SetClass(class_root);
// Create java.lang.invoke.VarHandle.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/VarHandle;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeVarHandle, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeVarHandle, class_root);
mirror::VarHandle::SetClass(class_root);
// Create java.lang.invoke.FieldVarHandle.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/FieldVarHandle;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeFieldVarHandle, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeFieldVarHandle, class_root);
mirror::FieldVarHandle::SetClass(class_root);
// Create java.lang.invoke.ArrayElementVarHandle.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/ArrayElementVarHandle;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeArrayElementVarHandle, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeArrayElementVarHandle, class_root);
mirror::ArrayElementVarHandle::SetClass(class_root);
// Create java.lang.invoke.ByteArrayViewVarHandle.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/ByteArrayViewVarHandle;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeByteArrayViewVarHandle, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeByteArrayViewVarHandle, class_root);
mirror::ByteArrayViewVarHandle::SetClass(class_root);
// Create java.lang.invoke.ByteBufferViewVarHandle.class root
class_root = FindSystemClass(self, "Ljava/lang/invoke/ByteBufferViewVarHandle;");
CHECK(class_root != nullptr);
- SetClassRoot(kJavaLangInvokeByteBufferViewVarHandle, class_root);
+ SetClassRoot(ClassRoot::kJavaLangInvokeByteBufferViewVarHandle, class_root);
mirror::ByteBufferViewVarHandle::SetClass(class_root);
class_root = FindSystemClass(self, "Ldalvik/system/EmulatedStackFrame;");
CHECK(class_root != nullptr);
- SetClassRoot(kDalvikSystemEmulatedStackFrame, class_root);
+ SetClassRoot(ClassRoot::kDalvikSystemEmulatedStackFrame, class_root);
mirror::EmulatedStackFrame::SetClass(class_root);
// java.lang.ref classes need to be specially flagged, but otherwise are normal classes
@@ -805,18 +808,19 @@
class_root = FindSystemClass(self, "Ljava/lang/ClassLoader;");
class_root->SetClassLoaderClass();
CHECK_EQ(class_root->GetObjectSize(), mirror::ClassLoader::InstanceSize());
- SetClassRoot(kJavaLangClassLoader, class_root);
+ SetClassRoot(ClassRoot::kJavaLangClassLoader, class_root);
// Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
// java.lang.StackTraceElement as a convenience.
- SetClassRoot(kJavaLangThrowable, FindSystemClass(self, "Ljava/lang/Throwable;"));
- mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
- SetClassRoot(kJavaLangClassNotFoundException,
+ SetClassRoot(ClassRoot::kJavaLangThrowable, FindSystemClass(self, "Ljava/lang/Throwable;"));
+ mirror::Throwable::SetClass(GetClassRoot(ClassRoot::kJavaLangThrowable, this));
+ SetClassRoot(ClassRoot::kJavaLangClassNotFoundException,
FindSystemClass(self, "Ljava/lang/ClassNotFoundException;"));
- SetClassRoot(kJavaLangStackTraceElement, FindSystemClass(self, "Ljava/lang/StackTraceElement;"));
- SetClassRoot(kJavaLangStackTraceElementArrayClass,
+ SetClassRoot(ClassRoot::kJavaLangStackTraceElement,
+ FindSystemClass(self, "Ljava/lang/StackTraceElement;"));
+ SetClassRoot(ClassRoot::kJavaLangStackTraceElementArrayClass,
FindSystemClass(self, "[Ljava/lang/StackTraceElement;"));
- mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
+ mirror::StackTraceElement::SetClass(GetClassRoot(ClassRoot::kJavaLangStackTraceElement, this));
// Create conflict tables that depend on the class linker.
runtime->FixupConflictTables();
@@ -834,8 +838,7 @@
ObjPtr<mirror::Class> string_factory_class =
class_linker->FindSystemClass(self, "Ljava/lang/StringFactory;");
CHECK(string_factory_class != nullptr);
- ObjPtr<mirror::Class> string_class =
- class_linker->GetClassRoot(ClassLinker::ClassRoot::kJavaLangString);
+ ObjPtr<mirror::Class> string_class = GetClassRoot<mirror::String>(class_linker);
WellKnownClasses::InitStringInit(string_class, string_factory_class);
// Update the primordial thread.
self->InitStringEntryPoints();
@@ -851,7 +854,8 @@
// as the types of the field can't be resolved prior to the runtime being
// fully initialized
StackHandleScope<2> hs(self);
- Handle<mirror::Class> java_lang_ref_Reference = hs.NewHandle(GetClassRoot(kJavaLangRefReference));
+ Handle<mirror::Class> java_lang_ref_Reference =
+ hs.NewHandle(GetClassRoot<mirror::Reference>(this));
Handle<mirror::Class> java_lang_ref_FinalizerReference =
hs.NewHandle(FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;"));
@@ -876,7 +880,7 @@
CHECK_STREQ(zombie->GetTypeDescriptor(), "Ljava/lang/Object;");
// ensure all class_roots_ are initialized
- for (size_t i = 0; i < kClassRootsMax; i++) {
+ for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); i++) {
ClassRoot class_root = static_cast<ClassRoot>(i);
ObjPtr<mirror::Class> klass = GetClassRoot(class_root);
CHECK(klass != nullptr);
@@ -896,11 +900,11 @@
void ClassLinker::RunRootClinits() {
Thread* self = Thread::Current();
- for (size_t i = 0; i < ClassLinker::kClassRootsMax; ++i) {
- ObjPtr<mirror::Class> c = GetClassRoot(ClassRoot(i));
+ for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); ++i) {
+ ObjPtr<mirror::Class> c = GetClassRoot(ClassRoot(i), this);
if (!c->IsArrayClass() && !c->IsPrimitive()) {
StackHandleScope<1> hs(self);
- Handle<mirror::Class> h_class(hs.NewHandle(GetClassRoot(ClassRoot(i))));
+ Handle<mirror::Class> h_class(hs.NewHandle(c));
EnsureInitialized(self, h_class, true, true);
self->AssertNoPendingException();
}
@@ -1034,13 +1038,13 @@
class_roots_ = GcRoot<mirror::ObjectArray<mirror::Class>>(
down_cast<mirror::ObjectArray<mirror::Class>*>(
spaces[0]->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)));
- mirror::Class::SetClassClass(class_roots_.Read()->Get(kJavaLangClass));
+ mirror::Class::SetClassClass(GetClassRoot(ClassRoot::kJavaLangClass, this));
// Special case of setting up the String class early so that we can test arbitrary objects
// as being Strings or not
- mirror::String::SetClass(GetClassRoot(kJavaLangString));
+ mirror::String::SetClass(GetClassRoot<mirror::String>(this));
- ObjPtr<mirror::Class> java_lang_Object = GetClassRoot(kJavaLangObject);
+ ObjPtr<mirror::Class> java_lang_Object = GetClassRoot<mirror::Object>(this);
java_lang_Object->SetObjectSize(sizeof(mirror::Object));
// Allocate in non-movable so that it's possible to check if a JNI weak global ref has been
// cleared without triggering the read barrier and unintentionally mark the sentinel alive.
@@ -1048,37 +1052,48 @@
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(kObjectArrayClass)->GetIfTable());
- DCHECK_EQ(array_iftable_.Read(), GetClassRoot(kBooleanArrayClass)->GetIfTable());
+ array_iftable_ =
+ 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(kJavaLangReflectField));
- mirror::Field::SetArrayClass(GetClassRoot(kJavaLangReflectFieldArrayClass));
- mirror::Constructor::SetClass(GetClassRoot(kJavaLangReflectConstructor));
- mirror::Constructor::SetArrayClass(GetClassRoot(kJavaLangReflectConstructorArrayClass));
- mirror::Method::SetClass(GetClassRoot(kJavaLangReflectMethod));
- mirror::Method::SetArrayClass(GetClassRoot(kJavaLangReflectMethodArrayClass));
- mirror::CallSite::SetClass(GetClassRoot(kJavaLangInvokeCallSite));
- mirror::MethodHandleImpl::SetClass(GetClassRoot(kJavaLangInvokeMethodHandleImpl));
- mirror::MethodHandlesLookup::SetClass(GetClassRoot(kJavaLangInvokeMethodHandlesLookup));
- mirror::MethodType::SetClass(GetClassRoot(kJavaLangInvokeMethodType));
- mirror::VarHandle::SetClass(GetClassRoot(kJavaLangInvokeVarHandle));
- mirror::FieldVarHandle::SetClass(GetClassRoot(kJavaLangInvokeFieldVarHandle));
- mirror::ArrayElementVarHandle::SetClass(GetClassRoot(kJavaLangInvokeArrayElementVarHandle));
- mirror::ByteArrayViewVarHandle::SetClass(GetClassRoot(kJavaLangInvokeByteArrayViewVarHandle));
- mirror::ByteBufferViewVarHandle::SetClass(GetClassRoot(kJavaLangInvokeByteBufferViewVarHandle));
- mirror::Reference::SetClass(GetClassRoot(kJavaLangRefReference));
- mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
- mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
- mirror::CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
- mirror::DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
- mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
- mirror::IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
- mirror::LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
- mirror::ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
- mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
- mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
- mirror::EmulatedStackFrame::SetClass(GetClassRoot(kDalvikSystemEmulatedStackFrame));
- mirror::ClassExt::SetClass(GetClassRoot(kDalvikSystemClassExt));
+ 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::CallSite::SetClass(GetClassRoot(ClassRoot::kJavaLangInvokeCallSite, this).Ptr());
+ mirror::MethodHandleImpl::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeMethodHandleImpl, this).Ptr());
+ mirror::MethodHandlesLookup::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeMethodHandlesLookup, this).Ptr());
+ mirror::MethodType::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeMethodType, this).Ptr());
+ mirror::VarHandle::SetClass(GetClassRoot(ClassRoot::kJavaLangInvokeVarHandle, this).Ptr());
+ mirror::FieldVarHandle::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeFieldVarHandle, this).Ptr());
+ mirror::ArrayElementVarHandle::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeArrayElementVarHandle, this).Ptr());
+ mirror::ByteArrayViewVarHandle::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeByteArrayViewVarHandle, this).Ptr());
+ mirror::ByteBufferViewVarHandle::SetClass(
+ GetClassRoot(ClassRoot::kJavaLangInvokeByteBufferViewVarHandle, this).Ptr());
+ mirror::Reference::SetClass(GetClassRoot(ClassRoot::kJavaLangRefReference, this));
+ mirror::BooleanArray::SetArrayClass(GetClassRoot(ClassRoot::kBooleanArrayClass, this));
+ mirror::ByteArray::SetArrayClass(GetClassRoot(ClassRoot::kByteArrayClass, this));
+ mirror::CharArray::SetArrayClass(GetClassRoot(ClassRoot::kCharArrayClass, this));
+ mirror::DoubleArray::SetArrayClass(GetClassRoot(ClassRoot::kDoubleArrayClass, this));
+ mirror::FloatArray::SetArrayClass(GetClassRoot(ClassRoot::kFloatArrayClass, this));
+ mirror::IntArray::SetArrayClass(GetClassRoot(ClassRoot::kIntArrayClass, this));
+ mirror::LongArray::SetArrayClass(GetClassRoot(ClassRoot::kLongArrayClass, this));
+ mirror::ShortArray::SetArrayClass(GetClassRoot(ClassRoot::kShortArrayClass, this));
+ mirror::Throwable::SetClass(GetClassRoot(ClassRoot::kJavaLangThrowable, this));
+ mirror::StackTraceElement::SetClass(GetClassRoot(ClassRoot::kJavaLangStackTraceElement, this));
+ mirror::EmulatedStackFrame::SetClass(
+ GetClassRoot(ClassRoot::kDalvikSystemEmulatedStackFrame, this).Ptr());
+ mirror::ClassExt::SetClass(GetClassRoot(ClassRoot::kDalvikSystemClassExt, this));
for (gc::space::ImageSpace* image_space : spaces) {
// Boot class loader, use a null handle.
@@ -1695,15 +1710,16 @@
MutableHandle<mirror::ClassLoader> image_class_loader(hs.NewHandle(
app_image ? header.GetImageRoot(ImageHeader::kClassLoader)->AsClassLoader() : nullptr));
DCHECK(class_roots != nullptr);
- if (class_roots->GetLength() != static_cast<int32_t>(kClassRootsMax)) {
+ if (class_roots->GetLength() != static_cast<int32_t>(ClassRoot::kMax)) {
*error_msg = StringPrintf("Expected %d class roots but got %d",
class_roots->GetLength(),
- static_cast<int32_t>(kClassRootsMax));
+ static_cast<int32_t>(ClassRoot::kMax));
return false;
}
// Check against existing class roots to make sure they match the ones in the boot image.
- for (size_t i = 0; i < kClassRootsMax; i++) {
- if (class_roots->Get(i) != GetClassRoot(static_cast<ClassRoot>(i))) {
+ ObjPtr<mirror::ObjectArray<mirror::Class>> existing_class_roots = GetClassRoots();
+ for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); i++) {
+ if (class_roots->Get(i) != GetClassRoot(static_cast<ClassRoot>(i), existing_class_roots)) {
*error_msg = "App image class roots must have pointer equality with runtime ones.";
return false;
}
@@ -2231,7 +2247,7 @@
StackHandleScope<1> hs(self);
DCHECK(out_location != nullptr);
auto dex_cache(hs.NewHandle(ObjPtr<mirror::DexCache>::DownCast(
- GetClassRoot(kJavaLangDexCache)->AllocObject(self))));
+ GetClassRoot<mirror::DexCache>(this)->AllocObject(self))));
if (dex_cache == nullptr) {
self->AssertPendingOOMException();
return nullptr;
@@ -2280,14 +2296,14 @@
}
mirror::Class* ClassLinker::AllocClass(Thread* self, uint32_t class_size) {
- return AllocClass(self, GetClassRoot(kJavaLangClass), class_size);
+ return AllocClass(self, GetClassRoot<mirror::Class>(this), class_size);
}
mirror::ObjectArray<mirror::StackTraceElement>* ClassLinker::AllocStackTraceElementArray(
Thread* self,
size_t length) {
return mirror::ObjectArray<mirror::StackTraceElement>::Alloc(
- self, GetClassRoot(kJavaLangStackTraceElementArrayClass), length);
+ self, GetClassRoot<mirror::ObjectArray<mirror::StackTraceElement>>(this), length);
}
mirror::Class* ClassLinker::EnsureResolved(Thread* self,
@@ -2684,17 +2700,17 @@
if (UNLIKELY(!init_done_)) {
// finish up init of hand crafted class_roots_
if (strcmp(descriptor, "Ljava/lang/Object;") == 0) {
- klass.Assign(GetClassRoot(kJavaLangObject));
+ klass.Assign(GetClassRoot<mirror::Object>(this));
} else if (strcmp(descriptor, "Ljava/lang/Class;") == 0) {
- klass.Assign(GetClassRoot(kJavaLangClass));
+ klass.Assign(GetClassRoot<mirror::Class>(this));
} else if (strcmp(descriptor, "Ljava/lang/String;") == 0) {
- klass.Assign(GetClassRoot(kJavaLangString));
+ klass.Assign(GetClassRoot<mirror::String>(this));
} else if (strcmp(descriptor, "Ljava/lang/ref/Reference;") == 0) {
- klass.Assign(GetClassRoot(kJavaLangRefReference));
+ klass.Assign(GetClassRoot<mirror::Reference>(this));
} else if (strcmp(descriptor, "Ljava/lang/DexCache;") == 0) {
- klass.Assign(GetClassRoot(kJavaLangDexCache));
+ klass.Assign(GetClassRoot<mirror::DexCache>(this));
} else if (strcmp(descriptor, "Ldalvik/system/ClassExt;") == 0) {
- klass.Assign(GetClassRoot(kDalvikSystemClassExt));
+ klass.Assign(GetClassRoot<mirror::ClassExt>(this));
}
}
@@ -2744,7 +2760,7 @@
ObjectLock<mirror::Class> lock(self, klass);
klass->SetClinitThreadId(self->GetTid());
// Make sure we have a valid empty iftable even if there are errors.
- klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
+ klass->SetIfTable(GetClassRoot<mirror::Object>(this)->GetIfTable());
// Add the newly loaded class to the loaded classes table.
ObjPtr<mirror::Class> existing = InsertClass(descriptor, klass.Get(), hash);
@@ -3084,7 +3100,7 @@
const char* descriptor = dex_file.GetClassDescriptor(dex_class_def);
CHECK(descriptor != nullptr);
- klass->SetClass(GetClassRoot(kJavaLangClass));
+ klass->SetClass(GetClassRoot<mirror::Class>(this));
uint32_t access_flags = dex_class_def.GetJavaAccessFlags();
CHECK_EQ(access_flags & ~kAccJavaFlagsMask, 0U);
klass->SetAccessFlags(access_flags);
@@ -3654,7 +3670,7 @@
ObjectLock<mirror::Class> lock(self, h_class);
h_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
h_class->SetPrimitiveType(type);
- h_class->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
+ h_class->SetIfTable(GetClassRoot<mirror::Object>(this)->GetIfTable());
mirror::Class::SetStatus(h_class, ClassStatus::kInitialized, self);
const char* descriptor = Primitive::Descriptor(type);
ObjPtr<mirror::Class> existing = InsertClass(descriptor,
@@ -3737,17 +3753,17 @@
if (UNLIKELY(!init_done_)) {
// Classes that were hand created, ie not by FindSystemClass
if (strcmp(descriptor, "[Ljava/lang/Class;") == 0) {
- new_class.Assign(GetClassRoot(kClassArrayClass));
+ new_class.Assign(GetClassRoot<mirror::ObjectArray<mirror::Class>>(this));
} else if (strcmp(descriptor, "[Ljava/lang/Object;") == 0) {
- new_class.Assign(GetClassRoot(kObjectArrayClass));
- } else if (strcmp(descriptor, GetClassRootDescriptor(kJavaLangStringArrayClass)) == 0) {
- new_class.Assign(GetClassRoot(kJavaLangStringArrayClass));
+ new_class.Assign(GetClassRoot<mirror::ObjectArray<mirror::Object>>(this));
+ } else if (strcmp(descriptor, "[Ljava/lang/String;") == 0) {
+ new_class.Assign(GetClassRoot<mirror::ObjectArray<mirror::String>>(this));
} else if (strcmp(descriptor, "[C") == 0) {
- new_class.Assign(GetClassRoot(kCharArrayClass));
+ new_class.Assign(GetClassRoot<mirror::CharArray>(this));
} else if (strcmp(descriptor, "[I") == 0) {
- new_class.Assign(GetClassRoot(kIntArrayClass));
+ new_class.Assign(GetClassRoot<mirror::IntArray>(this));
} else if (strcmp(descriptor, "[J") == 0) {
- new_class.Assign(GetClassRoot(kLongArrayClass));
+ new_class.Assign(GetClassRoot<mirror::LongArray>(this));
}
}
if (new_class == nullptr) {
@@ -3760,7 +3776,7 @@
}
ObjectLock<mirror::Class> lock(self, new_class); // Must hold lock on object when initializing.
DCHECK(new_class->GetComponentType() != nullptr);
- ObjPtr<mirror::Class> java_lang_Object = GetClassRoot(kJavaLangObject);
+ ObjPtr<mirror::Class> java_lang_Object = GetClassRoot<mirror::Object>(this);
new_class->SetSuperClass(java_lang_Object);
new_class->SetVTable(java_lang_Object->GetVTable());
new_class->SetPrimitiveType(Primitive::kPrimNot);
@@ -3828,25 +3844,26 @@
}
mirror::Class* ClassLinker::FindPrimitiveClass(char type) {
+ ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = GetClassRoots();
switch (type) {
case 'B':
- return GetClassRoot(kPrimitiveByte);
+ return GetClassRoot(ClassRoot::kPrimitiveByte, class_roots).Ptr();
case 'C':
- return GetClassRoot(kPrimitiveChar);
+ return GetClassRoot(ClassRoot::kPrimitiveChar, class_roots).Ptr();
case 'D':
- return GetClassRoot(kPrimitiveDouble);
+ return GetClassRoot(ClassRoot::kPrimitiveDouble, class_roots).Ptr();
case 'F':
- return GetClassRoot(kPrimitiveFloat);
+ return GetClassRoot(ClassRoot::kPrimitiveFloat, class_roots).Ptr();
case 'I':
- return GetClassRoot(kPrimitiveInt);
+ return GetClassRoot(ClassRoot::kPrimitiveInt, class_roots).Ptr();
case 'J':
- return GetClassRoot(kPrimitiveLong);
+ return GetClassRoot(ClassRoot::kPrimitiveLong, class_roots).Ptr();
case 'S':
- return GetClassRoot(kPrimitiveShort);
+ return GetClassRoot(ClassRoot::kPrimitiveShort, class_roots).Ptr();
case 'Z':
- return GetClassRoot(kPrimitiveBoolean);
+ return GetClassRoot(ClassRoot::kPrimitiveBoolean, class_roots).Ptr();
case 'V':
- return GetClassRoot(kPrimitiveVoid);
+ return GetClassRoot(ClassRoot::kPrimitiveVoid, class_roots).Ptr();
default:
break;
}
@@ -4381,7 +4398,7 @@
Thread* self = soa.Self();
StackHandleScope<10> hs(self);
MutableHandle<mirror::Class> temp_klass(hs.NewHandle(
- AllocClass(self, GetClassRoot(kJavaLangClass), sizeof(mirror::Class))));
+ AllocClass(self, GetClassRoot<mirror::Class>(this), sizeof(mirror::Class))));
if (temp_klass == nullptr) {
CHECK(self->IsExceptionPending()); // OOME.
return nullptr;
@@ -4394,9 +4411,9 @@
temp_klass->SetClassLoader(soa.Decode<mirror::ClassLoader>(loader));
DCHECK_EQ(temp_klass->GetPrimitiveType(), Primitive::kPrimNot);
temp_klass->SetName(soa.Decode<mirror::String>(name));
- temp_klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache());
+ temp_klass->SetDexCache(GetClassRoot<mirror::Proxy>(this)->GetDexCache());
// Object has an empty iftable, copy it for that reason.
- temp_klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
+ temp_klass->SetIfTable(GetClassRoot<mirror::Object>(this)->GetIfTable());
mirror::Class::SetStatus(temp_klass, ClassStatus::kIdx, self);
std::string descriptor(GetDescriptorForProxy(temp_klass.Get()));
const size_t hash = ComputeModifiedUtf8Hash(descriptor.c_str());
@@ -4463,7 +4480,7 @@
}
// The super class is java.lang.reflect.Proxy
- temp_klass->SetSuperClass(GetClassRoot(kJavaLangReflectProxy));
+ temp_klass->SetSuperClass(GetClassRoot<mirror::Proxy>(this));
// Now effectively in the loaded state.
mirror::Class::SetStatus(temp_klass, ClassStatus::kLoaded, self);
self->AssertNoPendingException();
@@ -4551,11 +4568,12 @@
void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out) {
// Create constructor for Proxy that must initialize the method.
- CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 21u);
+ ObjPtr<mirror::Class> proxy_class = GetClassRoot<mirror::Proxy>(this);
+ CHECK_EQ(proxy_class->NumDirectMethods(), 21u);
// Find the <init>(InvocationHandler)V method. The exact method offset varies depending
// on which front-end compiler was used to build the libcore DEX files.
- ArtMethod* proxy_constructor = GetClassRoot(kJavaLangReflectProxy)->FindConstructor(
+ ArtMethod* proxy_constructor = proxy_class->FindConstructor(
"(Ljava/lang/reflect/InvocationHandler;)V", image_pointer_size_);
DCHECK(proxy_constructor != nullptr)
<< "Could not find <init> method in java.lang.reflect.Proxy";
@@ -5553,7 +5571,8 @@
bool ClassLinker::LinkSuperClass(Handle<mirror::Class> klass) {
CHECK(!klass->IsPrimitive());
ObjPtr<mirror::Class> super = klass->GetSuperClass();
- if (klass.Get() == GetClassRoot(kJavaLangObject)) {
+ ObjPtr<mirror::Class> object_class = GetClassRoot<mirror::Object>(this);
+ if (klass.Get() == object_class) {
if (super != nullptr) {
ThrowClassFormatError(klass.Get(), "java.lang.Object must not have a superclass");
return false;
@@ -5566,7 +5585,7 @@
return false;
}
// Verify
- if (klass->IsInterface() && super != GetClassRoot(kJavaLangObject)) {
+ if (klass->IsInterface() && super != object_class) {
ThrowClassFormatError(klass.Get(), "Interfaces must have java.lang.Object as superclass");
return false;
}
@@ -5609,7 +5628,7 @@
klass->SetClassFlags(klass->GetClassFlags() | reference_flags);
}
// Disallow custom direct subclasses of java.lang.ref.Reference.
- if (init_done_ && super == GetClassRoot(kJavaLangRefReference)) {
+ if (init_done_ && super == GetClassRoot<mirror::Reference>(this)) {
ThrowLinkageError(klass.Get(),
"Class %s attempts to subclass java.lang.ref.Reference, which is not allowed",
klass->PrettyDescriptor().c_str());
@@ -5974,7 +5993,7 @@
}
klass->SetVTable(vtable.Get());
} else {
- CHECK_EQ(klass.Get(), GetClassRoot(kJavaLangObject));
+ CHECK_EQ(klass.Get(), GetClassRoot<mirror::Object>(this));
if (!IsUint<16>(num_virtual_methods)) {
ThrowClassFormatError(klass.Get(), "Too many methods: %d",
static_cast<int>(num_virtual_methods));
@@ -7851,7 +7870,7 @@
// Convert a ClassNotFoundException to a NoClassDefFoundError.
StackHandleScope<1> hs(self);
Handle<mirror::Throwable> cause(hs.NewHandle(self->GetException()));
- if (cause->InstanceOf(GetClassRoot(kJavaLangClassNotFoundException))) {
+ if (cause->InstanceOf(GetClassRoot(ClassRoot::kJavaLangClassNotFoundException, this))) {
DCHECK(resolved == nullptr); // No Handle needed to preserve resolved.
self->ClearException();
ThrowNoClassDefFoundError("Failed resolution of: %s", descriptor);
@@ -8678,67 +8697,10 @@
mirror::ObjectArray<mirror::Class>* class_roots = class_roots_.Read();
DCHECK(class_roots != nullptr);
- DCHECK(class_roots->Get(class_root) == nullptr);
- class_roots->Set<false>(class_root, klass);
-}
-
-const char* ClassLinker::GetClassRootDescriptor(ClassRoot class_root) {
- static const char* class_roots_descriptors[] = {
- "Ljava/lang/Class;",
- "Ljava/lang/Object;",
- "[Ljava/lang/Class;",
- "[Ljava/lang/Object;",
- "Ljava/lang/String;",
- "Ljava/lang/DexCache;",
- "Ljava/lang/ref/Reference;",
- "Ljava/lang/reflect/Constructor;",
- "Ljava/lang/reflect/Field;",
- "Ljava/lang/reflect/Method;",
- "Ljava/lang/reflect/Proxy;",
- "[Ljava/lang/String;",
- "[Ljava/lang/reflect/Constructor;",
- "[Ljava/lang/reflect/Field;",
- "[Ljava/lang/reflect/Method;",
- "Ljava/lang/invoke/CallSite;",
- "Ljava/lang/invoke/MethodHandleImpl;",
- "Ljava/lang/invoke/MethodHandles$Lookup;",
- "Ljava/lang/invoke/MethodType;",
- "Ljava/lang/invoke/VarHandle;",
- "Ljava/lang/invoke/FieldVarHandle;",
- "Ljava/lang/invoke/ArrayElementVarHandle;",
- "Ljava/lang/invoke/ByteArrayViewVarHandle;",
- "Ljava/lang/invoke/ByteBufferViewVarHandle;",
- "Ljava/lang/ClassLoader;",
- "Ljava/lang/Throwable;",
- "Ljava/lang/ClassNotFoundException;",
- "Ljava/lang/StackTraceElement;",
- "Ldalvik/system/EmulatedStackFrame;",
- "Z",
- "B",
- "C",
- "D",
- "F",
- "I",
- "J",
- "S",
- "V",
- "[Z",
- "[B",
- "[C",
- "[D",
- "[F",
- "[I",
- "[J",
- "[S",
- "[Ljava/lang/StackTraceElement;",
- "Ldalvik/system/ClassExt;",
- };
- static_assert(arraysize(class_roots_descriptors) == size_t(kClassRootsMax),
- "Mismatch between class descriptors and class-root enum");
-
- const char* descriptor = class_roots_descriptors[class_root];
- CHECK(descriptor != nullptr);
- return descriptor;
+ DCHECK_LT(static_cast<uint32_t>(class_root), static_cast<uint32_t>(ClassRoot::kMax));
+ int32_t index = static_cast<int32_t>(class_root);
+ DCHECK(class_roots->Get(index) == nullptr);
+ class_roots->Set<false>(index, klass);
}
jobject ClassLinker::CreateWellKnownClassLoader(Thread* self,
@@ -9071,7 +9033,7 @@
mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount) {
return down_cast<mirror::IfTable*>(
mirror::IfTable::Alloc(self,
- GetClassRoot(kObjectArrayClass),
+ GetClassRoot<mirror::ObjectArray<mirror::Object>>(this),
ifcount * mirror::IfTable::kMax));
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 52ecf82..afe5c99 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -68,6 +68,7 @@
} // namespace mirror
class ClassHierarchyAnalysis;
+enum class ClassRoot : uint32_t;
class ClassTable;
template<class T> class Handle;
class ImtConflictTable;
@@ -107,59 +108,6 @@
class ClassLinker {
public:
- // Well known mirror::Class roots accessed via GetClassRoot.
- enum ClassRoot {
- kJavaLangClass,
- kJavaLangObject,
- kClassArrayClass,
- kObjectArrayClass,
- kJavaLangString,
- kJavaLangDexCache,
- kJavaLangRefReference,
- kJavaLangReflectConstructor,
- kJavaLangReflectField,
- kJavaLangReflectMethod,
- kJavaLangReflectProxy,
- kJavaLangStringArrayClass,
- kJavaLangReflectConstructorArrayClass,
- kJavaLangReflectFieldArrayClass,
- kJavaLangReflectMethodArrayClass,
- kJavaLangInvokeCallSite,
- kJavaLangInvokeMethodHandleImpl,
- kJavaLangInvokeMethodHandlesLookup,
- kJavaLangInvokeMethodType,
- kJavaLangInvokeVarHandle,
- kJavaLangInvokeFieldVarHandle,
- kJavaLangInvokeArrayElementVarHandle,
- kJavaLangInvokeByteArrayViewVarHandle,
- kJavaLangInvokeByteBufferViewVarHandle,
- kJavaLangClassLoader,
- kJavaLangThrowable,
- kJavaLangClassNotFoundException,
- kJavaLangStackTraceElement,
- kDalvikSystemEmulatedStackFrame,
- kPrimitiveBoolean,
- kPrimitiveByte,
- kPrimitiveChar,
- kPrimitiveDouble,
- kPrimitiveFloat,
- kPrimitiveInt,
- kPrimitiveLong,
- kPrimitiveShort,
- kPrimitiveVoid,
- kBooleanArrayClass,
- kByteArrayClass,
- kCharArrayClass,
- kDoubleArrayClass,
- kFloatArrayClass,
- kIntArrayClass,
- kLongArrayClass,
- kShortArrayClass,
- kJavaLangStackTraceElementArrayClass,
- kDalvikSystemClassExt,
- kClassRootsMax,
- };
-
static constexpr bool kAppImageMayContainStrings = false;
explicit ClassLinker(InternTable* intern_table);
@@ -552,10 +500,6 @@
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
- mirror::Class* GetClassRoot(ClassRoot class_root) REQUIRES_SHARED(Locks::mutator_lock_);
-
- static const char* GetClassRootDescriptor(ClassRoot class_root);
-
// Is the given entry point quick code to run the resolution stub?
bool IsQuickResolutionStub(const void* entry_point) const;
@@ -597,8 +541,9 @@
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
mirror::ObjectArray<mirror::Class>* GetClassRoots() REQUIRES_SHARED(Locks::mutator_lock_) {
- mirror::ObjectArray<mirror::Class>* class_roots = class_roots_.Read();
+ mirror::ObjectArray<mirror::Class>* class_roots = class_roots_.Read<kReadBarrierOption>();
DCHECK(class_roots != nullptr);
return class_roots;
}
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 6ed029c..48ec6b6 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -25,6 +25,7 @@
#include "art_method-inl.h"
#include "base/enums.h"
#include "class_linker-inl.h"
+#include "class_root.h"
#include "common_runtime_test.h"
#include "dex/dex_file_types.h"
#include "dex/standard_dex_file.h"
@@ -1387,11 +1388,10 @@
TEST_F(ClassLinkerTest, ClassRootDescriptors) {
ScopedObjectAccess soa(Thread::Current());
std::string temp;
- for (int i = 0; i < ClassLinker::kClassRootsMax; i++) {
- ObjPtr<mirror::Class> klass = class_linker_->GetClassRoot(ClassLinker::ClassRoot(i));
+ for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); i++) {
+ ObjPtr<mirror::Class> klass = GetClassRoot(ClassRoot(i), class_linker_);
EXPECT_GT(strlen(klass->GetDescriptor(&temp)), 0U);
- EXPECT_STREQ(klass->GetDescriptor(&temp),
- class_linker_->GetClassRootDescriptor(ClassLinker::ClassRoot(i))) << " i = " << i;
+ EXPECT_STREQ(klass->GetDescriptor(&temp), GetClassRootDescriptor(ClassRoot(i))) << " i = " << i;
}
}
diff --git a/runtime/class_root.cc b/runtime/class_root.cc
new file mode 100644
index 0000000..08820b0
--- /dev/null
+++ b/runtime/class_root.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "class_root.h"
+
+namespace art {
+
+const char* GetClassRootDescriptor(ClassRoot class_root) {
+ static const char* class_roots_descriptors[] = {
+#define CLASS_ROOT_DESCRIPTOR(name, descriptor, mirror_type) descriptor,
+ CLASS_ROOT_LIST(CLASS_ROOT_DESCRIPTOR)
+#undef CLASS_ROOT_DESCRIPTOR
+ };
+ static_assert(arraysize(class_roots_descriptors) == static_cast<size_t>(ClassRoot::kMax),
+ "Mismatch between class descriptors and class-root enum");
+
+ DCHECK_LT(static_cast<uint32_t>(class_root), static_cast<uint32_t>(ClassRoot::kMax));
+ const char* descriptor = class_roots_descriptors[static_cast<size_t>(class_root)];
+ CHECK(descriptor != nullptr);
+ return descriptor;
+}
+
+} // namespace art
diff --git a/runtime/class_root.h b/runtime/class_root.h
new file mode 100644
index 0000000..f43e2c6
--- /dev/null
+++ b/runtime/class_root.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_CLASS_ROOT_H_
+#define ART_RUNTIME_CLASS_ROOT_H_
+
+#include "class_linker.h"
+#include "mirror/class.h"
+#include "mirror/object_array-inl.h"
+#include "obj_ptr-inl.h"
+#include "runtime.h"
+
+namespace art {
+
+namespace mirror {
+class ArrayElementVarHandle;
+class ByteArrayViewVarHandle;
+class ByteBufferViewVarHandle;
+class CallSite;
+class ClassExt;
+class ClassLoader;
+class Constructor;
+class DexCache;
+class EmulatedStackFrame;
+class Field;
+class FieldVarHandle;
+class Method;
+class MethodHandleImpl;
+class MethodHandlesLookup;
+class MethodType;
+class Object;
+class Proxy;
+template<typename T> class PrimitiveArray;
+class Reference;
+class StackTraceElement;
+class String;
+class Throwable;
+class VarHandle;
+} // namespace mirror
+
+#define CLASS_ROOT_LIST(M) \
+ M(kJavaLangClass, "Ljava/lang/Class;", mirror::Class) \
+ M(kJavaLangObject, "Ljava/lang/Object;", mirror::Object) \
+ M(kClassArrayClass, "[Ljava/lang/Class;", mirror::ObjectArray<mirror::Class>) \
+ M(kObjectArrayClass, "[Ljava/lang/Object;", mirror::ObjectArray<mirror::Object>) \
+ M(kJavaLangString, "Ljava/lang/String;", mirror::String) \
+ M(kJavaLangDexCache, "Ljava/lang/DexCache;", mirror::DexCache) \
+ M(kJavaLangRefReference, "Ljava/lang/ref/Reference;", mirror::Reference) \
+ M(kJavaLangReflectConstructor, "Ljava/lang/reflect/Constructor;", mirror::Constructor) \
+ M(kJavaLangReflectField, "Ljava/lang/reflect/Field;", mirror::Field) \
+ M(kJavaLangReflectMethod, "Ljava/lang/reflect/Method;", mirror::Method) \
+ M(kJavaLangReflectProxy, "Ljava/lang/reflect/Proxy;", mirror::Proxy) \
+ M(kJavaLangStringArrayClass, "[Ljava/lang/String;", mirror::ObjectArray<mirror::String>) \
+ M(kJavaLangReflectConstructorArrayClass, "[Ljava/lang/reflect/Constructor;", mirror::ObjectArray<mirror::Constructor>) \
+ M(kJavaLangReflectFieldArrayClass, "[Ljava/lang/reflect/Field;", mirror::ObjectArray<mirror::Field>) \
+ M(kJavaLangReflectMethodArrayClass, "[Ljava/lang/reflect/Method;", mirror::ObjectArray<mirror::Method>) \
+ M(kJavaLangInvokeCallSite, "Ljava/lang/invoke/CallSite;", mirror::CallSite) \
+ M(kJavaLangInvokeMethodHandleImpl, "Ljava/lang/invoke/MethodHandleImpl;", mirror::MethodHandleImpl) \
+ M(kJavaLangInvokeMethodHandlesLookup, "Ljava/lang/invoke/MethodHandles$Lookup;", mirror::MethodHandlesLookup) \
+ M(kJavaLangInvokeMethodType, "Ljava/lang/invoke/MethodType;", mirror::MethodType) \
+ M(kJavaLangInvokeVarHandle, "Ljava/lang/invoke/VarHandle;", mirror::VarHandle) \
+ M(kJavaLangInvokeFieldVarHandle, "Ljava/lang/invoke/FieldVarHandle;", mirror::FieldVarHandle) \
+ M(kJavaLangInvokeArrayElementVarHandle, "Ljava/lang/invoke/ArrayElementVarHandle;", mirror::ArrayElementVarHandle) \
+ M(kJavaLangInvokeByteArrayViewVarHandle, "Ljava/lang/invoke/ByteArrayViewVarHandle;", mirror::ByteArrayViewVarHandle) \
+ M(kJavaLangInvokeByteBufferViewVarHandle, "Ljava/lang/invoke/ByteBufferViewVarHandle;", mirror::ByteBufferViewVarHandle) \
+ M(kJavaLangClassLoader, "Ljava/lang/ClassLoader;", mirror::ClassLoader) \
+ M(kJavaLangThrowable, "Ljava/lang/Throwable;", mirror::Throwable) \
+ M(kJavaLangClassNotFoundException, "Ljava/lang/ClassNotFoundException;", detail::NoMirrorType<detail::ClassNotFoundExceptionTag>) \
+ M(kJavaLangStackTraceElement, "Ljava/lang/StackTraceElement;", mirror::StackTraceElement) \
+ M(kDalvikSystemEmulatedStackFrame, "Ldalvik/system/EmulatedStackFrame;", mirror::EmulatedStackFrame) \
+ M(kPrimitiveBoolean, "Z", detail::NoMirrorType<uint8_t>) \
+ M(kPrimitiveByte, "B", detail::NoMirrorType<int8_t>) \
+ M(kPrimitiveChar, "C", detail::NoMirrorType<uint16_t>) \
+ M(kPrimitiveDouble, "D", detail::NoMirrorType<double>) \
+ M(kPrimitiveFloat, "F", detail::NoMirrorType<float>) \
+ M(kPrimitiveInt, "I", detail::NoMirrorType<int32_t>) \
+ M(kPrimitiveLong, "J", detail::NoMirrorType<int64_t>) \
+ M(kPrimitiveShort, "S", detail::NoMirrorType<int16_t>) \
+ M(kPrimitiveVoid, "V", detail::NoMirrorType<void>) \
+ M(kBooleanArrayClass, "[Z", mirror::PrimitiveArray<uint8_t>) \
+ M(kByteArrayClass, "[B", mirror::PrimitiveArray<int8_t>) \
+ M(kCharArrayClass, "[C", mirror::PrimitiveArray<uint16_t>) \
+ M(kDoubleArrayClass, "[D", mirror::PrimitiveArray<double>) \
+ M(kFloatArrayClass, "[F", mirror::PrimitiveArray<float>) \
+ M(kIntArrayClass, "[I", mirror::PrimitiveArray<int32_t>) \
+ M(kLongArrayClass, "[J", mirror::PrimitiveArray<int64_t>) \
+ M(kShortArrayClass, "[S", mirror::PrimitiveArray<int16_t>) \
+ M(kJavaLangStackTraceElementArrayClass, "[Ljava/lang/StackTraceElement;", mirror::ObjectArray<mirror::StackTraceElement>) \
+ M(kDalvikSystemClassExt, "Ldalvik/system/ClassExt;", mirror::ClassExt)
+
+// Well known mirror::Class roots accessed via ClassLinker::GetClassRoots().
+enum class ClassRoot : uint32_t {
+#define CLASS_ROOT_ENUMERATOR(name, descriptor, mirror_type) name,
+ CLASS_ROOT_LIST(CLASS_ROOT_ENUMERATOR)
+#undef CLASS_ROOT_ENUMERATOR
+ kMax,
+};
+
+const char* GetClassRootDescriptor(ClassRoot class_root);
+
+template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+inline ObjPtr<mirror::Class> GetClassRoot(
+ ClassRoot class_root,
+ ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots) REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK(class_roots != nullptr);
+ if (kReadBarrierOption == kWithReadBarrier) {
+ // With read barrier all references must point to the to-space.
+ // Without read barrier, this check could fail.
+ DCHECK_EQ(class_roots, Runtime::Current()->GetClassLinker()->GetClassRoots());
+ }
+ DCHECK_LT(static_cast<uint32_t>(class_root), static_cast<uint32_t>(ClassRoot::kMax));
+ int32_t index = static_cast<int32_t>(class_root);
+ ObjPtr<mirror::Class> klass =
+ class_roots->GetWithoutChecks<kDefaultVerifyFlags, kReadBarrierOption>(index);
+ DCHECK(klass != nullptr);
+ return klass.Ptr();
+}
+
+template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+inline ObjPtr<mirror::Class> GetClassRoot(ClassRoot class_root, ClassLinker* linker)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return GetClassRoot<kReadBarrierOption>(class_root, linker->GetClassRoots<kReadBarrierOption>());
+}
+
+template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+inline ObjPtr<mirror::Class> GetClassRoot(ClassRoot class_root)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return GetClassRoot<kReadBarrierOption>(class_root, Runtime::Current()->GetClassLinker());
+}
+
+namespace detail {
+
+class ClassNotFoundExceptionTag;
+template <class Tag> struct NoMirrorType;
+
+template <class MirrorType>
+struct ClassRootSelector; // No definition for unspecialized ClassRoot selector.
+
+#define SPECIALIZE_CLASS_ROOT_SELECTOR(name, descriptor, mirror_type) \
+ template <> \
+ struct ClassRootSelector<mirror_type> { \
+ static constexpr ClassRoot value = ClassRoot::name; \
+ };
+
+CLASS_ROOT_LIST(SPECIALIZE_CLASS_ROOT_SELECTOR)
+
+#undef SPECIALIZE_CLASS_ROOT_SELECTOR
+
+} // namespace detail
+
+template <class MirrorType, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+inline ObjPtr<mirror::Class> GetClassRoot(ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return GetClassRoot<kWithReadBarrier>(detail::ClassRootSelector<MirrorType>::value, class_roots);
+}
+
+template <class MirrorType, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+inline ObjPtr<mirror::Class> GetClassRoot(ClassLinker* linker)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return GetClassRoot<kWithReadBarrier>(detail::ClassRootSelector<MirrorType>::value, linker);
+}
+
+template <class MirrorType, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+inline ObjPtr<mirror::Class> GetClassRoot() REQUIRES_SHARED(Locks::mutator_lock_) {
+ return GetClassRoot<kWithReadBarrier>(detail::ClassRootSelector<MirrorType>::value);
+}
+
+} // namespace art
+
+#endif // ART_RUNTIME_CLASS_ROOT_H_
diff --git a/runtime/entrypoints/quick/callee_save_frame.h b/runtime/entrypoints/quick/callee_save_frame.h
index 6f1bbaa..1e30907 100644
--- a/runtime/entrypoints/quick/callee_save_frame.h
+++ b/runtime/entrypoints/quick/callee_save_frame.h
@@ -68,7 +68,7 @@
bool exit_check_;
};
-namespace detail_ {
+namespace detail {
template <InstructionSet>
struct CSFSelector; // No definition for unspecialized callee save frame selector.
@@ -87,9 +87,9 @@
template <>
struct CSFSelector<InstructionSet::kX86_64> { using type = x86_64::X86_64CalleeSaveFrame; };
-} // namespace detail_
+} // namespace detail
-using RuntimeCalleeSaveFrame = detail_::CSFSelector<kRuntimeISA>::type;
+using RuntimeCalleeSaveFrame = detail::CSFSelector<kRuntimeISA>::type;
} // namespace art
diff --git a/runtime/gc/accounting/mod_union_table_test.cc b/runtime/gc/accounting/mod_union_table_test.cc
index e5b8ea5..d59ff71 100644
--- a/runtime/gc/accounting/mod_union_table_test.cc
+++ b/runtime/gc/accounting/mod_union_table_test.cc
@@ -17,6 +17,7 @@
#include "mod_union_table-inl.h"
#include "class_linker-inl.h"
+#include "class_root.h"
#include "common_runtime_test.h"
#include "gc/space/space-inl.h"
#include "mirror/array-inl.h"
@@ -70,8 +71,7 @@
mirror::Class* GetObjectArrayClass(Thread* self, space::ContinuousMemMapAllocSpace* space)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (java_lang_object_array_ == nullptr) {
- java_lang_object_array_ =
- Runtime::Current()->GetClassLinker()->GetClassRoot(ClassLinker::kObjectArrayClass);
+ java_lang_object_array_ = GetClassRoot<mirror::ObjectArray<mirror::Object>>().Ptr();
// Since the test doesn't have an image, the class of the object array keeps cards live
// inside the card cache mod-union table and causes the check
// ASSERT_FALSE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(obj3)));
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 0747c3c..2c2c437 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -23,6 +23,7 @@
#include "base/quasi_atomic.h"
#include "base/stl_util.h"
#include "base/systrace.h"
+#include "class_root.h"
#include "debugger.h"
#include "gc/accounting/atomic_stack.h"
#include "gc/accounting/heap_bitmap-inl.h"
@@ -2244,7 +2245,7 @@
// Avoid going through read barrier for since kDisallowReadBarrierDuringScan may be enabled.
// Explicitly mark to make sure to get an object in the to-space.
mirror::Class* int_array_class = down_cast<mirror::Class*>(
- Mark(mirror::IntArray::GetArrayClass<kWithoutReadBarrier>()));
+ Mark(GetClassRoot<mirror::IntArray, kWithoutReadBarrier>().Ptr()));
CHECK(int_array_class != nullptr);
if (ReadBarrier::kEnableToSpaceInvariantChecks) {
AssertToSpaceInvariant(nullptr, MemberOffset(0), int_array_class);
@@ -2324,7 +2325,7 @@
CHECK_GE(byte_size - alloc_size, min_object_size);
// FillWithDummyObject may mark an object, avoid holding skipped_blocks_lock_ to prevent lock
// violation and possible deadlock. The deadlock case is a recursive case:
- // FillWithDummyObject -> IntArray::GetArrayClass -> Mark -> Copy -> AllocateInSkippedBlock.
+ // FillWithDummyObject -> Mark(IntArray.class) -> Copy -> AllocateInSkippedBlock.
FillWithDummyObject(reinterpret_cast<mirror::Object*>(addr + alloc_size),
byte_size - alloc_size);
CHECK(region_space_->IsInToSpace(reinterpret_cast<mirror::Object*>(addr + alloc_size)));
diff --git a/runtime/gc/heap_verification_test.cc b/runtime/gc/heap_verification_test.cc
index 40ee86c..4f06ee6 100644
--- a/runtime/gc/heap_verification_test.cc
+++ b/runtime/gc/heap_verification_test.cc
@@ -18,6 +18,7 @@
#include "base/memory_tool.h"
#include "class_linker-inl.h"
+#include "class_root.h"
#include "handle_scope-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
@@ -36,10 +37,9 @@
template <class T>
mirror::ObjectArray<T>* AllocObjectArray(Thread* self, size_t length)
REQUIRES_SHARED(Locks::mutator_lock_) {
- ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
return mirror::ObjectArray<T>::Alloc(
self,
- class_linker->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass),
+ GetClassRoot<mirror::ObjectArray<mirror::Object>>(),
length);
}
};
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 3b64874..7bd5a6a 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -50,6 +50,7 @@
#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
+#include "class_root.h"
#include "common_throws.h"
#include "debugger.h"
#include "dex/dex_file-inl.h"
@@ -1418,8 +1419,7 @@
__ AddObjectId(obj);
__ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj));
__ AddU4(elements.size());
- __ AddClassId(LookupClassId(
- Runtime::Current()->GetClassLinker()->GetClassRoot(ClassLinker::kObjectArrayClass)));
+ __ AddClassId(LookupClassId(GetClassRoot<mirror::ObjectArray<mirror::Object>>().Ptr()));
for (mirror::Object* e : elements) {
__ AddObjectId(e);
}
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 860de2c..98fe8b2 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -23,6 +23,7 @@
#include "base/enums.h"
#include "base/memory_tool.h"
#include "class_linker.h"
+#include "class_root.h"
#include "common_runtime_test.h"
#include "dex/descriptors_names.h"
#include "dex/dex_instruction.h"
@@ -1370,7 +1371,7 @@
Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
mirror::ObjectArray<mirror::Object>::Alloc(
- self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1));
+ self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
ASSERT_TRUE(args != nullptr);
args->Set(0, input.Get());
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 3f4e841..ad6b37b 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -26,6 +26,7 @@
#include "class_ext.h"
#include "class_linker-inl.h"
#include "class_loader.h"
+#include "class_root.h"
#include "dex/descriptors_names.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_annotations.h"
@@ -75,26 +76,26 @@
ObjPtr<mirror::Class> Class::GetPrimitiveClass(ObjPtr<mirror::String> name) {
const char* expected_name = nullptr;
- ClassLinker::ClassRoot class_root = ClassLinker::kJavaLangObject; // Invalid.
+ ClassRoot class_root = ClassRoot::kJavaLangObject; // Invalid.
if (name != nullptr && name->GetLength() >= 2) {
// Perfect hash for the expected values: from the second letters of the primitive types,
// only 'y' has the bit 0x10 set, so use it to change 'b' to 'B'.
char hash = name->CharAt(0) ^ ((name->CharAt(1) & 0x10) << 1);
switch (hash) {
- case 'b': expected_name = "boolean"; class_root = ClassLinker::kPrimitiveBoolean; break;
- case 'B': expected_name = "byte"; class_root = ClassLinker::kPrimitiveByte; break;
- case 'c': expected_name = "char"; class_root = ClassLinker::kPrimitiveChar; break;
- case 'd': expected_name = "double"; class_root = ClassLinker::kPrimitiveDouble; break;
- case 'f': expected_name = "float"; class_root = ClassLinker::kPrimitiveFloat; break;
- case 'i': expected_name = "int"; class_root = ClassLinker::kPrimitiveInt; break;
- case 'l': expected_name = "long"; class_root = ClassLinker::kPrimitiveLong; break;
- case 's': expected_name = "short"; class_root = ClassLinker::kPrimitiveShort; break;
- case 'v': expected_name = "void"; class_root = ClassLinker::kPrimitiveVoid; break;
+ case 'b': expected_name = "boolean"; class_root = ClassRoot::kPrimitiveBoolean; break;
+ case 'B': expected_name = "byte"; class_root = ClassRoot::kPrimitiveByte; break;
+ case 'c': expected_name = "char"; class_root = ClassRoot::kPrimitiveChar; break;
+ case 'd': expected_name = "double"; class_root = ClassRoot::kPrimitiveDouble; break;
+ case 'f': expected_name = "float"; class_root = ClassRoot::kPrimitiveFloat; break;
+ case 'i': expected_name = "int"; class_root = ClassRoot::kPrimitiveInt; break;
+ case 'l': expected_name = "long"; class_root = ClassRoot::kPrimitiveLong; break;
+ case 's': expected_name = "short"; class_root = ClassRoot::kPrimitiveShort; break;
+ case 'v': expected_name = "void"; class_root = ClassRoot::kPrimitiveVoid; break;
default: break;
}
}
if (expected_name != nullptr && name->Equals(expected_name)) {
- ObjPtr<mirror::Class> klass = Runtime::Current()->GetClassLinker()->GetClassRoot(class_root);
+ ObjPtr<mirror::Class> klass = GetClassRoot(class_root);
DCHECK(klass != nullptr);
return klass;
} else {
diff --git a/runtime/mirror/emulated_stack_frame.cc b/runtime/mirror/emulated_stack_frame.cc
index 5f00c6e..527408b 100644
--- a/runtime/mirror/emulated_stack_frame.cc
+++ b/runtime/mirror/emulated_stack_frame.cc
@@ -17,6 +17,7 @@
#include "emulated_stack_frame.h"
#include "class-inl.h"
+#include "class_root.h"
#include "gc_root-inl.h"
#include "jvalue-inl.h"
#include "method_handles-inl.h"
@@ -166,8 +167,7 @@
CalculateFrameAndReferencesSize(to_types.Get(), r_type.Get(), &frame_size, &refs_size);
// Step 3 : Allocate the arrays.
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ObjPtr<mirror::Class> array_class(class_linker->GetClassRoot(ClassLinker::kObjectArrayClass));
+ ObjPtr<mirror::Class> array_class(GetClassRoot<mirror::ObjectArray<mirror::Object>>());
Handle<mirror::ObjectArray<mirror::Object>> references(hs.NewHandle(
mirror::ObjectArray<mirror::Object>::Alloc(self, array_class, refs_size)));
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 69ba4b9..8b7a1b6 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -28,6 +28,7 @@
#include "class-inl.h"
#include "class_linker-inl.h"
#include "class_linker.h"
+#include "class_root.h"
#include "common_runtime_test.h"
#include "dex/dex_file.h"
#include "entrypoints/entrypoint_utils-inl.h"
@@ -78,7 +79,7 @@
mirror::ObjectArray<T>* AllocObjectArray(Thread* self, size_t length)
REQUIRES_SHARED(Locks::mutator_lock_) {
return mirror::ObjectArray<T>::Alloc(
- self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), length);
+ self, GetClassRoot(ClassRoot::kObjectArrayClass, class_linker_), length);
}
};
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 5a80929..129bae6 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -47,6 +47,7 @@
#include "base/to_str.h"
#include "base/utils.h"
#include "class_linker-inl.h"
+#include "class_root.h"
#include "debugger.h"
#include "dex/descriptors_names.h"
#include "dex/dex_file-inl.h"
@@ -2510,7 +2511,8 @@
// class of the ArtMethod pointers.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
StackHandleScope<1> hs(self_);
- ObjPtr<mirror::Class> array_class = class_linker->GetClassRoot(ClassLinker::kObjectArrayClass);
+ ObjPtr<mirror::Class> array_class =
+ GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker);
// The first element is the methods and dex pc array, the other elements are declaring classes
// for the methods to ensure classes in the stack trace don't get unloaded.
Handle<mirror::ObjectArray<mirror::Object>> trace(