summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-02-25 02:51:02 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-02-25 02:51:02 +0000
commita0c9b085d4ecf90ca3aa1252e81e65072b377ca4 (patch)
tree01b9b556f274c900bee79cfb8846bc9b854118e1 /runtime
parent35312f46b1d71ad7f092dbdbc913c0846835386e (diff)
parent9837939678bb5dcba178e5fb00ed59b5d14c8d9b (diff)
downloadart-a0c9b085d4ecf90ca3aa1252e81e65072b377ca4.zip
art-a0c9b085d4ecf90ca3aa1252e81e65072b377ca4.tar.gz
art-a0c9b085d4ecf90ca3aa1252e81e65072b377ca4.tar.bz2
Merge "Avoid std::string allocations for finding an array class."
Diffstat (limited to 'runtime')
-rw-r--r--runtime/class_linker-inl.h30
-rw-r--r--runtime/class_linker.cc146
-rw-r--r--runtime/class_linker.h26
-rw-r--r--runtime/class_linker_test.cc96
-rw-r--r--runtime/common_test.h16
-rw-r--r--runtime/debugger.cc97
-rw-r--r--runtime/entrypoints/entrypoint_utils.h2
-rw-r--r--runtime/exception_test.cc2
-rw-r--r--runtime/gc/heap_test.cc3
-rw-r--r--runtime/gc/space/space_test.h5
-rw-r--r--runtime/indirect_reference_table_test.cc2
-rw-r--r--runtime/interpreter/interpreter_common.cc4
-rw-r--r--runtime/jni_internal.cc15
-rw-r--r--runtime/jni_internal_test.cc5
-rw-r--r--runtime/mirror/array.cc17
-rw-r--r--runtime/mirror/class.cc5
-rw-r--r--runtime/mirror/object_test.cc82
-rw-r--r--runtime/native/dalvik_system_VMRuntime.cc26
-rw-r--r--runtime/native/java_lang_Class.cc6
-rw-r--r--runtime/native/java_lang_reflect_Array.cc8
-rw-r--r--runtime/object_utils.h8
-rw-r--r--runtime/scoped_thread_state_change.h5
-rw-r--r--runtime/thread.cc2
-rw-r--r--runtime/transaction_test.cc60
-rw-r--r--runtime/utils_test.cc11
-rw-r--r--runtime/verifier/method_verifier.cc11
-rw-r--r--runtime/verifier/method_verifier_test.cc2
-rw-r--r--runtime/verifier/reg_type.cc7
-rw-r--r--runtime/verifier/reg_type_cache.cc9
29 files changed, 403 insertions, 305 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 66c24b5..6ef0082 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -23,10 +23,40 @@
#include "mirror/dex_cache.h"
#include "mirror/iftable.h"
#include "mirror/object_array.h"
+#include "object_utils.h"
#include "sirt_ref.h"
namespace art {
+inline bool ClassLinker::IsInBootClassPath(const char* descriptor) {
+ DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_);
+ return pair.second != nullptr;
+}
+
+inline mirror::Class* ClassLinker::FindSystemClass(Thread* self, const char* descriptor) {
+ SirtRef<mirror::ClassLoader> class_loader(self, nullptr);
+ return FindClass(self, descriptor, class_loader);
+}
+
+inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, mirror::Class* element_class) {
+ for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
+ // Read the cached the array class once to avoid races with other threads setting it.
+ mirror::Class* array_class = find_array_class_cache_[i];
+ if (array_class != nullptr && array_class->GetComponentType() == element_class) {
+ return array_class;
+ }
+ }
+ std::string descriptor("[");
+ descriptor += ClassHelper(element_class).GetDescriptor();
+ SirtRef<mirror::ClassLoader> class_loader(self, element_class->GetClassLoader());
+ mirror::Class* array_class = FindClass(self, descriptor.c_str(), class_loader);
+ // Benign races in storing array class and incrementing index.
+ size_t victim_index = find_array_class_cache_next_victim_;
+ find_array_class_cache_[victim_index] = array_class;
+ find_array_class_cache_next_victim_ = (victim_index + 1) % kFindArrayCacheSize;
+ return array_class;
+}
+
inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx,
mirror::ArtMethod* referrer) {
mirror::String* resolved_string = referrer->GetDexCacheStrings()->Get(string_idx);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 48ec5ab..a165a68 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -176,17 +176,19 @@ ClassLinker::ClassLinker(InternTable* intern_table)
: dex_lock_("ClassLinker dex lock", kDefaultMutexLevel),
dex_cache_image_class_lookup_required_(false),
failed_dex_cache_class_lookups_(0),
- class_roots_(NULL),
- array_iftable_(NULL),
+ class_roots_(nullptr),
+ array_iftable_(nullptr),
+ find_array_class_cache_next_victim_(0),
init_done_(false),
dex_caches_dirty_(false),
class_table_dirty_(false),
intern_table_(intern_table),
- portable_resolution_trampoline_(NULL),
- quick_resolution_trampoline_(NULL),
- portable_imt_conflict_trampoline_(NULL),
- quick_imt_conflict_trampoline_(NULL) {
+ portable_resolution_trampoline_(nullptr),
+ quick_resolution_trampoline_(nullptr),
+ portable_imt_conflict_trampoline_(nullptr),
+ quick_imt_conflict_trampoline_(nullptr) {
CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax));
+ memset(find_array_class_cache_, 0, kFindArrayCacheSize * sizeof(mirror::Class*));
}
void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class_path) {
@@ -335,54 +337,54 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class
// Object, String and DexCache need to be rerun through FindSystemClass to finish init
java_lang_Object->SetStatus(mirror::Class::kStatusNotReady, self);
- mirror::Class* Object_class = FindSystemClass("Ljava/lang/Object;");
+ mirror::Class* Object_class = FindSystemClass(self, "Ljava/lang/Object;");
CHECK_EQ(java_lang_Object.get(), Object_class);
CHECK_EQ(java_lang_Object->GetObjectSize(), sizeof(mirror::Object));
java_lang_String->SetStatus(mirror::Class::kStatusNotReady, self);
- mirror::Class* String_class = FindSystemClass("Ljava/lang/String;");
+ mirror::Class* String_class = FindSystemClass(self, "Ljava/lang/String;");
CHECK_EQ(java_lang_String.get(), String_class);
CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(mirror::String));
java_lang_DexCache->SetStatus(mirror::Class::kStatusNotReady, self);
- mirror::Class* DexCache_class = FindSystemClass("Ljava/lang/DexCache;");
+ mirror::Class* DexCache_class = FindSystemClass(self, "Ljava/lang/DexCache;");
CHECK_EQ(java_lang_String.get(), String_class);
CHECK_EQ(java_lang_DexCache.get(), DexCache_class);
CHECK_EQ(java_lang_DexCache->GetObjectSize(), sizeof(mirror::DexCache));
// Setup the primitive array type classes - can't be done until Object has a vtable.
- SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
+ SetClassRoot(kBooleanArrayClass, FindSystemClass(self, "[Z"));
mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
- SetClassRoot(kByteArrayClass, FindSystemClass("[B"));
+ SetClassRoot(kByteArrayClass, FindSystemClass(self, "[B"));
mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
- mirror::Class* found_char_array_class = FindSystemClass("[C");
+ mirror::Class* found_char_array_class = FindSystemClass(self, "[C");
CHECK_EQ(char_array_class.get(), found_char_array_class);
- SetClassRoot(kShortArrayClass, FindSystemClass("[S"));
+ SetClassRoot(kShortArrayClass, FindSystemClass(self, "[S"));
mirror::ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
- mirror::Class* found_int_array_class = FindSystemClass("[I");
+ mirror::Class* found_int_array_class = FindSystemClass(self, "[I");
CHECK_EQ(int_array_class.get(), found_int_array_class);
- SetClassRoot(kLongArrayClass, FindSystemClass("[J"));
+ SetClassRoot(kLongArrayClass, FindSystemClass(self, "[J"));
mirror::LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
- SetClassRoot(kFloatArrayClass, FindSystemClass("[F"));
+ SetClassRoot(kFloatArrayClass, FindSystemClass(self, "[F"));
mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
- SetClassRoot(kDoubleArrayClass, FindSystemClass("[D"));
+ SetClassRoot(kDoubleArrayClass, FindSystemClass(self, "[D"));
mirror::DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
- mirror::Class* found_class_array_class = FindSystemClass("[Ljava/lang/Class;");
+ mirror::Class* found_class_array_class = FindSystemClass(self, "[Ljava/lang/Class;");
CHECK_EQ(class_array_class.get(), found_class_array_class);
- mirror::Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
+ mirror::Class* found_object_array_class = FindSystemClass(self, "[Ljava/lang/Object;");
CHECK_EQ(object_array_class.get(), found_object_array_class);
// Setup the single, global copy of "iftable".
- mirror::Class* java_lang_Cloneable = FindSystemClass("Ljava/lang/Cloneable;");
+ mirror::Class* java_lang_Cloneable = FindSystemClass(self, "Ljava/lang/Cloneable;");
CHECK(java_lang_Cloneable != NULL);
- mirror::Class* java_io_Serializable = FindSystemClass("Ljava/io/Serializable;");
+ mirror::Class* java_io_Serializable = FindSystemClass(self, "Ljava/io/Serializable;");
CHECK(java_io_Serializable != NULL);
// We assume that Cloneable/Serializable don't have superinterfaces -- normally we'd have to
// crawl up and explicitly list all of the supers as well.
@@ -398,73 +400,73 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class
CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
// Run Class, ArtField, and ArtMethod through FindSystemClass. This initializes their
// dex_cache_ fields and register them in class_table_.
- mirror::Class* Class_class = FindSystemClass("Ljava/lang/Class;");
+ mirror::Class* Class_class = FindSystemClass(self, "Ljava/lang/Class;");
CHECK_EQ(java_lang_Class.get(), Class_class);
java_lang_reflect_ArtMethod->SetStatus(mirror::Class::kStatusNotReady, self);
- mirror::Class* Art_method_class = FindSystemClass("Ljava/lang/reflect/ArtMethod;");
+ mirror::Class* Art_method_class = FindSystemClass(self, "Ljava/lang/reflect/ArtMethod;");
CHECK_EQ(java_lang_reflect_ArtMethod.get(), Art_method_class);
java_lang_reflect_ArtField->SetStatus(mirror::Class::kStatusNotReady, self);
- mirror::Class* Art_field_class = FindSystemClass("Ljava/lang/reflect/ArtField;");
+ mirror::Class* Art_field_class = FindSystemClass(self, "Ljava/lang/reflect/ArtField;");
CHECK_EQ(java_lang_reflect_ArtField.get(), Art_field_class);
- mirror::Class* String_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangStringArrayClass]);
+ mirror::Class* String_array_class = FindSystemClass(self, class_roots_descriptors_[kJavaLangStringArrayClass]);
CHECK_EQ(object_array_string.get(), String_array_class);
mirror::Class* Art_method_array_class =
- FindSystemClass(class_roots_descriptors_[kJavaLangReflectArtMethodArrayClass]);
+ FindSystemClass(self, class_roots_descriptors_[kJavaLangReflectArtMethodArrayClass]);
CHECK_EQ(object_array_art_method.get(), Art_method_array_class);
mirror::Class* Art_field_array_class =
- FindSystemClass(class_roots_descriptors_[kJavaLangReflectArtFieldArrayClass]);
+ FindSystemClass(self, class_roots_descriptors_[kJavaLangReflectArtFieldArrayClass]);
CHECK_EQ(object_array_art_field.get(), Art_field_array_class);
// End of special init trickery, subsequent classes may be loaded via FindSystemClass.
// Create java.lang.reflect.Proxy root.
- mirror::Class* java_lang_reflect_Proxy = FindSystemClass("Ljava/lang/reflect/Proxy;");
+ mirror::Class* java_lang_reflect_Proxy = FindSystemClass(self, "Ljava/lang/reflect/Proxy;");
SetClassRoot(kJavaLangReflectProxy, java_lang_reflect_Proxy);
// java.lang.ref classes need to be specially flagged, but otherwise are normal classes
- mirror::Class* java_lang_ref_Reference = FindSystemClass("Ljava/lang/ref/Reference;");
+ mirror::Class* java_lang_ref_Reference = FindSystemClass(self, "Ljava/lang/ref/Reference;");
SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference);
- mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
+ mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;");
java_lang_ref_FinalizerReference->SetAccessFlags(
java_lang_ref_FinalizerReference->GetAccessFlags() |
kAccClassIsReference | kAccClassIsFinalizerReference);
- mirror::Class* java_lang_ref_PhantomReference = FindSystemClass("Ljava/lang/ref/PhantomReference;");
+ mirror::Class* java_lang_ref_PhantomReference = FindSystemClass(self, "Ljava/lang/ref/PhantomReference;");
java_lang_ref_PhantomReference->SetAccessFlags(
java_lang_ref_PhantomReference->GetAccessFlags() |
kAccClassIsReference | kAccClassIsPhantomReference);
- mirror::Class* java_lang_ref_SoftReference = FindSystemClass("Ljava/lang/ref/SoftReference;");
+ mirror::Class* java_lang_ref_SoftReference = FindSystemClass(self, "Ljava/lang/ref/SoftReference;");
java_lang_ref_SoftReference->SetAccessFlags(
java_lang_ref_SoftReference->GetAccessFlags() | kAccClassIsReference);
- mirror::Class* java_lang_ref_WeakReference = FindSystemClass("Ljava/lang/ref/WeakReference;");
+ mirror::Class* java_lang_ref_WeakReference = FindSystemClass(self, "Ljava/lang/ref/WeakReference;");
java_lang_ref_WeakReference->SetAccessFlags(
java_lang_ref_WeakReference->GetAccessFlags() |
kAccClassIsReference | kAccClassIsWeakReference);
// Setup the ClassLoader, verifying the object_size_.
- mirror::Class* java_lang_ClassLoader = FindSystemClass("Ljava/lang/ClassLoader;");
+ mirror::Class* java_lang_ClassLoader = FindSystemClass(self, "Ljava/lang/ClassLoader;");
CHECK_EQ(java_lang_ClassLoader->GetObjectSize(), sizeof(mirror::ClassLoader));
SetClassRoot(kJavaLangClassLoader, java_lang_ClassLoader);
// Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
// java.lang.StackTraceElement as a convenience.
- SetClassRoot(kJavaLangThrowable, FindSystemClass("Ljava/lang/Throwable;"));
+ SetClassRoot(kJavaLangThrowable, FindSystemClass(self, "Ljava/lang/Throwable;"));
mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
- SetClassRoot(kJavaLangClassNotFoundException, FindSystemClass("Ljava/lang/ClassNotFoundException;"));
- SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;"));
- SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;"));
+ SetClassRoot(kJavaLangClassNotFoundException, FindSystemClass(self, "Ljava/lang/ClassNotFoundException;"));
+ SetClassRoot(kJavaLangStackTraceElement, FindSystemClass(self, "Ljava/lang/StackTraceElement;"));
+ SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass(self, "[Ljava/lang/StackTraceElement;"));
mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
- FinishInit();
+ FinishInit(self);
VLOG(startup) << "ClassLinker::InitFromCompiler exiting";
}
-void ClassLinker::FinishInit() {
+void ClassLinker::FinishInit(Thread* self) {
VLOG(startup) << "ClassLinker::FinishInit entering";
// Let the heap know some key offsets into java.lang.ref instances
@@ -473,7 +475,7 @@ void ClassLinker::FinishInit() {
// fully initialized
mirror::Class* java_lang_ref_Reference = GetClassRoot(kJavaLangRefReference);
mirror::Class* java_lang_ref_FinalizerReference =
- FindSystemClass("Ljava/lang/ref/FinalizerReference;");
+ FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;");
mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
FieldHelper fh(pendingNext);
@@ -1111,7 +1113,7 @@ void ClassLinker::InitFromImage() {
mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
- FinishInit();
+ FinishInit(self);
VLOG(startup) << "ClassLinker::InitFromImage exiting";
}
@@ -1150,6 +1152,13 @@ void ClassLinker::VisitRoots(RootCallback* callback, void* arg, bool only_dirty,
}
callback(reinterpret_cast<mirror::Object**>(&array_iftable_), arg, 0, kRootVMInternal);
DCHECK(array_iftable_ != nullptr);
+ for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
+ if (find_array_class_cache_[i] != nullptr) {
+ callback(reinterpret_cast<mirror::Object**>(&find_array_class_cache_[i]), arg, 0,
+ kRootVMInternal);
+ DCHECK(find_array_class_cache_[i] != nullptr);
+ }
+ }
}
void ClassLinker::VisitClasses(ClassVisitor* visitor, void* arg) {
@@ -1307,21 +1316,10 @@ static mirror::Class* EnsureResolved(Thread* self, mirror::Class* klass)
return klass;
}
-bool ClassLinker::IsInBootClassPath(const char* descriptor) {
- DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_);
- return pair.second != NULL;
-}
-
-mirror::Class* ClassLinker::FindSystemClass(const char* descriptor) {
- SirtRef<mirror::ClassLoader> class_loader(Thread::Current(), nullptr);
- return FindClass(descriptor, class_loader);
-}
-
-mirror::Class* ClassLinker::FindClass(const char* descriptor,
+mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor,
const SirtRef<mirror::ClassLoader>& class_loader) {
DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
- Thread* self = Thread::Current();
- DCHECK(self != NULL);
+ DCHECK(self != nullptr);
self->AssertNoPendingException();
if (descriptor[1] == '\0') {
// only the descriptors of primitive types should be 1 character long, also avoid class lookup
@@ -1335,7 +1333,7 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor,
}
// Class is not yet loaded.
if (descriptor[0] == '[') {
- return CreateArrayClass(descriptor, class_loader);
+ return CreateArrayClass(self, descriptor, class_loader);
} else if (class_loader.get() == nullptr) {
DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_);
if (pair.second != NULL) {
@@ -1346,7 +1344,7 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor,
// First try the boot class path, we check the descriptor first to avoid an unnecessary
// throw of a NoClassDefFoundError.
if (IsInBootClassPath(descriptor)) {
- mirror::Class* system_class = FindSystemClass(descriptor);
+ mirror::Class* system_class = FindSystemClass(self, descriptor);
CHECK(system_class != NULL);
return system_class;
}
@@ -1365,7 +1363,7 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor,
}
} else {
- ScopedObjectAccessUnchecked soa(self->GetJniEnv());
+ ScopedObjectAccessUnchecked soa(self);
ScopedLocalRef<jobject> class_loader_object(soa.Env(),
soa.AddLocalReference<jobject>(class_loader.get()));
std::string class_name_string(DescriptorToDot(descriptor));
@@ -1382,7 +1380,7 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor,
WellKnownClasses::java_lang_ClassLoader_loadClass,
class_name_object.get()));
}
- if (soa.Self()->IsExceptionPending()) {
+ if (self->IsExceptionPending()) {
// If the ClassLoader threw, pass that exception up.
return NULL;
} else if (result.get() == NULL) {
@@ -2133,12 +2131,11 @@ mirror::Class* ClassLinker::InitializePrimitiveClass(mirror::Class* primitive_cl
// array class; that always comes from the base element class.
//
// Returns NULL with an exception raised on failure.
-mirror::Class* ClassLinker::CreateArrayClass(const char* descriptor,
+mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descriptor,
const SirtRef<mirror::ClassLoader>& class_loader) {
// Identify the underlying component type
CHECK_EQ('[', descriptor[0]);
- Thread* self = Thread::Current();
- SirtRef<mirror::Class> component_type(self, FindClass(descriptor + 1, class_loader));
+ SirtRef<mirror::Class> component_type(self, FindClass(self, descriptor + 1, class_loader));
if (component_type.get() == nullptr) {
DCHECK(self->IsExceptionPending());
return nullptr;
@@ -3242,7 +3239,7 @@ bool ClassLinker::ValidateSuperClassDescriptors(const SirtRef<mirror::Class>& kl
for (int i = super->GetVTable()->GetLength() - 1; i >= 0; --i) {
mirror::ArtMethod* method = klass->GetVTable()->Get(i);
if (method != super->GetVTable()->Get(i) &&
- !IsSameMethodSignatureInDifferentClassContexts(method, super.get(), klass.get())) {
+ !IsSameMethodSignatureInDifferentClassContexts(self, method, super.get(), klass.get())) {
ThrowLinkageError(klass.get(), "Class %s method %s resolves differently in superclass %s",
PrettyDescriptor(klass.get()).c_str(), PrettyMethod(method).c_str(),
PrettyDescriptor(super.get()).c_str());
@@ -3255,7 +3252,7 @@ bool ClassLinker::ValidateSuperClassDescriptors(const SirtRef<mirror::Class>& kl
if (klass->GetClassLoader() != interface->GetClassLoader()) {
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
mirror::ArtMethod* method = klass->GetIfTable()->GetMethodArray(i)->Get(j);
- if (!IsSameMethodSignatureInDifferentClassContexts(method, interface.get(),
+ if (!IsSameMethodSignatureInDifferentClassContexts(self, method, interface.get(),
method->GetDeclaringClass())) {
ThrowLinkageError(klass.get(), "Class %s method %s resolves differently in interface %s",
PrettyDescriptor(method->GetDeclaringClass()).c_str(),
@@ -3271,13 +3268,13 @@ bool ClassLinker::ValidateSuperClassDescriptors(const SirtRef<mirror::Class>& kl
// Returns true if classes referenced by the signature of the method are the
// same classes in klass1 as they are in klass2.
-bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(mirror::ArtMethod* method,
+bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(Thread* self,
+ mirror::ArtMethod* method,
mirror::Class* klass1,
mirror::Class* klass2) {
if (klass1 == klass2) {
return true;
}
- Thread* self = Thread::Current();
CHECK(klass1 != nullptr);
CHECK(klass2 != nullptr);
SirtRef<mirror::ClassLoader> loader1(self, klass1->GetClassLoader());
@@ -3292,7 +3289,7 @@ bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(mirror::ArtMetho
}
if (descriptor[0] == 'L' || descriptor[0] == '[') {
// Found a non-primitive type.
- if (!IsSameDescriptorInDifferentClassContexts(descriptor, loader1, loader2)) {
+ if (!IsSameDescriptorInDifferentClassContexts(self, descriptor, loader1, loader2)) {
return false;
}
}
@@ -3300,7 +3297,7 @@ bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(mirror::ArtMetho
// Check the return type
const char* descriptor = dex_file.GetReturnTypeDescriptor(proto_id);
if (descriptor[0] == 'L' || descriptor[0] == '[') {
- if (!IsSameDescriptorInDifferentClassContexts(descriptor, loader1, loader2)) {
+ if (!IsSameDescriptorInDifferentClassContexts(self, descriptor, loader1, loader2)) {
return false;
}
}
@@ -3308,16 +3305,15 @@ bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(mirror::ArtMetho
}
// Returns true if the descriptor resolves to the same class in the context of loader1 and loader2.
-bool ClassLinker::IsSameDescriptorInDifferentClassContexts(const char* descriptor,
+bool ClassLinker::IsSameDescriptorInDifferentClassContexts(Thread* self, const char* descriptor,
SirtRef<mirror::ClassLoader>& loader1,
SirtRef<mirror::ClassLoader>& loader2) {
CHECK(descriptor != nullptr);
- Thread* self = Thread::Current();
- SirtRef<mirror::Class> found1(self, FindClass(descriptor, loader1));
+ SirtRef<mirror::Class> found1(self, FindClass(self, descriptor, loader1));
if (found1.get() == nullptr) {
self->ClearException();
}
- mirror::Class* found2 = FindClass(descriptor, loader2);
+ mirror::Class* found2 = FindClass(self, descriptor, loader2);
if (found2 == nullptr) {
self->ClearException();
}
@@ -4117,22 +4113,22 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_i
DCHECK(dex_cache.get() != NULL);
mirror::Class* resolved = dex_cache->GetResolvedType(type_idx);
if (resolved == NULL) {
+ Thread* self = Thread::Current();
const char* descriptor = dex_file.StringByTypeIdx(type_idx);
- resolved = FindClass(descriptor, class_loader);
+ resolved = FindClass(self, descriptor, class_loader);
if (resolved != NULL) {
// TODO: we used to throw here if resolved's class loader was not the
// boot class loader. This was to permit different classes with the
// same name to be loaded simultaneously by different loaders
dex_cache->SetResolvedType(type_idx, resolved);
} else {
- Thread* self = Thread::Current();
CHECK(self->IsExceptionPending())
<< "Expected pending exception for failed resolution of: " << descriptor;
// Convert a ClassNotFoundException to a NoClassDefFoundError.
SirtRef<mirror::Throwable> cause(self, self->GetException(NULL));
if (cause->InstanceOf(GetClassRoot(kJavaLangClassNotFoundException))) {
DCHECK(resolved == NULL); // No SirtRef needed to preserve resolved.
- Thread::Current()->ClearException();
+ self->ClearException();
ThrowNoClassDefFoundError("Failed resolution of: %s", descriptor);
self->GetException(NULL)->SetCause(cause.get());
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 0745ee2..f346102 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -72,10 +72,17 @@ class ClassLinker {
// Finds a class by its descriptor, loading it if necessary.
// If class_loader is null, searches boot_class_path_.
- mirror::Class* FindClass(const char* descriptor, const SirtRef<mirror::ClassLoader>& class_loader)
+ mirror::Class* FindClass(Thread* self, const char* descriptor,
+ const SirtRef<mirror::ClassLoader>& class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::Class* FindSystemClass(const char* descriptor)
+ // Finds a class by its descriptor using the "system" class loader, ie by searching the
+ // boot_class_path_.
+ mirror::Class* FindSystemClass(Thread* self, const char* descriptor)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Finds the array class given for the element class.
+ mirror::Class* FindArrayClass(Thread* self, mirror::Class* element_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Reutrns true if the class linker is initialized.
@@ -378,7 +385,7 @@ class ClassLinker {
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FinishInit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void FinishInit(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// For early bootstrapping by Init
mirror::Class* AllocClass(Thread* self, mirror::Class* java_lang_Class, size_t class_size)
@@ -399,7 +406,7 @@ class ClassLinker {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::Class* CreateArrayClass(const char* descriptor,
+ mirror::Class* CreateArrayClass(Thread* self, const char* descriptor,
const SirtRef<mirror::ClassLoader>& class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -449,12 +456,12 @@ class ClassLinker {
bool ValidateSuperClassDescriptors(const SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsSameDescriptorInDifferentClassContexts(const char* descriptor,
+ bool IsSameDescriptorInDifferentClassContexts(Thread* self, const char* descriptor,
SirtRef<mirror::ClassLoader>& class_loader1,
SirtRef<mirror::ClassLoader>& class_loader2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsSameMethodSignatureInDifferentClassContexts(mirror::ArtMethod* method,
+ bool IsSameMethodSignatureInDifferentClassContexts(Thread* self, mirror::ArtMethod* method,
mirror::Class* klass1,
mirror::Class* klass2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -617,8 +624,15 @@ class ClassLinker {
return descriptor;
}
+ // The interface table used by all arrays.
mirror::IfTable* array_iftable_;
+ // A cache of the last FindArrayClass results. The cache serves to avoid creating array class
+ // descriptors for the sake of performing FindClass.
+ static constexpr size_t kFindArrayCacheSize = 16;
+ mirror::Class* find_array_class_cache_[kFindArrayCacheSize];
+ size_t find_array_class_cache_next_victim_;
+
bool init_done_;
bool dex_caches_dirty_ GUARDED_BY(dex_lock_);
bool class_table_dirty_ GUARDED_BY(Locks::classlinker_classes_lock_);
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index ebf02fe..d6a67cc 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -41,18 +41,20 @@ class ClassLinkerTest : public CommonTest {
protected:
void AssertNonExistentClass(const std::string& descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- EXPECT_TRUE(class_linker_->FindSystemClass(descriptor.c_str()) == NULL);
Thread* self = Thread::Current();
+ EXPECT_TRUE(class_linker_->FindSystemClass(self, descriptor.c_str()) == NULL);
EXPECT_TRUE(self->IsExceptionPending());
mirror::Object* exception = self->GetException(NULL);
self->ClearException();
- mirror::Class* exception_class = class_linker_->FindSystemClass("Ljava/lang/NoClassDefFoundError;");
+ mirror::Class* exception_class =
+ class_linker_->FindSystemClass(self, "Ljava/lang/NoClassDefFoundError;");
EXPECT_TRUE(exception->InstanceOf(exception_class));
}
void AssertPrimitiveClass(const std::string& descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AssertPrimitiveClass(descriptor, class_linker_->FindSystemClass(descriptor.c_str()));
+ Thread* self = Thread::Current();
+ AssertPrimitiveClass(descriptor, class_linker_->FindSystemClass(self, descriptor.c_str()));
}
void AssertPrimitiveClass(const std::string& descriptor, mirror::Class* primitive)
@@ -98,7 +100,7 @@ class ClassLinkerTest : public CommonTest {
Thread* self = Thread::Current();
SirtRef<mirror::ClassLoader> loader(self, class_loader);
SirtRef<mirror::Class> array(self,
- class_linker_->FindClass(array_descriptor.c_str(), loader));
+ class_linker_->FindClass(self, array_descriptor.c_str(), loader));
ClassHelper array_component_ch(array->GetComponentType());
EXPECT_STREQ(component_type.c_str(), array_component_ch.GetDescriptor());
EXPECT_EQ(class_loader, array->GetClassLoader());
@@ -115,7 +117,8 @@ class ClassLinkerTest : public CommonTest {
EXPECT_TRUE(array->GetClass()->GetSuperClass() != NULL);
ASSERT_STREQ(array_descriptor.c_str(), kh.GetDescriptor());
EXPECT_TRUE(array->GetSuperClass() != NULL);
- EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Object;"), array->GetSuperClass());
+ Thread* self = Thread::Current();
+ EXPECT_EQ(class_linker_->FindSystemClass(self, "Ljava/lang/Object;"), array->GetSuperClass());
EXPECT_TRUE(array->HasSuperClass());
ASSERT_TRUE(array->GetComponentType() != NULL);
kh.ChangeClass(array->GetComponentType());
@@ -147,6 +150,7 @@ class ClassLinkerTest : public CommonTest {
kh.ChangeClass(array.get());
kh.ChangeClass(kh.GetDirectInterface(1));
EXPECT_STREQ(kh.GetDescriptor(), "Ljava/io/Serializable;");
+ EXPECT_EQ(class_linker_->FindArrayClass(self, array->GetComponentType()), array.get());
}
void AssertMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -300,8 +304,8 @@ class ClassLinkerTest : public CommonTest {
void AssertDexFileClass(mirror::ClassLoader* class_loader, const std::string& descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ASSERT_TRUE(descriptor != NULL);
- SirtRef<mirror::Class> klass(Thread::Current(),
- class_linker_->FindSystemClass(descriptor.c_str()));
+ Thread* self = Thread::Current();
+ SirtRef<mirror::Class> klass(self, class_linker_->FindSystemClass(self, descriptor.c_str()));
ASSERT_TRUE(klass.get() != nullptr);
EXPECT_STREQ(descriptor.c_str(), ClassHelper(klass.get()).GetDescriptor());
EXPECT_EQ(class_loader, klass->GetClassLoader());
@@ -359,7 +363,9 @@ struct CheckOffsets {
std::vector<CheckOffset> offsets;
bool Check() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Class* klass = Runtime::Current()->GetClassLinker()->FindSystemClass(class_descriptor.c_str());
+ Thread* self = Thread::Current();
+ mirror::Class* klass =
+ Runtime::Current()->GetClassLinker()->FindSystemClass(self, class_descriptor.c_str());
CHECK(klass != NULL) << class_descriptor;
bool error = false;
@@ -646,12 +652,12 @@ TEST_F(ClassLinkerTest, FindClassNested) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Nested")));
- mirror::Class* outer = class_linker_->FindClass("LNested;", class_loader);
+ mirror::Class* outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader);
ASSERT_TRUE(outer != NULL);
EXPECT_EQ(0U, outer->NumVirtualMethods());
EXPECT_EQ(1U, outer->NumDirectMethods());
- mirror::Class* inner = class_linker_->FindClass("LNested$Inner;", class_loader);
+ mirror::Class* inner = class_linker_->FindClass(soa.Self(), "LNested$Inner;", class_loader);
ASSERT_TRUE(inner != NULL);
EXPECT_EQ(0U, inner->NumVirtualMethods());
EXPECT_EQ(1U, inner->NumDirectMethods());
@@ -673,7 +679,7 @@ TEST_F(ClassLinkerTest, FindClass_Primitives) {
TEST_F(ClassLinkerTest, FindClass) {
ScopedObjectAccess soa(Thread::Current());
- mirror::Class* JavaLangObject = class_linker_->FindSystemClass("Ljava/lang/Object;");
+ mirror::Class* JavaLangObject = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
ClassHelper kh(JavaLangObject);
ASSERT_TRUE(JavaLangObject != NULL);
ASSERT_TRUE(JavaLangObject->GetClass() != NULL);
@@ -710,7 +716,7 @@ TEST_F(ClassLinkerTest, FindClass) {
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")));
AssertNonExistentClass("LMyClass;");
- mirror::Class* MyClass = class_linker_->FindClass("LMyClass;", class_loader);
+ mirror::Class* MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
kh.ChangeClass(MyClass);
ASSERT_TRUE(MyClass != NULL);
ASSERT_TRUE(MyClass->GetClass() != NULL);
@@ -761,7 +767,7 @@ TEST_F(ClassLinkerTest, LibCore) {
// start of the object
TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
ScopedObjectAccess soa(Thread::Current());
- mirror::Class* array_class = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* array_class = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
mirror::ObjectArray<mirror::String>* array =
mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), array_class, 0);
uintptr_t data_offset =
@@ -777,27 +783,27 @@ TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::LongArray> long_array(soa.Self(), mirror::LongArray::Alloc(soa.Self(), 0));
- EXPECT_EQ(class_linker_->FindSystemClass("[J"), long_array->GetClass());
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[J"), long_array->GetClass());
uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData());
EXPECT_TRUE(IsAligned<8>(data_offset)); // Longs require 8 byte alignment
SirtRef<mirror::DoubleArray> double_array(soa.Self(), mirror::DoubleArray::Alloc(soa.Self(), 0));
- EXPECT_EQ(class_linker_->FindSystemClass("[D"), double_array->GetClass());
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[D"), double_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(double_array->GetData());
EXPECT_TRUE(IsAligned<8>(data_offset)); // Doubles require 8 byte alignment
SirtRef<mirror::IntArray> int_array(soa.Self(), mirror::IntArray::Alloc(soa.Self(), 0));
- EXPECT_EQ(class_linker_->FindSystemClass("[I"), int_array->GetClass());
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[I"), int_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(int_array->GetData());
EXPECT_TRUE(IsAligned<4>(data_offset)); // Ints require 4 byte alignment
SirtRef<mirror::CharArray> char_array(soa.Self(), mirror::CharArray::Alloc(soa.Self(), 0));
- EXPECT_EQ(class_linker_->FindSystemClass("[C"), char_array->GetClass());
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[C"), char_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(char_array->GetData());
EXPECT_TRUE(IsAligned<2>(data_offset)); // Chars require 2 byte alignment
SirtRef<mirror::ShortArray> short_array(soa.Self(), mirror::ShortArray::Alloc(soa.Self(), 0));
- EXPECT_EQ(class_linker_->FindSystemClass("[S"), short_array->GetClass());
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[S"), short_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(short_array->GetData());
EXPECT_TRUE(IsAligned<2>(data_offset)); // Shorts require 2 byte alignment
@@ -810,28 +816,28 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), nullptr);
mirror::Class* c;
- c = class_linker_->FindClass("Ljava/lang/Boolean;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
FieldHelper fh(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Byte;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Byte;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Character;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Character;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Double;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Double;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Float;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Float;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Integer;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Integer;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Long;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Long;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
- c = class_linker_->FindClass("Ljava/lang/Short;", class_loader);
+ c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Short;", class_loader);
fh.ChangeField(c->GetIFields()->Get(0));
EXPECT_STREQ("value", fh.GetName());
}
@@ -840,8 +846,8 @@ TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::ClassLoader> class_loader_1(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")));
SirtRef<mirror::ClassLoader> class_loader_2(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")));
- mirror::Class* MyClass_1 = class_linker_->FindClass("LMyClass;", class_loader_1);
- mirror::Class* MyClass_2 = class_linker_->FindClass("LMyClass;", class_loader_2);
+ mirror::Class* MyClass_1 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1);
+ mirror::Class* MyClass_2 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2);
EXPECT_TRUE(MyClass_1 != NULL);
EXPECT_TRUE(MyClass_2 != NULL);
EXPECT_NE(MyClass_1, MyClass_2);
@@ -849,8 +855,10 @@ TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
TEST_F(ClassLinkerTest, StaticFields) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Statics")));
- SirtRef<mirror::Class> statics(soa.Self(), class_linker_->FindClass("LStatics;", class_loader));
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
+ soa.Decode<mirror::ClassLoader*>(LoadDex("Statics")));
+ SirtRef<mirror::Class> statics(soa.Self(), class_linker_->FindClass(soa.Self(), "LStatics;",
+ class_loader));
class_linker_->EnsureInitialized(statics, true, true);
// Static final primitives that are initialized by a compile-time constant
@@ -933,11 +941,11 @@ TEST_F(ClassLinkerTest, StaticFields) {
TEST_F(ClassLinkerTest, Interfaces) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Interfaces")));
- mirror::Class* I = class_linker_->FindClass("LInterfaces$I;", class_loader);
- mirror::Class* J = class_linker_->FindClass("LInterfaces$J;", class_loader);
- mirror::Class* K = class_linker_->FindClass("LInterfaces$K;", class_loader);
- mirror::Class* A = class_linker_->FindClass("LInterfaces$A;", class_loader);
- mirror::Class* B = class_linker_->FindClass("LInterfaces$B;", class_loader);
+ mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader);
+ mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader);
+ mirror::Class* K = class_linker_->FindClass(soa.Self(), "LInterfaces$K;", class_loader);
+ mirror::Class* A = class_linker_->FindClass(soa.Self(), "LInterfaces$A;", class_loader);
+ mirror::Class* B = class_linker_->FindClass(soa.Self(), "LInterfaces$B;", class_loader);
EXPECT_TRUE(I->IsAssignableFrom(A));
EXPECT_TRUE(J->IsAssignableFrom(A));
EXPECT_TRUE(J->IsAssignableFrom(K));
@@ -996,7 +1004,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
const DexFile* dex_file = Runtime::Current()->GetCompileTimeClassPath(jclass_loader)[0];
CHECK(dex_file != NULL);
- mirror::Class* klass = class_linker_->FindClass("LStaticsFromCode;", class_loader);
+ mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader);
mirror::ArtMethod* clinit = klass->FindClassInitializer();
mirror::ArtMethod* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;");
const DexFile::StringId* string_id = dex_file->FindStringId("LStaticsFromCode;");
@@ -1017,32 +1025,32 @@ TEST_F(ClassLinkerTest, FinalizableBit) {
mirror::Class* c;
// Object has a finalize method, but we know it's empty.
- c = class_linker_->FindSystemClass("Ljava/lang/Object;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
EXPECT_FALSE(c->IsFinalizable());
// Enum has a finalize method to prevent its subclasses from implementing one.
- c = class_linker_->FindSystemClass("Ljava/lang/Enum;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Enum;");
EXPECT_FALSE(c->IsFinalizable());
// RoundingMode is an enum.
- c = class_linker_->FindSystemClass("Ljava/math/RoundingMode;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/math/RoundingMode;");
EXPECT_FALSE(c->IsFinalizable());
// RandomAccessFile extends Object and overrides finalize.
- c = class_linker_->FindSystemClass("Ljava/io/RandomAccessFile;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/RandomAccessFile;");
EXPECT_TRUE(c->IsFinalizable());
// FileInputStream is finalizable and extends InputStream which isn't.
- c = class_linker_->FindSystemClass("Ljava/io/InputStream;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/InputStream;");
EXPECT_FALSE(c->IsFinalizable());
- c = class_linker_->FindSystemClass("Ljava/io/FileInputStream;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/FileInputStream;");
EXPECT_TRUE(c->IsFinalizable());
// ScheduledThreadPoolExecutor doesn't have a finalize method but
// extends ThreadPoolExecutor which does.
- c = class_linker_->FindSystemClass("Ljava/util/concurrent/ThreadPoolExecutor;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/util/concurrent/ThreadPoolExecutor;");
EXPECT_TRUE(c->IsFinalizable());
- c = class_linker_->FindSystemClass("Ljava/util/concurrent/ScheduledThreadPoolExecutor;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/util/concurrent/ScheduledThreadPoolExecutor;");
EXPECT_TRUE(c->IsFinalizable());
}
diff --git a/runtime/common_test.h b/runtime/common_test.h
index 7f9b6b1..215b642 100644
--- a/runtime/common_test.h
+++ b/runtime/common_test.h
@@ -418,8 +418,9 @@ class CommonTest : public testing::Test {
void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
- SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
- mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
+ Thread* self = Thread::Current();
+ SirtRef<mirror::ClassLoader> loader(self, class_loader);
+ mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
CHECK(klass != NULL) << "Class not found " << class_name;
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
MakeExecutable(klass->GetDirectMethod(i));
@@ -632,8 +633,9 @@ class CommonTest : public testing::Test {
void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
- SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
- mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
+ Thread* self = Thread::Current();
+ SirtRef<mirror::ClassLoader> loader(self, class_loader);
+ mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
CHECK(klass != NULL) << "Class not found " << class_name;
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
CompileMethod(klass->GetDirectMethod(i));
@@ -656,7 +658,8 @@ class CommonTest : public testing::Test {
const char* method_name, const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
- mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
+ Thread* self = Thread::Current();
+ mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
CHECK(klass != NULL) << "Class not found " << class_name;
mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
CHECK(method != NULL) << "Direct method not found: "
@@ -668,7 +671,8 @@ class CommonTest : public testing::Test {
const char* method_name, const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
- mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
+ Thread* self = Thread::Current();
+ mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
CHECK(klass != NULL) << "Class not found " << class_name;
mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
CHECK(method != NULL) << "Virtual method not found: "
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 89f841e..d3f684d 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -289,27 +289,39 @@ static JDWP::JdwpTag BasicTagFromDescriptor(const char* descriptor) {
return static_cast<JDWP::JdwpTag>(descriptor[0]);
}
-static JDWP::JdwpTag TagFromClass(mirror::Class* c)
+static JDWP::JdwpTag TagFromClass(const ScopedObjectAccessUnchecked& soa, mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(c != NULL);
if (c->IsArrayClass()) {
return JDWP::JT_ARRAY;
}
-
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (c->IsStringClass()) {
return JDWP::JT_STRING;
- } else if (c->IsClassClass()) {
+ }
+ if (c->IsClassClass()) {
return JDWP::JT_CLASS_OBJECT;
- } else if (class_linker->FindSystemClass("Ljava/lang/Thread;")->IsAssignableFrom(c)) {
- return JDWP::JT_THREAD;
- } else if (class_linker->FindSystemClass("Ljava/lang/ThreadGroup;")->IsAssignableFrom(c)) {
- return JDWP::JT_THREAD_GROUP;
- } else if (class_linker->FindSystemClass("Ljava/lang/ClassLoader;")->IsAssignableFrom(c)) {
- return JDWP::JT_CLASS_LOADER;
- } else {
- return JDWP::JT_OBJECT;
}
+ {
+ mirror::Class* thread_class = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread);
+ if (thread_class->IsAssignableFrom(c)) {
+ return JDWP::JT_THREAD;
+ }
+ }
+ {
+ mirror::Class* thread_group_class =
+ soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup);
+ if (thread_group_class->IsAssignableFrom(c)) {
+ return JDWP::JT_THREAD_GROUP;
+ }
+ }
+ {
+ mirror::Class* class_loader_class =
+ soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader);
+ if (class_loader_class->IsAssignableFrom(c)) {
+ return JDWP::JT_CLASS_LOADER;
+ }
+ }
+ return JDWP::JT_OBJECT;
}
/*
@@ -320,9 +332,9 @@ static JDWP::JdwpTag TagFromClass(mirror::Class* c)
*
* Null objects are tagged JT_OBJECT.
*/
-static JDWP::JdwpTag TagFromObject(mirror::Object* o)
+static JDWP::JdwpTag TagFromObject(const ScopedObjectAccessUnchecked& soa, mirror::Object* o)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (o == NULL) ? JDWP::JT_OBJECT : TagFromClass(o->GetClass());
+ return (o == NULL) ? JDWP::JT_OBJECT : TagFromClass(soa, o->GetClass());
}
static bool IsPrimitiveTag(JDWP::JdwpTag tag) {
@@ -1011,11 +1023,12 @@ JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string& result
}
JDWP::JdwpError Dbg::GetObjectTag(JDWP::ObjectId object_id, uint8_t& tag) {
+ ScopedObjectAccessUnchecked soa(Thread::Current());
mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if (o == ObjectRegistry::kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
- tag = TagFromObject(o);
+ tag = TagFromObject(soa, o);
return JDWP::ERR_NONE;
}
@@ -1062,7 +1075,7 @@ JDWP::JdwpError Dbg::GetArrayLength(JDWP::ObjectId array_id, int& length) {
JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
mirror::Array* a = DecodeArray(array_id, status);
- if (a == NULL) {
+ if (a == nullptr) {
return status;
}
@@ -1093,10 +1106,12 @@ JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count,
memcpy(dst, &src[offset * width], count * width);
}
} else {
+ ScopedObjectAccessUnchecked soa(Thread::Current());
mirror::ObjectArray<mirror::Object>* oa = a->AsObjectArray<mirror::Object>();
for (int i = 0; i < count; ++i) {
mirror::Object* element = oa->Get(offset + i);
- JDWP::JdwpTag specific_tag = (element != NULL) ? TagFromObject(element) : tag;
+ JDWP::JdwpTag specific_tag = (element != nullptr) ? TagFromObject(soa, element)
+ : tag;
expandBufAdd1(pReply, specific_tag);
expandBufAddObjectId(pReply, gRegistry->Add(element));
}
@@ -1639,8 +1654,9 @@ void Dbg::OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::Expa
CHECK_EQ(tag, JDWP::JT_VOID);
}
} else {
+ ScopedObjectAccessUnchecked soa(Thread::Current());
mirror::Object* value = return_value->GetL();
- expandBufAdd1(pReply, TagFromObject(value));
+ expandBufAdd1(pReply, TagFromObject(soa, value));
expandBufAddObjectId(pReply, gRegistry->Add(value));
}
}
@@ -1672,7 +1688,7 @@ JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* p
if (thread_object == ObjectRegistry::kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
-
+ const char* old_cause = soa.Self()->StartAssertNoThreadSuspension("Debugger: GetThreadGroup");
// Okay, so it's an object, but is it actually a thread?
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread;
@@ -1685,14 +1701,14 @@ JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* p
if (error != JDWP::ERR_NONE) {
return error;
}
-
- mirror::Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Thread;");
- CHECK(c != NULL);
+ mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread);
+ CHECK(c != nullptr);
mirror::ArtField* f = c->FindInstanceField("group", "Ljava/lang/ThreadGroup;");
CHECK(f != NULL);
mirror::Object* group = f->GetObject(thread_object);
CHECK(group != NULL);
JDWP::ObjectId thread_group_id = gRegistry->Add(group);
+ soa.Self()->EndAssertNoThreadSuspension(old_cause);
expandBufAddObjectId(pReply, thread_group_id);
return JDWP::ERR_NONE;
@@ -1701,25 +1717,28 @@ JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* p
std::string Dbg::GetThreadGroupName(JDWP::ObjectId thread_group_id) {
ScopedObjectAccess soa(Thread::Current());
mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
- CHECK(thread_group != NULL);
-
- mirror::Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/ThreadGroup;");
- CHECK(c != NULL);
+ CHECK(thread_group != nullptr);
+ const char* old_cause = soa.Self()->StartAssertNoThreadSuspension("Debugger: GetThreadGroupName");
+ mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup);
+ CHECK(c != nullptr);
mirror::ArtField* f = c->FindInstanceField("name", "Ljava/lang/String;");
CHECK(f != NULL);
mirror::String* s = reinterpret_cast<mirror::String*>(f->GetObject(thread_group));
+ soa.Self()->EndAssertNoThreadSuspension(old_cause);
return s->ToModifiedUtf8();
}
JDWP::ObjectId Dbg::GetThreadGroupParent(JDWP::ObjectId thread_group_id) {
+ ScopedObjectAccessUnchecked soa(Thread::Current());
mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
- CHECK(thread_group != NULL);
-
- mirror::Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/ThreadGroup;");
- CHECK(c != NULL);
+ CHECK(thread_group != nullptr);
+ const char* old_cause = soa.Self()->StartAssertNoThreadSuspension("Debugger: GetThreadGroupParent");
+ mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup);
+ CHECK(c != nullptr);
mirror::ArtField* f = c->FindInstanceField("parent", "Ljava/lang/ThreadGroup;");
CHECK(f != NULL);
mirror::Object* parent = f->GetObject(thread_group);
+ soa.Self()->EndAssertNoThreadSuspension(old_cause);
return gRegistry->Add(parent);
}
@@ -2090,13 +2109,13 @@ JDWP::JdwpError Dbg::GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame
return JDWP::ERR_NONE;
}
-void Dbg::GetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame_id, int slot, JDWP::JdwpTag tag,
- uint8_t* buf, size_t width) {
+void Dbg::GetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame_id, int slot,
+ JDWP::JdwpTag tag, uint8_t* buf, size_t width) {
struct GetLocalVisitor : public StackVisitor {
- GetLocalVisitor(Thread* thread, Context* context, JDWP::FrameId frame_id, int slot,
- JDWP::JdwpTag tag, uint8_t* buf, size_t width)
+ GetLocalVisitor(const ScopedObjectAccessUnchecked& soa, Thread* thread, Context* context,
+ JDWP::FrameId frame_id, int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t width)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(thread, context), frame_id_(frame_id), slot_(slot), tag_(tag),
+ : StackVisitor(thread, context), soa_(soa), frame_id_(frame_id), slot_(slot), tag_(tag),
buf_(buf), width_(width) {}
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
@@ -2175,7 +2194,7 @@ void Dbg::GetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame_id, int sl
if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) {
LOG(FATAL) << "Register " << reg << " expected to hold object: " << o;
}
- tag_ = TagFromObject(o);
+ tag_ = TagFromObject(soa_, o);
JDWP::SetObjectId(buf_+1, gRegistry->Add(o));
}
break;
@@ -2208,7 +2227,7 @@ void Dbg::GetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame_id, int sl
JDWP::Set1(buf_, tag_);
return false;
}
-
+ const ScopedObjectAccessUnchecked& soa_;
const JDWP::FrameId frame_id_;
const int slot_;
JDWP::JdwpTag tag_;
@@ -2224,7 +2243,7 @@ void Dbg::GetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame_id, int sl
return;
}
UniquePtr<Context> context(Context::Create());
- GetLocalVisitor visitor(thread, context.get(), frame_id, slot, tag, buf, width);
+ GetLocalVisitor visitor(soa, thread, context.get(), frame_id, slot, tag, buf, width);
visitor.WalkStack();
}
@@ -3037,7 +3056,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
pReq->result_value.SetJ(0);
} else if (pReq->result_tag == JDWP::JT_OBJECT) {
/* if no exception thrown, examine object result more closely */
- JDWP::JdwpTag new_tag = TagFromObject(pReq->result_value.GetL());
+ JDWP::JdwpTag new_tag = TagFromObject(soa, pReq->result_value.GetL());
if (new_tag != pReq->result_tag) {
VLOG(jdwp) << " JDWP promoted result from " << pReq->result_tag << " to " << new_tag;
pReq->result_tag = new_tag;
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 8b94b5a..2c08351 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -18,7 +18,7 @@
#define ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
#include "base/macros.h"
-#include "class_linker.h"
+#include "class_linker-inl.h"
#include "common_throws.h"
#include "dex_file.h"
#include "indirect_reference_table.h"
diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc
index f7b621f..c7f537a 100644
--- a/runtime/exception_test.cc
+++ b/runtime/exception_test.cc
@@ -39,7 +39,7 @@ class ExceptionTest : public CommonTest {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::ClassLoader> class_loader(
soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("ExceptionHandle")));
- my_klass_ = class_linker_->FindClass("LExceptionHandle;", class_loader);
+ my_klass_ = class_linker_->FindClass(soa.Self(), "LExceptionHandle;", class_loader);
ASSERT_TRUE(my_klass_ != NULL);
SirtRef<mirror::Class> sirt_klass(soa.Self(), my_klass_);
class_linker_->EnsureInitialized(sirt_klass, true, true);
diff --git a/runtime/gc/heap_test.cc b/runtime/gc/heap_test.cc
index b02b8bb..4b86339 100644
--- a/runtime/gc/heap_test.cc
+++ b/runtime/gc/heap_test.cc
@@ -43,7 +43,8 @@ TEST_F(HeapTest, GarbageCollectClassLinkerInit) {
ScopedObjectAccess soa(Thread::Current());
// garbage is created during ClassLinker::Init
- SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass("[Ljava/lang/Object;"));
+ SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
+ "[Ljava/lang/Object;"));
for (size_t i = 0; i < 1024; ++i) {
SirtRef<mirror::ObjectArray<mirror::Object> > array(soa.Self(),
mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.get(), 2048));
diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h
index d01bf2c..093967e 100644
--- a/runtime/gc/space/space_test.h
+++ b/runtime/gc/space/space_test.h
@@ -43,8 +43,9 @@ class SpaceTest : public CommonTest {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Note the minimum size, which is the size of a zero-length byte array.
EXPECT_GE(size, SizeOfZeroLengthByteArray());
- SirtRef<mirror::ClassLoader> null_loader(Thread::Current(), nullptr);
- mirror::Class* byte_array_class = Runtime::Current()->GetClassLinker()->FindClass("[B",
+ Thread* self = Thread::Current();
+ SirtRef<mirror::ClassLoader> null_loader(self, nullptr);
+ mirror::Class* byte_array_class = Runtime::Current()->GetClassLinker()->FindClass(self, "[B",
null_loader);
EXPECT_TRUE(byte_array_class != nullptr);
o->SetClass(byte_array_class);
diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc
index b6c6cb4..78e1992 100644
--- a/runtime/indirect_reference_table_test.cc
+++ b/runtime/indirect_reference_table_test.cc
@@ -48,7 +48,7 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
static const size_t kTableMax = 20;
IndirectReferenceTable irt(kTableInitial, kTableMax, kGlobal);
- mirror::Class* c = class_linker_->FindSystemClass("Ljava/lang/Object;");
+ mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
ASSERT_TRUE(c != NULL);
mirror::Object* obj0 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj0 != NULL);
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 9e1d915..83a1fbc 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -280,7 +280,7 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str()));
SirtRef<ClassLoader> class_loader(self, nullptr); // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader();
- Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(),
+ Class* found = Runtime::Current()->GetClassLinker()->FindClass(self, descriptor.c_str(),
class_loader);
CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: "
<< PrettyDescriptor(descriptor);
@@ -289,7 +289,7 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
SirtRef<ClassLoader> class_loader(self, down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset)));
std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset + 1)->AsString()->ToModifiedUtf8().c_str()));
- Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(),
+ Class* found = Runtime::Current()->GetClassLinker()->FindClass(self, descriptor.c_str(),
class_loader);
result->SetL(found);
} else if (name == "java.lang.Object java.lang.Class.newInstance()") {
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index a0665b5..76aa734 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -27,7 +27,7 @@
#include "base/mutex.h"
#include "base/stl_util.h"
#include "base/stringpiece.h"
-#include "class_linker.h"
+#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "gc/accounting/card_table-inl.h"
#include "interpreter/interpreter.h"
@@ -284,7 +284,7 @@ static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, con
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (sig[1] != '\0') {
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), c->GetClassLoader());
- field_type = class_linker->FindClass(sig, class_loader);
+ field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
} else {
field_type = class_linker->FindPrimitiveClass(*sig);
}
@@ -651,9 +651,9 @@ class JNI {
mirror::Class* c = nullptr;
if (runtime->IsStarted()) {
SirtRef<mirror::ClassLoader> class_loader(soa.Self(), GetClassLoader(soa));
- c = class_linker->FindClass(descriptor.c_str(), class_loader);
+ c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
} else {
- c = class_linker->FindSystemClass(descriptor.c_str());
+ c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
}
return soa.AddLocalReference<jclass>(c);
}
@@ -2140,13 +2140,8 @@ class JNI {
PrettyDescriptor(element_class).c_str());
return nullptr;
}
- std::string descriptor("[");
- descriptor += ClassHelper(element_class).GetDescriptor();
-
- // Find the class.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), element_class->GetClassLoader());
- array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
+ array_class = class_linker->FindArrayClass(soa.Self(), element_class);
if (UNLIKELY(array_class == nullptr)) {
return nullptr;
}
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index 2dd7d96..63bc45c 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -107,7 +107,8 @@ class JniInternalTest : public CommonTest {
class_name);
}
- mirror::Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(), class_loader);
+ mirror::Class* c = class_linker_->FindClass(self, DotToDescriptor(class_name).c_str(),
+ class_loader);
CHECK(c != NULL);
*method = is_static ? c->FindDirectMethod(method_name, method_signature)
@@ -1778,7 +1779,7 @@ TEST_F(JniInternalTest, StaticMainMethod) {
class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
- mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader);
+ mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
ASSERT_TRUE(klass != NULL);
mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
diff --git a/runtime/mirror/array.cc b/runtime/mirror/array.cc
index 2180857..715f072 100644
--- a/runtime/mirror/array.cc
+++ b/runtime/mirror/array.cc
@@ -18,6 +18,7 @@
#include "class.h"
#include "class-inl.h"
+#include "class_linker-inl.h"
#include "common_throws.h"
#include "dex_file-inl.h"
#include "gc/accounting/card_table-inl.h"
@@ -85,20 +86,22 @@ Array* Array::CreateMultiArray(Thread* self, const SirtRef<Class>& element_class
}
}
- // Generate the full name of the array class.
- std::string descriptor(num_dimensions, '[');
- descriptor += ClassHelper(element_class.get()).GetDescriptor();
-
// Find/generate the array class.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- SirtRef<mirror::ClassLoader> class_loader(self, element_class->GetClassLoader());
SirtRef<mirror::Class> array_class(self,
- class_linker->FindClass(descriptor.c_str(), class_loader));
+ class_linker->FindArrayClass(self, element_class.get()));
if (UNLIKELY(array_class.get() == nullptr)) {
CHECK(self->IsExceptionPending());
return nullptr;
}
- // create the array
+ for (int32_t i = 1; i < dimensions->GetLength(); ++i) {
+ array_class.reset(class_linker->FindArrayClass(self, array_class.get()));
+ if (UNLIKELY(array_class.get() == nullptr)) {
+ CHECK(self->IsExceptionPending());
+ return nullptr;
+ }
+ }
+ // Create the array.
Array* new_array = RecursiveCreateMultiArray(self, array_class, 0, dimensions);
if (UNLIKELY(new_array == nullptr)) {
CHECK(self->IsExceptionPending());
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 3208de9..6dbb29d 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -72,7 +72,7 @@ void Class::SetStatus(Status new_status, Thread* self) {
<< PrettyClass(this) << " " << old_status << " -> " << new_status;
}
}
- if (new_status == kStatusError) {
+ if (UNLIKELY(new_status == kStatusError)) {
CHECK_NE(GetStatus(), kStatusError)
<< "Attempt to set as erroneous an already erroneous class " << PrettyClass(this);
@@ -95,7 +95,8 @@ void Class::SetStatus(Status new_status, Thread* self) {
// clear exception to call FindSystemClass
self->ClearException();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* eiie_class = class_linker->FindSystemClass("Ljava/lang/ExceptionInInitializerError;");
+ Class* eiie_class = class_linker->FindSystemClass(self,
+ "Ljava/lang/ExceptionInInitializerError;");
CHECK(!self->IsExceptionPending());
// Only verification errors, not initialization problems, should set a verify error.
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 40c3748..34fb15e 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -123,7 +123,8 @@ TEST_F(ObjectTest, AllocObjectArray) {
EXPECT_TRUE(oa->Get(0) == oa.get());
EXPECT_TRUE(oa->Get(1) == oa.get());
- Class* aioobe = class_linker_->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;");
+ Class* aioobe = class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/ArrayIndexOutOfBoundsException;");
EXPECT_TRUE(oa->Get(-1) == NULL);
EXPECT_TRUE(soa.Self()->IsExceptionPending());
@@ -138,21 +139,23 @@ TEST_F(ObjectTest, AllocObjectArray) {
ASSERT_TRUE(oa->GetClass() != NULL);
ClassHelper oa_ch(oa->GetClass());
ASSERT_EQ(2U, oa_ch.NumDirectInterfaces());
- EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Cloneable;"), oa_ch.GetDirectInterface(0));
- EXPECT_EQ(class_linker_->FindSystemClass("Ljava/io/Serializable;"), oa_ch.GetDirectInterface(1));
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;"),
+ oa_ch.GetDirectInterface(0));
+ EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"),
+ oa_ch.GetDirectInterface(1));
}
TEST_F(ObjectTest, AllocArray) {
ScopedObjectAccess soa(Thread::Current());
- Class* c = class_linker_->FindSystemClass("[I");
+ Class* c = class_linker_->FindSystemClass(soa.Self(), "[I");
SirtRef<Array> a(soa.Self(), Array::Alloc<true>(soa.Self(), c, 1));
ASSERT_TRUE(c == a->GetClass());
- c = class_linker_->FindSystemClass("[Ljava/lang/Object;");
+ c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
a.reset(Array::Alloc<true>(soa.Self(), c, 1));
ASSERT_TRUE(c == a->GetClass());
- c = class_linker_->FindSystemClass("[[Ljava/lang/Object;");
+ c = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;");
a.reset(Array::Alloc<true>(soa.Self(), c, 1));
ASSERT_TRUE(c == a->GetClass());
}
@@ -173,7 +176,7 @@ void TestPrimitiveArray(ClassLinker* cl) {
EXPECT_EQ(T(123), a->Get(0));
EXPECT_EQ(T(321), a->Get(1));
- Class* aioobe = cl->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;");
+ Class* aioobe = cl->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;");
EXPECT_EQ(0, a->Get(-1));
EXPECT_TRUE(soa.Self()->IsExceptionPending());
@@ -214,7 +217,7 @@ TEST_F(ObjectTest, PrimitiveArray_Short_Alloc) {
TEST_F(ObjectTest, CheckAndAllocArrayFromCode) {
// pretend we are trying to call 'new char[3]' from String.toCharArray
ScopedObjectAccess soa(Thread::Current());
- Class* java_util_Arrays = class_linker_->FindSystemClass("Ljava/util/Arrays;");
+ Class* java_util_Arrays = class_linker_->FindSystemClass(soa.Self(), "Ljava/util/Arrays;");
ArtMethod* sort = java_util_Arrays->FindDirectMethod("sort", "([I)V");
const DexFile::StringId* string_id = java_lang_dex_file_->FindStringId("[I");
ASSERT_TRUE(string_id != NULL);
@@ -233,11 +236,11 @@ TEST_F(ObjectTest, CheckAndAllocArrayFromCode) {
TEST_F(ObjectTest, CreateMultiArray) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<Class> c(soa.Self(), class_linker_->FindSystemClass("I"));
+ SirtRef<Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(), "I"));
SirtRef<IntArray> dims(soa.Self(), IntArray::Alloc(soa.Self(), 1));
dims->Set<false>(0, 1);
Array* multi = Array::CreateMultiArray(soa.Self(), c, dims);
- EXPECT_TRUE(multi->GetClass() == class_linker_->FindSystemClass("[I"));
+ EXPECT_TRUE(multi->GetClass() == class_linker_->FindSystemClass(soa.Self(), "[I"));
EXPECT_EQ(1, multi->GetLength());
dims->Set<false>(0, -1);
@@ -253,11 +256,11 @@ TEST_F(ObjectTest, CreateMultiArray) {
dims->Set<false>(0, i);
dims->Set<false>(1, j);
multi = Array::CreateMultiArray(soa.Self(), c, dims);
- EXPECT_TRUE(multi->GetClass() == class_linker_->FindSystemClass("[[I"));
+ EXPECT_TRUE(multi->GetClass() == class_linker_->FindSystemClass(soa.Self(), "[[I"));
EXPECT_EQ(i, multi->GetLength());
for (int k = 0; k < i; ++k) {
Array* outer = multi->AsObjectArray<Array>()->Get(k);
- EXPECT_TRUE(outer->GetClass() == class_linker_->FindSystemClass("[I"));
+ EXPECT_TRUE(outer->GetClass() == class_linker_->FindSystemClass(soa.Self(), "[I"));
EXPECT_EQ(j, outer->GetLength());
}
}
@@ -272,8 +275,7 @@ TEST_F(ObjectTest, StaticFieldFromCode) {
CHECK(dex_file != NULL);
SirtRef<mirror::ClassLoader> loader(soa.Self(), soa.Decode<ClassLoader*>(class_loader));
- Class* klass =
- class_linker_->FindClass("LStaticsFromCode;", loader);
+ Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", loader);
ArtMethod* clinit = klass->FindClassInitializer();
const DexFile::StringId* klass_string_id = dex_file->FindStringId("LStaticsFromCode;");
ASSERT_TRUE(klass_string_id != NULL);
@@ -404,9 +406,9 @@ TEST_F(ObjectTest, DescriptorCompare) {
SirtRef<ClassLoader> class_loader_1(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader_1));
SirtRef<ClassLoader> class_loader_2(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader_2));
- Class* klass1 = linker->FindClass("LProtoCompare;", class_loader_1);
+ Class* klass1 = linker->FindClass(soa.Self(), "LProtoCompare;", class_loader_1);
ASSERT_TRUE(klass1 != NULL);
- Class* klass2 = linker->FindClass("LProtoCompare2;", class_loader_2);
+ Class* klass2 = linker->FindClass(soa.Self(), "LProtoCompare2;", class_loader_2);
ASSERT_TRUE(klass2 != NULL);
ArtMethod* m1_1 = klass1->GetVirtualMethod(0);
@@ -472,8 +474,8 @@ TEST_F(ObjectTest, InstanceOf) {
jobject jclass_loader = LoadDex("XandY");
SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
- Class* X = class_linker_->FindClass("LX;", class_loader);
- Class* Y = class_linker_->FindClass("LY;", class_loader);
+ Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader);
+ Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader);
ASSERT_TRUE(X != NULL);
ASSERT_TRUE(Y != NULL);
@@ -487,16 +489,16 @@ TEST_F(ObjectTest, InstanceOf) {
EXPECT_TRUE(y->InstanceOf(X));
EXPECT_TRUE(y->InstanceOf(Y));
- Class* java_lang_Class = class_linker_->FindSystemClass("Ljava/lang/Class;");
- Class* Object_array_class = class_linker_->FindSystemClass("[Ljava/lang/Object;");
+ Class* java_lang_Class = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Class;");
+ Class* Object_array_class = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
EXPECT_FALSE(java_lang_Class->InstanceOf(Object_array_class));
EXPECT_TRUE(Object_array_class->InstanceOf(java_lang_Class));
// All array classes implement Cloneable and Serializable.
Object* array = ObjectArray<Object>::Alloc(soa.Self(), Object_array_class, 1);
- Class* java_lang_Cloneable = class_linker_->FindSystemClass("Ljava/lang/Cloneable;");
- Class* java_io_Serializable = class_linker_->FindSystemClass("Ljava/io/Serializable;");
+ Class* java_lang_Cloneable = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;");
+ Class* java_io_Serializable = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;");
EXPECT_TRUE(array->InstanceOf(java_lang_Cloneable));
EXPECT_TRUE(array->InstanceOf(java_io_Serializable));
}
@@ -505,8 +507,8 @@ TEST_F(ObjectTest, IsAssignableFrom) {
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("XandY");
SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
- Class* X = class_linker_->FindClass("LX;", class_loader);
- Class* Y = class_linker_->FindClass("LY;", class_loader);
+ Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader);
+ Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader);
EXPECT_TRUE(X->IsAssignableFrom(X));
EXPECT_TRUE(X->IsAssignableFrom(Y));
@@ -514,8 +516,8 @@ TEST_F(ObjectTest, IsAssignableFrom) {
EXPECT_TRUE(Y->IsAssignableFrom(Y));
// class final String implements CharSequence, ..
- Class* string = class_linker_->FindSystemClass("Ljava/lang/String;");
- Class* charseq = class_linker_->FindSystemClass("Ljava/lang/CharSequence;");
+ Class* string = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;");
+ Class* charseq = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/CharSequence;");
// Can String be assigned to CharSequence without a cast?
EXPECT_TRUE(charseq->IsAssignableFrom(string));
// Can CharSequence be assigned to String without a cast?
@@ -542,36 +544,36 @@ TEST_F(ObjectTest, IsAssignableFromArray) {
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("XandY");
SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
- Class* X = class_linker_->FindClass("LX;", class_loader);
- Class* Y = class_linker_->FindClass("LY;", class_loader);
+ Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader);
+ Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader);
ASSERT_TRUE(X != NULL);
ASSERT_TRUE(Y != NULL);
- Class* YA = class_linker_->FindClass("[LY;", class_loader);
- Class* YAA = class_linker_->FindClass("[[LY;", class_loader);
+ Class* YA = class_linker_->FindClass(soa.Self(), "[LY;", class_loader);
+ Class* YAA = class_linker_->FindClass(soa.Self(), "[[LY;", class_loader);
ASSERT_TRUE(YA != NULL);
ASSERT_TRUE(YAA != NULL);
- Class* XAA = class_linker_->FindClass("[[LX;", class_loader);
+ Class* XAA = class_linker_->FindClass(soa.Self(), "[[LX;", class_loader);
ASSERT_TRUE(XAA != NULL);
- Class* O = class_linker_->FindSystemClass("Ljava/lang/Object;");
- Class* OA = class_linker_->FindSystemClass("[Ljava/lang/Object;");
- Class* OAA = class_linker_->FindSystemClass("[[Ljava/lang/Object;");
- Class* OAAA = class_linker_->FindSystemClass("[[[Ljava/lang/Object;");
+ Class* O = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
+ Class* OA = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
+ Class* OAA = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;");
+ Class* OAAA = class_linker_->FindSystemClass(soa.Self(), "[[[Ljava/lang/Object;");
ASSERT_TRUE(O != NULL);
ASSERT_TRUE(OA != NULL);
ASSERT_TRUE(OAA != NULL);
ASSERT_TRUE(OAAA != NULL);
- Class* S = class_linker_->FindSystemClass("Ljava/io/Serializable;");
- Class* SA = class_linker_->FindSystemClass("[Ljava/io/Serializable;");
- Class* SAA = class_linker_->FindSystemClass("[[Ljava/io/Serializable;");
+ Class* S = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;");
+ Class* SA = class_linker_->FindSystemClass(soa.Self(), "[Ljava/io/Serializable;");
+ Class* SAA = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/io/Serializable;");
ASSERT_TRUE(S != NULL);
ASSERT_TRUE(SA != NULL);
ASSERT_TRUE(SAA != NULL);
- Class* IA = class_linker_->FindSystemClass("[I");
+ Class* IA = class_linker_->FindSystemClass(soa.Self(), "[I");
ASSERT_TRUE(IA != NULL);
EXPECT_TRUE(YAA->IsAssignableFrom(YAA)); // identity
@@ -616,7 +618,7 @@ TEST_F(ObjectTest, FindInstanceField) {
// TODO: check that s.count == 3.
// Ensure that we handle superclass fields correctly...
- c = class_linker_->FindSystemClass("Ljava/lang/StringBuilder;");
+ c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/StringBuilder;");
ASSERT_TRUE(c != NULL);
// No StringBuilder.count...
EXPECT_TRUE(c->FindDeclaredInstanceField("count", "I") == NULL);
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index def3292..5779442 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -16,7 +16,7 @@
#include <limits.h>
-#include "class_linker.h"
+#include "class_linker-inl.h"
#include "common_throws.h"
#include "debugger.h"
#include "dex_file-inl.h"
@@ -57,22 +57,22 @@ static jobject VMRuntime_newNonMovableArray(JNIEnv* env, jobject, jclass javaEle
jint length) {
ScopedFastNativeObjectAccess soa(env);
mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass);
- if (element_class == NULL) {
+ if (UNLIKELY(element_class == nullptr)) {
ThrowNullPointerException(NULL, "element class == null");
- return NULL;
+ return nullptr;
}
- if (length < 0) {
+ if (UNLIKELY(length < 0)) {
ThrowNegativeArraySizeException(length);
- return NULL;
- }
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- std::string descriptor;
- descriptor += "[";
- descriptor += ClassHelper(element_class).GetDescriptor();
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), nullptr);
- mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
+ return nullptr;
+ }
+ Runtime* runtime = Runtime::Current();
+ mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(soa.Self(), element_class);
+ if (UNLIKELY(array_class == nullptr)) {
+ return nullptr;
+ }
+ gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentNonMovingAllocator();
mirror::Array* result = mirror::Array::Alloc<true>(soa.Self(), array_class, length,
- Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
+ allocator);
return soa.AddLocalReference<jobject>(result);
}
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 3e3f608..8bf36e7 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -43,7 +43,8 @@ static mirror::Class* DecodeClass(const ScopedFastNativeObjectAccess& soa, jobje
}
// "name" is in "binary name" format, e.g. "dalvik.system.Debug$1".
-static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize, jobject javaLoader) {
+static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize,
+ jobject javaLoader) {
ScopedObjectAccess soa(env);
ScopedUtfChars name(env, javaName);
if (name.c_str() == nullptr) {
@@ -64,7 +65,8 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean
SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
soa.Decode<mirror::ClassLoader*>(javaLoader));
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- SirtRef<mirror::Class> c(soa.Self(), class_linker->FindClass(descriptor.c_str(), class_loader));
+ SirtRef<mirror::Class> c(soa.Self(), class_linker->FindClass(soa.Self(), descriptor.c_str(),
+ class_loader));
if (c.get() == nullptr) {
ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
env->ExceptionClear();
diff --git a/runtime/native/java_lang_reflect_Array.cc b/runtime/native/java_lang_reflect_Array.cc
index 2197597..fc30aa6 100644
--- a/runtime/native/java_lang_reflect_Array.cc
+++ b/runtime/native/java_lang_reflect_Array.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "class_linker.h"
+#include "class_linker-inl.h"
#include "common_throws.h"
#include "dex_file-inl.h"
#include "jni_internal.h"
@@ -50,12 +50,8 @@ static jobject Array_createObjectArray(JNIEnv* env, jclass, jclass javaElementCl
ThrowNegativeArraySizeException(length);
return NULL;
}
- std::string descriptor("[");
- descriptor += ClassHelper(element_class).GetDescriptor();
-
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), element_class->GetClassLoader());
- mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
+ mirror::Class* array_class = class_linker->FindArrayClass(soa.Self(), element_class);
if (UNLIKELY(array_class == NULL)) {
CHECK(soa.Self()->IsExceptionPending());
return NULL;
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index a981fab..4eac291 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_OBJECT_UTILS_H_
#define ART_RUNTIME_OBJECT_UTILS_H_
-#include "class_linker-inl.h"
+#include "class_linker.h"
#include "dex_file.h"
#include "monitor.h"
#include "mirror/art_field.h"
@@ -158,10 +158,10 @@ class ClassHelper {
DCHECK(!klass_->IsPrimitive());
if (klass_->IsArrayClass()) {
if (idx == 0) {
- return GetClassLinker()->FindSystemClass("Ljava/lang/Cloneable;");
+ return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/lang/Cloneable;");
} else {
DCHECK_EQ(1U, idx);
- return GetClassLinker()->FindSystemClass("Ljava/io/Serializable;");
+ return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/io/Serializable;");
}
} else if (klass_->IsProxyClass()) {
return klass_->GetIfTable()->GetInterface(idx);
@@ -251,7 +251,7 @@ class FieldHelper {
mirror::Class* GetType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint32_t field_index = field_->GetDexFieldIndex();
if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
- return GetClassLinker()->FindSystemClass(GetTypeDescriptor());
+ return GetClassLinker()->FindSystemClass(Thread::Current(), GetTypeDescriptor());
}
const DexFile& dex_file = GetDexFile();
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
diff --git a/runtime/scoped_thread_state_change.h b/runtime/scoped_thread_state_change.h
index 2f959db..f0f5ed2 100644
--- a/runtime/scoped_thread_state_change.h
+++ b/runtime/scoped_thread_state_change.h
@@ -122,6 +122,7 @@ class ScopedObjectAccessUnchecked : public ScopedThreadStateChange {
: ScopedThreadStateChange(ThreadForEnv(env), kRunnable),
env_(down_cast<JNIEnvExt*>(env)), vm_(env_->vm) {
self_->VerifyStack();
+ Locks::mutator_lock_->AssertSharedHeld(self_);
}
explicit ScopedObjectAccessUnchecked(Thread* self)
@@ -130,6 +131,7 @@ class ScopedObjectAccessUnchecked : public ScopedThreadStateChange {
env_(down_cast<JNIEnvExt*>(self->GetJniEnv())),
vm_(env_ != NULL ? env_->vm : NULL) {
self_->VerifyStack();
+ Locks::mutator_lock_->AssertSharedHeld(self_);
}
// Used when we want a scoped JNI thread state but have no thread/JNIEnv. Consequently doesn't
@@ -139,6 +141,7 @@ class ScopedObjectAccessUnchecked : public ScopedThreadStateChange {
// Here purely to force inlining.
~ScopedObjectAccessUnchecked() ALWAYS_INLINE {
+ Locks::mutator_lock_->AssertSharedHeld(self_);
}
JNIEnvExt* Env() const {
@@ -250,14 +253,12 @@ class ScopedObjectAccess : public ScopedObjectAccessUnchecked {
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE
: ScopedObjectAccessUnchecked(env) {
- Locks::mutator_lock_->AssertSharedHeld(Self());
}
explicit ScopedObjectAccess(Thread* self)
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
: ScopedObjectAccessUnchecked(self) {
- Locks::mutator_lock_->AssertSharedHeld(Self());
}
~ScopedObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 8949a5b..8b93b91 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1529,7 +1529,7 @@ void Thread::ThrowNewWrappedException(const ThrowLocation& throw_location,
}
SirtRef<mirror::ClassLoader> class_loader(this, cl);
SirtRef<mirror::Class>
- exception_class(this, runtime->GetClassLinker()->FindClass(exception_class_descriptor,
+ exception_class(this, runtime->GetClassLinker()->FindClass(this, exception_class_descriptor,
class_loader));
if (UNLIKELY(exception_class.get() == nullptr)) {
CHECK(IsExceptionPending());
diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc
index dcfa24b..9dc7b44 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -29,7 +29,7 @@ class TransactionTest : public CommonTest {
TEST_F(TransactionTest, Object_class) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindSystemClass("Ljava/lang/Object;"));
+ class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
ASSERT_TRUE(sirt_klass.get() != nullptr);
Transaction transaction;
@@ -47,7 +47,8 @@ TEST_F(TransactionTest, Object_class) {
TEST_F(TransactionTest, Object_monitor) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindSystemClass("Ljava/lang/Object;"));
+ class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/Object;"));
ASSERT_TRUE(sirt_klass.get() != nullptr);
SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
ASSERT_TRUE(sirt_obj.get() != nullptr);
@@ -74,7 +75,8 @@ TEST_F(TransactionTest, Object_monitor) {
TEST_F(TransactionTest, Array_length) {
ScopedObjectAccess soa(Thread::Current());
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindSystemClass("[Ljava/lang/Object;"));
+ class_linker_->FindSystemClass(soa.Self(),
+ "[Ljava/lang/Object;"));
ASSERT_TRUE(sirt_klass.get() != nullptr);
constexpr int32_t kArraySize = 2;
@@ -101,7 +103,8 @@ TEST_F(TransactionTest, StaticFieldsTest) {
ASSERT_TRUE(class_loader.get() != nullptr);
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindClass("LStaticFieldsTest;", class_loader));
+ class_linker_->FindClass(soa.Self(), "LStaticFieldsTest;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->EnsureInitialized(sirt_klass, true, true);
ASSERT_TRUE(sirt_klass->IsInitialized());
@@ -147,13 +150,16 @@ TEST_F(TransactionTest, StaticFieldsTest) {
ASSERT_EQ(FieldHelper(doubleField).GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
ASSERT_EQ(doubleField->GetDouble(sirt_klass.get()), static_cast<double>(0.0));
- mirror::ArtField* objectField = sirt_klass->FindDeclaredStaticField("objectField", "Ljava/lang/Object;");
+ mirror::ArtField* objectField = sirt_klass->FindDeclaredStaticField("objectField",
+ "Ljava/lang/Object;");
ASSERT_TRUE(objectField != nullptr);
ASSERT_EQ(FieldHelper(objectField).GetTypeAsPrimitiveType(), Primitive::kPrimNot);
ASSERT_EQ(objectField->GetObject(sirt_klass.get()), nullptr);
// Create a java.lang.Object instance to set objectField.
- SirtRef<mirror::Class> object_klass(soa.Self(), class_linker_->FindSystemClass("Ljava/lang/Object;"));
+ SirtRef<mirror::Class> object_klass(soa.Self(),
+ class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/Object;"));
ASSERT_TRUE(object_klass.get() != nullptr);
SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
ASSERT_TRUE(sirt_obj.get() != nullptr);
@@ -193,7 +199,8 @@ TEST_F(TransactionTest, InstanceFieldsTest) {
ASSERT_TRUE(class_loader.get() != nullptr);
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindClass("LInstanceFieldsTest;", class_loader));
+ class_linker_->FindClass(soa.Self(), "LInstanceFieldsTest;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->EnsureInitialized(sirt_klass, true, true);
ASSERT_TRUE(sirt_klass->IsInitialized());
@@ -243,13 +250,16 @@ TEST_F(TransactionTest, InstanceFieldsTest) {
ASSERT_EQ(FieldHelper(doubleField).GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
ASSERT_EQ(doubleField->GetDouble(sirt_instance.get()), static_cast<double>(0.0));
- mirror::ArtField* objectField = sirt_klass->FindDeclaredInstanceField("objectField", "Ljava/lang/Object;");
+ mirror::ArtField* objectField = sirt_klass->FindDeclaredInstanceField("objectField",
+ "Ljava/lang/Object;");
ASSERT_TRUE(objectField != nullptr);
ASSERT_EQ(FieldHelper(objectField).GetTypeAsPrimitiveType(), Primitive::kPrimNot);
ASSERT_EQ(objectField->GetObject(sirt_instance.get()), nullptr);
// Create a java.lang.Object instance to set objectField.
- SirtRef<mirror::Class> object_klass(soa.Self(), class_linker_->FindSystemClass("Ljava/lang/Object;"));
+ SirtRef<mirror::Class> object_klass(soa.Self(),
+ class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/Object;"));
ASSERT_TRUE(object_klass.get() != nullptr);
SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
ASSERT_TRUE(sirt_obj.get() != nullptr);
@@ -290,7 +300,8 @@ TEST_F(TransactionTest, StaticArrayFieldsTest) {
ASSERT_TRUE(class_loader.get() != nullptr);
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindClass("LStaticArrayFieldsTest;", class_loader));
+ class_linker_->FindClass(soa.Self(), "LStaticArrayFieldsTest;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->EnsureInitialized(sirt_klass, true, true);
ASSERT_TRUE(sirt_klass->IsInitialized());
@@ -352,15 +363,19 @@ TEST_F(TransactionTest, StaticArrayFieldsTest) {
ASSERT_EQ(doubleArray->GetLength(), 1);
ASSERT_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
- mirror::ArtField* objectArrayField = sirt_klass->FindDeclaredStaticField("objectArrayField", "[Ljava/lang/Object;");
+ mirror::ArtField* objectArrayField = sirt_klass->FindDeclaredStaticField("objectArrayField",
+ "[Ljava/lang/Object;");
ASSERT_TRUE(objectArrayField != nullptr);
- mirror::ObjectArray<mirror::Object>* objectArray = objectArrayField->GetObject(sirt_klass.get())->AsObjectArray<mirror::Object>();
+ mirror::ObjectArray<mirror::Object>* objectArray =
+ objectArrayField->GetObject(sirt_klass.get())->AsObjectArray<mirror::Object>();
ASSERT_TRUE(objectArray != nullptr);
ASSERT_EQ(objectArray->GetLength(), 1);
ASSERT_EQ(objectArray->GetWithoutChecks(0), nullptr);
// Create a java.lang.Object instance to set objectField.
- SirtRef<mirror::Class> object_klass(soa.Self(), class_linker_->FindSystemClass("Ljava/lang/Object;"));
+ SirtRef<mirror::Class> object_klass(soa.Self(),
+ class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/Object;"));
ASSERT_TRUE(object_klass.get() != nullptr);
SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
ASSERT_TRUE(sirt_obj.get() != nullptr);
@@ -400,7 +415,9 @@ TEST_F(TransactionTest, EmptyClass) {
ASSERT_TRUE(class_loader.get() != nullptr);
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindClass("LTransaction$EmptyStatic;", class_loader));
+ class_linker_->FindClass(soa.Self(),
+ "LTransaction$EmptyStatic;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->VerifyClass(sirt_klass);
ASSERT_TRUE(sirt_klass->IsVerified());
@@ -419,7 +436,9 @@ TEST_F(TransactionTest, StaticFieldClass) {
ASSERT_TRUE(class_loader.get() != nullptr);
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindClass("LTransaction$StaticFieldClass;", class_loader));
+ class_linker_->FindClass(soa.Self(),
+ "LTransaction$StaticFieldClass;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->VerifyClass(sirt_klass);
ASSERT_TRUE(sirt_klass->IsVerified());
@@ -441,22 +460,25 @@ TEST_F(TransactionTest, BlacklistedClass) {
// Load and verify java.lang.ExceptionInInitializerError and java.lang.InternalError which will
// be thrown by class initialization due to native call.
SirtRef<mirror::Class> sirt_klass(soa.Self(),
- class_linker_->FindSystemClass("Ljava/lang/ExceptionInInitializerError;"));
+ class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/ExceptionInInitializerError;"));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->VerifyClass(sirt_klass);
ASSERT_TRUE(sirt_klass->IsVerified());
- sirt_klass.reset(class_linker_->FindSystemClass("Ljava/lang/InternalError;"));
+ sirt_klass.reset(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/InternalError;"));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->VerifyClass(sirt_klass);
ASSERT_TRUE(sirt_klass->IsVerified());
// Load and verify Transaction$NativeSupport used in class initialization.
- sirt_klass.reset(class_linker_->FindClass("LTransaction$NativeSupport;", class_loader));
+ sirt_klass.reset(class_linker_->FindClass(soa.Self(), "LTransaction$NativeSupport;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->VerifyClass(sirt_klass);
ASSERT_TRUE(sirt_klass->IsVerified());
- sirt_klass.reset(class_linker_->FindClass("LTransaction$BlacklistedClass;", class_loader));
+ sirt_klass.reset(class_linker_->FindClass(soa.Self(), "LTransaction$BlacklistedClass;",
+ class_loader));
ASSERT_TRUE(sirt_klass.get() != nullptr);
class_linker_->VerifyClass(sirt_klass);
ASSERT_TRUE(sirt_klass->IsVerified());
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index b43177b..150695b 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -99,7 +99,7 @@ TEST_F(UtilsTest, PrettyTypeOf) {
SirtRef<mirror::ShortArray> a(soa.Self(), mirror::ShortArray::Alloc(soa.Self(), 2));
EXPECT_EQ("short[]", PrettyTypeOf(a.get()));
- mirror::Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.String[]", PrettyTypeOf(o));
@@ -109,7 +109,7 @@ TEST_F(UtilsTest, PrettyTypeOf) {
TEST_F(UtilsTest, PrettyClass) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyClass(NULL));
- mirror::Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyClass(o->GetClass()));
@@ -118,7 +118,7 @@ TEST_F(UtilsTest, PrettyClass) {
TEST_F(UtilsTest, PrettyClassAndClassLoader) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyClassAndClassLoader(NULL));
- mirror::Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.Class<java.lang.String[],null>", PrettyClassAndClassLoader(o->GetClass()));
@@ -128,7 +128,8 @@ TEST_F(UtilsTest, PrettyField) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyField(NULL));
- mirror::Class* java_lang_String = class_linker_->FindSystemClass("Ljava/lang/String;");
+ mirror::Class* java_lang_String = class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/String;");
mirror::ArtField* f;
f = java_lang_String->FindDeclaredInstanceField("count", "I");
@@ -197,7 +198,7 @@ TEST_F(UtilsTest, MangleForJni) {
TEST_F(UtilsTest, JniShortName_JniLongName) {
ScopedObjectAccess soa(Thread::Current());
- mirror::Class* c = class_linker_->FindSystemClass("Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
mirror::ArtMethod* m;
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index ab943a6..ffa8b9e 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3129,14 +3129,15 @@ mirror::ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst
this_class = actual_arg_type.GetClass();
} else {
const std::string& descriptor(actual_arg_type.GetDescriptor());
+ Thread* self = Thread::Current();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- this_class = class_linker->FindClass(descriptor.c_str(), *class_loader_);
+ this_class = class_linker->FindClass(self, descriptor.c_str(), *class_loader_);
if (this_class == NULL) {
Thread* self = Thread::Current();
self->ClearException();
// Look for a system class
SirtRef<mirror::ClassLoader> null_class_loader(self, nullptr);
- this_class = class_linker->FindClass(descriptor.c_str(), null_class_loader);
+ this_class = class_linker->FindClass(self, descriptor.c_str(), null_class_loader);
}
}
if (this_class == NULL) {
@@ -3638,7 +3639,7 @@ static mirror::ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint3
// Returns the access field of a quick field access (iget/iput-quick) or NULL
// if it cannot be found.
mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
- RegisterLine* reg_line) {
+ RegisterLine* reg_line) {
DCHECK(inst->Opcode() == Instruction::IGET_QUICK ||
inst->Opcode() == Instruction::IGET_WIDE_QUICK ||
inst->Opcode() == Instruction::IGET_OBJECT_QUICK ||
@@ -3654,12 +3655,12 @@ mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
const std::string& descriptor(object_type.GetDescriptor());
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Thread* self = Thread::Current();
- object_class = class_linker->FindClass(descriptor.c_str(), *class_loader_);
+ object_class = class_linker->FindClass(self, descriptor.c_str(), *class_loader_);
if (object_class == NULL) {
self->ClearException();
// Look for a system class
SirtRef<mirror::ClassLoader> null_class_loader(self, nullptr);
- object_class = class_linker->FindClass(descriptor.c_str(), null_class_loader);
+ object_class = class_linker->FindClass(self, descriptor.c_str(), null_class_loader);
}
}
if (object_class == NULL) {
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index a56abba..ffa2455 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -30,7 +30,7 @@ class MethodVerifierTest : public CommonTest {
void VerifyClass(const std::string& descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ASSERT_TRUE(descriptor != NULL);
- mirror::Class* klass = class_linker_->FindSystemClass(descriptor.c_str());
+ mirror::Class* klass = class_linker_->FindSystemClass(Thread::Current(), descriptor.c_str());
// Verify the class
std::string error_msg;
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 630ef8a..63f0ff4 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -18,6 +18,7 @@
#include "base/casts.h"
+#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
@@ -928,11 +929,7 @@ mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
}
mirror::Class* common_elem = ClassJoin(s_ct, t_ct);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Thread* self = Thread::Current();
- SirtRef<mirror::ClassLoader> class_loader(self, s->GetClassLoader());
- std::string descriptor("[");
- descriptor += ClassHelper(common_elem).GetDescriptor();
- mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
+ mirror::Class* array_class = class_linker->FindArrayClass(Thread::Current(), common_elem);
DCHECK(array_class != NULL);
return array_class;
} else {
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 5e894ed..9dd57b8 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -17,6 +17,7 @@
#include "reg_type_cache-inl.h"
#include "base/casts.h"
+#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
@@ -140,10 +141,11 @@ mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassL
// Class was not found, must create new type.
// Try resolving class
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- SirtRef<mirror::ClassLoader> class_loader(Thread::Current(), loader);
+ Thread* self = Thread::Current();
+ SirtRef<mirror::ClassLoader> class_loader(self, loader);
mirror::Class* klass = NULL;
if (can_load_classes_) {
- klass = class_linker->FindClass(descriptor, class_loader);
+ klass = class_linker->FindClass(self, descriptor, class_loader);
} else {
klass = class_linker->LookupClass(descriptor, loader);
if (klass != NULL && !klass->IsLoaded()) {
@@ -277,7 +279,8 @@ Type* RegTypeCache::CreatePrimitiveTypeInstance(const std::string& descriptor) {
mirror::Class* klass = NULL;
// Try loading the class from linker.
if (!descriptor.empty()) {
- klass = art::Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor.c_str());
+ klass = art::Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(),
+ descriptor.c_str());
}
Type* entry = Type::CreateInstance(klass, descriptor, RegTypeCache::primitive_count_);
RegTypeCache::primitive_count_++;