Remove mirror::String::java_lang_String_.
And simplify ClassLinker::InitWithoutImage().
And finish ObjPtr<>-ification of annotation processing.
Test: m test-art-host-gtest
Test: testrunner.py --host
Bug: 31113334
Change-Id: I882a6c2f2b2a88d6ba34e4759bac4a6caa54cafa
diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc
index 1697092..9bea18a 100644
--- a/openjdkjvmti/ti_class.cc
+++ b/openjdkjvmti/ti_class.cc
@@ -715,7 +715,7 @@
if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) {
art::StackHandleScope<1> hs(soa.Self());
art::Handle<art::mirror::Class> h_klass = hs.NewHandle(klass);
- art::mirror::ObjectArray<art::mirror::String>* str_array =
+ art::ObjPtr<art::mirror::ObjectArray<art::mirror::String>> str_array =
art::annotations::GetSignatureAnnotationForClass(h_klass);
if (str_array != nullptr) {
std::ostringstream oss;
diff --git a/openjdkjvmti/ti_field.cc b/openjdkjvmti/ti_field.cc
index 328e2a1..2a860d9 100644
--- a/openjdkjvmti/ti_field.cc
+++ b/openjdkjvmti/ti_field.cc
@@ -91,7 +91,7 @@
if (generic_ptr != nullptr) {
*generic_ptr = nullptr;
if (!art_field->GetDeclaringClass()->IsProxyClass()) {
- art::mirror::ObjectArray<art::mirror::String>* str_array =
+ art::ObjPtr<art::mirror::ObjectArray<art::mirror::String>> str_array =
art::annotations::GetSignatureAnnotationForField(art_field);
if (str_array != nullptr) {
std::ostringstream oss;
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index c0c312c..d0b7224f 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -345,7 +345,7 @@
if (generic_ptr != nullptr) {
*generic_ptr = nullptr;
if (!art_method->GetDeclaringClass()->IsProxyClass()) {
- art::mirror::ObjectArray<art::mirror::String>* str_array =
+ art::ObjPtr<art::mirror::ObjectArray<art::mirror::String>> str_array =
art::annotations::GetSignatureAnnotationForMethod(art_method);
if (str_array != nullptr) {
std::ostringstream oss;
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index 78516e3..b0c0e43 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -21,6 +21,7 @@
#include "base/callee_save_type.h"
#include "base/enums.h"
#include "class_linker-inl.h"
+#include "class_root.h"
#include "common_runtime_test.h"
#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "imt_conflict_table.h"
@@ -2096,7 +2097,7 @@
EXPECT_FALSE(self->IsExceptionPending());
- GcRoot<mirror::Class>& root = mirror::String::java_lang_String_;
+ GcRoot<mirror::Class> root(GetClassRoot<mirror::String>());
size_t result = Invoke3(reinterpret_cast<size_t>(&root), 0U, 0U, readBarrierForRootSlow, self);
EXPECT_FALSE(self->IsExceptionPending());
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b882f65..0952723 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -484,27 +484,10 @@
mirror::ObjectArray<mirror::Object>::ClassSize(image_pointer_size_))));
object_array_class->SetComponentType(java_lang_Object.Get());
- // Setup the char (primitive) class to be used for char[].
- Handle<mirror::Class> char_class(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(),
- mirror::Class::PrimitiveClassSize(image_pointer_size_))));
- // The primitive char class won't be initialized by
- // InitializePrimitiveClass until line 459, but strings (and
- // internal char arrays) will be allocated before that and the
- // component size, which is computed from the primitive type, needs
- // to be set here.
- char_class->SetPrimitiveType(Primitive::kPrimChar);
-
- // Setup the char[] class to be used for String.
- Handle<mirror::Class> char_array_class(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize(image_pointer_size_))));
- char_array_class->SetComponentType(char_class.Get());
-
// Setup String.
Handle<mirror::Class> java_lang_String(hs.NewHandle(
AllocClass(self, java_lang_Class.Get(), mirror::String::ClassSize(image_pointer_size_))));
java_lang_String->SetStringClass();
- mirror::String::SetClass(java_lang_String.Get());
mirror::Class::SetStatus(java_lang_String, ClassStatus::kResolved, self);
// Setup java.lang.ref.Reference.
@@ -523,7 +506,6 @@
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());
@@ -533,6 +515,7 @@
// Setup the primitive type classes.
SetClassRoot(ClassRoot::kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
SetClassRoot(ClassRoot::kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
+ SetClassRoot(ClassRoot::kPrimitiveChar, CreatePrimitiveClass(self, Primitive::kPrimChar));
SetClassRoot(ClassRoot::kPrimitiveShort, CreatePrimitiveClass(self, Primitive::kPrimShort));
SetClassRoot(ClassRoot::kPrimitiveInt, CreatePrimitiveClass(self, Primitive::kPrimInt));
SetClassRoot(ClassRoot::kPrimitiveLong, CreatePrimitiveClass(self, Primitive::kPrimLong));
@@ -543,13 +526,13 @@
// 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 AllocDexCache (done in AppendToBootClassPath).
+ // 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_))));
int_array_class->SetComponentType(GetClassRoot(ClassRoot::kPrimitiveInt, this));
SetClassRoot(ClassRoot::kIntArrayClass, int_array_class.Get());
- // Create long array type for AllocDexCache (done in AppendToBootClassPath).
+ // Create long array type for native pointer arrays (for example vtables) on 64-bit archs.
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(ClassRoot::kPrimitiveLong, this));
@@ -604,10 +587,6 @@
// now we can use FindSystemClass
- // run char class through InitializePrimitiveClass to finish init
- InitializePrimitiveClass(char_class.Get(), Primitive::kPrimChar);
- 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.
quick_generic_jni_trampoline_ = GetQuickGenericJniStub();
@@ -636,7 +615,7 @@
SetClassRoot(ClassRoot::kByteArrayClass, FindSystemClass(self, "[B"));
- CheckSystemClass(self, char_array_class, "[C");
+ SetClassRoot(ClassRoot::kCharArrayClass, FindSystemClass(self, "[C"));
SetClassRoot(ClassRoot::kShortArrayClass, FindSystemClass(self, "[S"));
@@ -685,7 +664,7 @@
FindSystemClass(self, "Ljava/lang/reflect/Proxy;"));
// Create java.lang.reflect.Field.class root.
- auto* class_root = FindSystemClass(self, "Ljava/lang/reflect/Field;");
+ ObjPtr<mirror::Class> class_root = FindSystemClass(self, "Ljava/lang/reflect/Field;");
CHECK(class_root != nullptr);
SetClassRoot(ClassRoot::kJavaLangReflectField, class_root);
@@ -1014,10 +993,6 @@
spaces[0]->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)));
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<mirror::String>(this));
-
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
@@ -2109,7 +2084,6 @@
ClassLinker::~ClassLinker() {
mirror::Class::ResetClass();
- mirror::String::ResetClass();
Thread* const self = Thread::Current();
for (const ClassLoaderData& data : class_loaders_) {
// CHA unloading analysis is not needed. No negative consequences are expected because
@@ -3561,20 +3535,13 @@
}
mirror::Class* ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type type) {
- ObjPtr<mirror::Class> klass =
+ ObjPtr<mirror::Class> primitive_class =
AllocClass(self, mirror::Class::PrimitiveClassSize(image_pointer_size_));
- if (UNLIKELY(klass == nullptr)) {
+ if (UNLIKELY(primitive_class == nullptr)) {
self->AssertPendingOOMException();
return nullptr;
}
- return InitializePrimitiveClass(klass, type);
-}
-
-mirror::Class* ClassLinker::InitializePrimitiveClass(ObjPtr<mirror::Class> primitive_class,
- Primitive::Type type) {
- CHECK(primitive_class != nullptr);
// Must hold lock on object when initializing.
- Thread* self = Thread::Current();
StackHandleScope<1> hs(self);
Handle<mirror::Class> h_class(hs.NewHandle(primitive_class));
ObjectLock<mirror::Class> lock(self, h_class);
@@ -3668,8 +3635,6 @@
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<mirror::CharArray>(this));
} else if (strcmp(descriptor, "[I") == 0) {
new_class.Assign(GetClassRoot<mirror::IntArray>(this));
} else if (strcmp(descriptor, "[J") == 0) {
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index afe5c99..1f94c43 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -793,10 +793,6 @@
mirror::Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
- mirror::Class* InitializePrimitiveClass(ObjPtr<mirror::Class> primitive_class,
- Primitive::Type type)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!Roles::uninterruptible_);
mirror::Class* CreateArrayClass(Thread* self,
const char* descriptor,
diff --git a/runtime/dex/dex_file_annotations.cc b/runtime/dex/dex_file_annotations.cc
index ffa0a90..5cb08dc 100644
--- a/runtime/dex/dex_file_annotations.cc
+++ b/runtime/dex/dex_file_annotations.cc
@@ -849,7 +849,8 @@
return annotation_value.value_.GetL();
}
-mirror::ObjectArray<mirror::String>* GetSignatureValue(const ClassData& klass,
+static ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureValue(
+ const ClassData& klass,
const DexFile::AnnotationSetItem* annotation_set)
REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile& dex_file = klass.GetDexFile();
@@ -860,12 +861,9 @@
if (annotation_item == nullptr) {
return nullptr;
}
- ObjPtr<mirror::Class> string_class = mirror::String::GetJavaLangString();
- Handle<mirror::Class> string_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &string_class)));
- if (string_array_class == nullptr) {
- return nullptr;
- }
+ Handle<mirror::Class> string_array_class =
+ hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::String>>());
+ DCHECK(string_array_class != nullptr);
ObjPtr<mirror::Object> obj =
GetAnnotationValue(klass, annotation_item, "value", string_array_class,
DexFile::kDexAnnotationArray);
@@ -880,19 +878,16 @@
const DexFile::AnnotationSetItem* annotation_set)
REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile& dex_file = klass.GetDexFile();
- StackHandleScope<1> hs(Thread::Current());
const DexFile::AnnotationItem* annotation_item =
SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Throws;",
DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return nullptr;
}
- ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
- Handle<mirror::Class> class_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &class_class)));
- if (class_array_class == nullptr) {
- return nullptr;
- }
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> class_array_class =
+ hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::Class>>());
+ DCHECK(class_array_class != nullptr);
ObjPtr<mirror::Object> obj =
GetAnnotationValue(klass, annotation_item, "value", class_array_class,
DexFile::kDexAnnotationArray);
@@ -1020,7 +1015,7 @@
return ProcessAnnotationSet(field_class, annotation_set, DexFile::kDexVisibilityRuntime);
}
-mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForField(ArtField* field) {
+ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForField(ArtField* field) {
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
if (annotation_set == nullptr) {
return nullptr;
@@ -1171,9 +1166,10 @@
annotation_class);
}
-bool GetParametersMetadataForMethod(ArtMethod* method,
- MutableHandle<mirror::ObjectArray<mirror::String>>* names,
- MutableHandle<mirror::IntArray>* access_flags) {
+bool GetParametersMetadataForMethod(
+ ArtMethod* method,
+ /*out*/ MutableHandle<mirror::ObjectArray<mirror::String>>* names,
+ /*out*/ MutableHandle<mirror::IntArray>* access_flags) {
const DexFile::AnnotationSetItem* annotation_set =
FindAnnotationSetForMethod(method);
if (annotation_set == nullptr) {
@@ -1193,12 +1189,10 @@
StackHandleScope<4> hs(Thread::Current());
// Extract the parameters' names String[].
- ObjPtr<mirror::Class> string_class = mirror::String::GetJavaLangString();
- Handle<mirror::Class> string_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &string_class)));
- if (UNLIKELY(string_array_class == nullptr)) {
- return false;
- }
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Handle<mirror::Class> string_array_class =
+ hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::String>>(class_linker));
+ DCHECK(string_array_class != nullptr);
ClassData data(method);
Handle<mirror::Object> names_obj =
@@ -1212,10 +1206,8 @@
}
// Extract the parameters' access flags int[].
- Handle<mirror::Class> int_array_class(hs.NewHandle(GetClassRoot<mirror::IntArray>()));
- if (UNLIKELY(int_array_class == nullptr)) {
- return false;
- }
+ Handle<mirror::Class> int_array_class(hs.NewHandle(GetClassRoot<mirror::IntArray>(class_linker)));
+ DCHECK(int_array_class != nullptr);
Handle<mirror::Object> access_flags_obj =
hs.NewHandle(GetAnnotationValue(data,
annotation_item,
@@ -1226,12 +1218,12 @@
return false;
}
- names->Assign(names_obj.Get()->AsObjectArray<mirror::String>());
- access_flags->Assign(access_flags_obj.Get()->AsIntArray());
+ names->Assign(names_obj->AsObjectArray<mirror::String>());
+ access_flags->Assign(access_flags_obj->AsIntArray());
return true;
}
-mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForMethod(ArtMethod* method) {
+ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForMethod(ArtMethod* method) {
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
if (annotation_set == nullptr) {
return nullptr;
@@ -1345,12 +1337,9 @@
return nullptr;
}
StackHandleScope<1> hs(Thread::Current());
- ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
- Handle<mirror::Class> class_array_class(hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindArrayClass(hs.Self(), &class_class)));
- if (class_array_class == nullptr) {
- return nullptr;
- }
+ Handle<mirror::Class> class_array_class =
+ hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::Class>>());
+ DCHECK(class_array_class != nullptr);
ObjPtr<mirror::Object> obj =
GetAnnotationValue(data, annotation_item, "value", class_array_class,
DexFile::kDexAnnotationArray);
@@ -1446,7 +1435,7 @@
DexFile::kDexAnnotationMethod);
}
-bool GetInnerClass(Handle<mirror::Class> klass, ObjPtr<mirror::String>* name) {
+bool GetInnerClass(Handle<mirror::Class> klass, /*out*/ ObjPtr<mirror::String>* name) {
ClassData data(klass);
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
if (annotation_set == nullptr) {
@@ -1513,7 +1502,8 @@
return true;
}
-mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass) {
+ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForClass(
+ Handle<mirror::Class> klass) {
ClassData data(klass);
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
if (annotation_set == nullptr) {
diff --git a/runtime/dex/dex_file_annotations.h b/runtime/dex/dex_file_annotations.h
index 9645a7f..bde7891 100644
--- a/runtime/dex/dex_file_annotations.h
+++ b/runtime/dex/dex_file_annotations.h
@@ -41,7 +41,7 @@
REQUIRES_SHARED(Locks::mutator_lock_);
ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForField(ArtField* field)
REQUIRES_SHARED(Locks::mutator_lock_);
-mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForField(ArtField* field)
+ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForField(ArtField* field)
REQUIRES_SHARED(Locks::mutator_lock_);
bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -64,11 +64,11 @@
uint32_t parameter_idx,
Handle<mirror::Class> annotation_class)
REQUIRES_SHARED(Locks::mutator_lock_);
-bool GetParametersMetadataForMethod(ArtMethod* method,
- MutableHandle<mirror::ObjectArray<mirror::String>>* names,
- MutableHandle<mirror::IntArray>* access_flags)
- REQUIRES_SHARED(Locks::mutator_lock_);
-mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForMethod(ArtMethod* method)
+bool GetParametersMetadataForMethod(
+ ArtMethod* method,
+ /*out*/ MutableHandle<mirror::ObjectArray<mirror::String>>* names,
+ /*out*/ MutableHandle<mirror::IntArray>* access_flags) REQUIRES_SHARED(Locks::mutator_lock_);
+ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForMethod(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_);
// Check whether `method` is annotated with `annotation_class`.
// If `lookup_in_resolved_boot_classes` is true, look up any of the
@@ -101,12 +101,12 @@
REQUIRES_SHARED(Locks::mutator_lock_);
ObjPtr<mirror::Object> GetEnclosingMethod(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
-bool GetInnerClass(Handle<mirror::Class> klass, ObjPtr<mirror::String>* name)
+bool GetInnerClass(Handle<mirror::Class> klass, /*out*/ ObjPtr<mirror::String>* name)
REQUIRES_SHARED(Locks::mutator_lock_);
bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags)
REQUIRES_SHARED(Locks::mutator_lock_);
-mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForClass(
+ Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
const char* GetSourceDebugExtension(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
bool IsClassAnnotationPresent(Handle<mirror::Class> klass,
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 37234e1..0ee780d 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -35,6 +35,7 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "class_linker-inl.h"
+#include "class_root.h"
#include "common_dex_operations.h"
#include "common_throws.h"
#include "dex/dex_file-inl.h"
@@ -328,7 +329,7 @@
ShadowFrame& shadow_frame,
dex::StringIndex string_idx)
REQUIRES_SHARED(Locks::mutator_lock_) {
- ObjPtr<mirror::Class> java_lang_string_class = mirror::String::GetJavaLangString();
+ ObjPtr<mirror::Class> java_lang_string_class = GetClassRoot<mirror::String>();
if (UNLIKELY(!java_lang_string_class->IsInitialized())) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
StackHandleScope<1> hs(self);
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 9bb760c..88cfafb 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -388,7 +388,7 @@
TEST_F(UnstartedRuntimeTest, StringInit) {
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
- ObjPtr<mirror::Class> klass = mirror::String::GetJavaLangString();
+ ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
ArtMethod* method =
klass->FindConstructor("(Ljava/lang/String;)V",
Runtime::Current()->GetClassLinker()->GetImagePointerSize());
@@ -537,7 +537,7 @@
tmp,
false,
object_class.Get(),
- mirror::String::GetJavaLangString(),
+ GetClassRoot<mirror::String>(),
hs_src,
1,
hs_dst,
@@ -551,7 +551,7 @@
{
StackHandleScope<3> hs_src(self);
hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
- hs_src.NewHandle(mirror::String::GetJavaLangString());
+ hs_src.NewHandle(GetClassRoot<mirror::String>());
hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
StackHandleScope<3> hs_dst(self);
@@ -568,7 +568,7 @@
tmp,
true,
object_class.Get(),
- mirror::String::GetJavaLangString(),
+ GetClassRoot<mirror::String>(),
hs_src,
0,
hs_dst,
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index e6bfe55..cb2708d 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -1461,12 +1461,12 @@
// circularity issue during loading the names of its members
DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
- this == String::GetJavaLangString())
+ this == GetClassRoot<String>())
<< "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
<< " IsRetired=" << IsRetired<kVerifyFlags>()
<< " IsErroneous=" <<
IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
- << " IsString=" << (this == String::GetJavaLangString())
+ << " IsString=" << (this == GetClassRoot<String>())
<< " status= " << GetStatus<kVerifyFlags>()
<< " descriptor=" << PrettyDescriptor();
}
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index e6079c0..8fa2c6c 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -25,6 +25,7 @@
#include "base/globals.h"
#include "base/utils.h"
#include "class.h"
+#include "class_root.h"
#include "common_throws.h"
#include "dex/utf.h"
#include "gc/heap-inl.h"
@@ -211,7 +212,8 @@
// http://b/23528461
size_t alloc_size = RoundUp(size, kObjectAlignment);
- Class* string_class = GetJavaLangString();
+ Runtime* runtime = Runtime::Current();
+ ObjPtr<Class> string_class = GetClassRoot<String>(runtime->GetClassLinker());
// Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
// Do this by comparing with the maximum length that will _not_ cause an overflow.
const size_t overflow_length = (-header_size) / block_size; // Unsigned arithmetic.
@@ -227,7 +229,7 @@
return nullptr;
}
- gc::Heap* heap = Runtime::Current()->GetHeap();
+ gc::Heap* heap = runtime->GetHeap();
return down_cast<String*>(
heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, string_class, alloc_size,
allocator_type, pre_fence_visitor));
diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc
index 6208a96..b76ca19 100644
--- a/runtime/mirror/string.cc
+++ b/runtime/mirror/string.cc
@@ -35,9 +35,6 @@
namespace art {
namespace mirror {
-// TODO: get global references for these
-GcRoot<Class> String::java_lang_String_;
-
int32_t String::FastIndexOf(int32_t ch, int32_t start) {
int32_t count = GetLength();
if (start < 0) {
@@ -52,18 +49,6 @@
}
}
-void String::SetClass(ObjPtr<Class> java_lang_String) {
- CHECK(java_lang_String_.IsNull());
- CHECK(java_lang_String != nullptr);
- CHECK(java_lang_String->IsStringClass());
- java_lang_String_ = GcRoot<Class>(java_lang_String);
-}
-
-void String::ResetClass() {
- CHECK(!java_lang_String_.IsNull());
- java_lang_String_ = GcRoot<Class>(nullptr);
-}
-
int String::ComputeHashCode() {
int32_t hash_code = 0;
if (IsCompressed()) {
@@ -372,10 +357,6 @@
return count_diff;
}
-void String::VisitRoots(RootVisitor* visitor) {
- java_lang_String_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
CharArray* String::ToCharArray(Thread* self) {
StackHandleScope<1> hs(self);
Handle<String> string(hs.NewHandle(this));
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 270ace1..598175b 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -228,15 +228,6 @@
: length;
}
- static Class* GetJavaLangString() REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(!java_lang_String_.IsNull());
- return java_lang_String_.Read();
- }
-
- static void SetClass(ObjPtr<Class> java_lang_String) REQUIRES_SHARED(Locks::mutator_lock_);
- static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
- static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
-
// Returns a human-readable equivalent of 'descriptor'. So "I" would be "int",
// "[[I" would be "int[][]", "[Ljava/lang/String;" would be
// "java.lang.String[]", and so forth.
@@ -281,10 +272,7 @@
uint8_t value_compressed_[0];
};
- static GcRoot<Class> java_lang_String_;
-
friend struct art::StringOffsets; // for verifying offset information
- ART_FRIEND_TEST(art::StubTest, ReadBarrierForRoot); // For java_lang_String_.
DISALLOW_IMPLICIT_CONSTRUCTORS(String);
};
diff --git a/runtime/mirror/var_handle_test.cc b/runtime/mirror/var_handle_test.cc
index 2c12832..cb2d628 100644
--- a/runtime/mirror/var_handle_test.cc
+++ b/runtime/mirror/var_handle_test.cc
@@ -92,8 +92,7 @@
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Handle<Class> var_type = hs.NewHandle(view_array_class->GetComponentType());
Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
- ObjPtr<mirror::Class> byte_class = class_linker->FindPrimitiveClass('B');
- Handle<Class> byte_array_class(hs.NewHandle(class_linker->FindArrayClass(self, &byte_class)));
+ Handle<Class> byte_array_class(hs.NewHandle(GetClassRoot<mirror::ByteArray>()));
InitializeVarHandle(bvh.Get(), var_type, byte_array_class, index_type, access_modes_bit_mask);
bvh->SetFieldBoolean<false>(ByteArrayViewVarHandle::NativeByteOrderOffset(), native_byte_order);
return bvh.Get();
@@ -234,8 +233,7 @@
ScopedObjectAccess soa(self);
StackHandleScope<3> hs(self);
int ptypes_count = static_cast<int>(descriptors.size()) - 1;
- ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass();
- ObjPtr<mirror::Class> array_of_class = class_linker->FindArrayClass(self, &class_type);
+ ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
Handle<ObjectArray<Class>> ptypes = hs.NewHandle(
ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, ptypes_count));
Handle<mirror::ClassLoader> boot_class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
@@ -599,10 +597,10 @@
VarHandle::AccessMode::kGetAndBitwiseXorRelease,
VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
- ObjPtr<mirror::Class> string_class = mirror::String::GetJavaLangString();
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Handle<Class> string_array_class(hs.NewHandle(class_linker->FindArrayClass(self, &string_class)));
- Handle<mirror::ArrayElementVarHandle> vh(hs.NewHandle(CreateArrayElementVarHandle(self, string_array_class, mask)));
+ Handle<mirror::Class> string_array_class = hs.NewHandle(
+ GetClassRoot<mirror::ObjectArray<mirror::String>>());
+ Handle<mirror::ArrayElementVarHandle> vh(
+ hs.NewHandle(CreateArrayElementVarHandle(self, string_array_class, mask)));
EXPECT_FALSE(vh.IsNull());
// Check access modes
@@ -746,11 +744,10 @@
VarHandle::AccessMode::kGetAndBitwiseXor,
VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ObjPtr<mirror::Class> char_class = class_linker->FindPrimitiveClass('C');
- Handle<Class> char_array_class(hs.NewHandle(class_linker->FindArrayClass(self, &char_class)));
+ Handle<Class> char_array_class(hs.NewHandle(GetClassRoot<mirror::CharArray>()));
const bool native_byte_order = true;
- Handle<mirror::ByteArrayViewVarHandle> vh(hs.NewHandle(CreateByteArrayViewVarHandle(self, char_array_class, native_byte_order, mask)));
+ Handle<mirror::ByteArrayViewVarHandle> vh(
+ hs.NewHandle(CreateByteArrayViewVarHandle(self, char_array_class, native_byte_order, mask)));
EXPECT_FALSE(vh.IsNull());
EXPECT_EQ(native_byte_order, vh->GetNativeByteOrder());
@@ -895,11 +892,10 @@
VarHandle::AccessMode::kGetAndBitwiseXor,
VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ObjPtr<mirror::Class> double_class = class_linker->FindPrimitiveClass('D');
- Handle<Class> double_array_class(hs.NewHandle(class_linker->FindArrayClass(self, &double_class)));
+ Handle<Class> double_array_class(hs.NewHandle(GetClassRoot<mirror::DoubleArray>()));
const bool native_byte_order = false;
- Handle<mirror::ByteBufferViewVarHandle> vh(hs.NewHandle(CreateByteBufferViewVarHandle(self, double_array_class, native_byte_order, mask)));
+ Handle<mirror::ByteBufferViewVarHandle> vh(hs.NewHandle(
+ CreateByteBufferViewVarHandle(self, double_array_class, native_byte_order, mask)));
EXPECT_FALSE(vh.IsNull());
EXPECT_EQ(native_byte_order, vh->GetNativeByteOrder());
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 32d9d68..6384d01 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1979,7 +1979,6 @@
// 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::String::VisitRoots(visitor);
mirror::ClassExt::VisitRoots(visitor);
// Visiting the roots of these ArtMethods is not currently required since all the GcRoots are
// null.
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index cbfbb40..73e516c 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -723,6 +723,7 @@
// mechanics to continue.
return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
} else { // Two reference types, compute Join
+ // Do not cache the classes as ClassJoin() can suspend and invalidate ObjPtr<>s.
DCHECK(GetClass() != nullptr && !GetClass()->IsPrimitive());
DCHECK(incoming_type.GetClass() != nullptr && !incoming_type.GetClass()->IsPrimitive());
ObjPtr<mirror::Class> join_class = ClassJoin(GetClass(), incoming_type.GetClass());