summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/driver/compiler_driver.cc14
-rw-r--r--openjdkjvmti/ti_class.cc84
-rw-r--r--openjdkjvmti/ti_class_loader.cc6
-rw-r--r--openjdkjvmti/ti_search.cc45
-rw-r--r--runtime/class_linker.cc105
-rw-r--r--runtime/class_linker.h30
-rw-r--r--runtime/class_loader_context.cc12
-rw-r--r--runtime/class_loader_context_test.cc117
-rw-r--r--runtime/class_loader_utils.h18
-rw-r--r--runtime/common_runtime_test.cc75
-rw-r--r--runtime/common_runtime_test.h9
-rw-r--r--runtime/debug_print.cc10
-rw-r--r--runtime/hidden_api_test.cc6
-rw-r--r--runtime/interpreter/unstarted_runtime.cc5
-rw-r--r--runtime/jni/java_vm_ext.cc12
-rw-r--r--runtime/native/java_lang_Class.cc29
-rw-r--r--runtime/well_known_classes.cc122
-rw-r--r--runtime/well_known_classes.h31
-rw-r--r--test/ti-agent/jni_helper.h2
19 files changed, 376 insertions, 356 deletions
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index f374ab3b3e..bb3925613d 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -1043,16 +1043,16 @@ static void VerifyClassLoaderClassesAreImageClasses(/* out */ HashSet<std::strin
ScopedObjectAccess soa(Thread::Current());
ScopedAssertNoThreadSuspension sants(__FUNCTION__);
ObjPtr<mirror::Class> class_loader_classes[] = {
- soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_BaseDexClassLoader),
- soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader),
- soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DexClassLoader),
+ WellKnownClasses::dalvik_system_BaseDexClassLoader.Get(),
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
+ WellKnownClasses::dalvik_system_DexClassLoader.Get(),
WellKnownClasses::dalvik_system_DexFile.Get(),
WellKnownClasses::dalvik_system_DexPathList.Get(),
WellKnownClasses::dalvik_system_DexPathList__Element.Get(),
- soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_InMemoryDexClassLoader),
- soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader),
- soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader),
- soa.Decode<mirror::Class>(WellKnownClasses::java_lang_ClassLoader),
+ WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get(),
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
+ WellKnownClasses::java_lang_BootClassLoader.Get(),
+ WellKnownClasses::java_lang_ClassLoader.Get(),
};
for (ObjPtr<mirror::Class> klass : class_loader_classes) {
std::string temp;
diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc
index 50dab1fe09..37ceb37958 100644
--- a/openjdkjvmti/ti_class.cc
+++ b/openjdkjvmti/ti_class.cc
@@ -80,7 +80,7 @@
#include "ti_phase.h"
#include "ti_redefine.h"
#include "transform.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace openjdkjvmti {
@@ -927,40 +927,42 @@ jvmtiError ClassUtil::GetClassLoaderClassDescriptors(jvmtiEnv* env,
} else if (count_ptr == nullptr || classes == nullptr) {
return ERR(NULL_POINTER);
}
- art::JNIEnvExt* jnienv = self->GetJniEnv();
- if (loader == nullptr ||
- jnienv->IsInstanceOf(loader, art::WellKnownClasses::java_lang_BootClassLoader)) {
+ std::vector<const art::DexFile*> dex_files_storage;
+ const std::vector<const art::DexFile*>* dex_files = nullptr;
+ if (loader == nullptr) {
// We can just get the dex files directly for the boot class path.
- return CopyClassDescriptors(env,
- art::Runtime::Current()->GetClassLinker()->GetBootClassPath(),
- count_ptr,
- classes);
- }
- if (!jnienv->IsInstanceOf(loader, art::WellKnownClasses::java_lang_ClassLoader)) {
- return ERR(ILLEGAL_ARGUMENT);
- } else if (!jnienv->IsInstanceOf(loader,
- art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) {
- JVMTI_LOG(ERROR, env) << "GetClassLoaderClassDescriptors is only implemented for "
- << "BootClassPath and dalvik.system.BaseDexClassLoader class loaders";
- // TODO Possibly return OK With no classes would be better since these ones cannot have any
- // real classes associated with them.
- return ERR(NOT_IMPLEMENTED);
+ dex_files = &art::Runtime::Current()->GetClassLinker()->GetBootClassPath();
+ } else {
+ art::ScopedObjectAccess soa(self);
+ art::StackHandleScope<1> hs(self);
+ art::Handle<art::mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(loader)));
+ if (class_loader->InstanceOf(art::WellKnownClasses::java_lang_BootClassLoader.Get())) {
+ // We can just get the dex files directly for the boot class path.
+ dex_files = &art::Runtime::Current()->GetClassLinker()->GetBootClassPath();
+ } else if (!class_loader->InstanceOf(art::WellKnownClasses::java_lang_ClassLoader.Get())) {
+ return ERR(ILLEGAL_ARGUMENT);
+ } else if (!class_loader->InstanceOf(
+ art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) {
+ JVMTI_LOG(ERROR, env) << "GetClassLoaderClassDescriptors is only implemented for "
+ << "BootClassPath and dalvik.system.BaseDexClassLoader class loaders";
+ // TODO Possibly return OK With no classes would be better since these ones cannot have any
+ // real classes associated with them.
+ return ERR(NOT_IMPLEMENTED);
+ } else {
+ art::VisitClassLoaderDexFiles(
+ self,
+ class_loader,
+ [&](const art::DexFile* dex_file) {
+ dex_files_storage.push_back(dex_file);
+ return true; // Continue with other dex files.
+ });
+ dex_files = &dex_files_storage;
+ }
}
-
- art::ScopedObjectAccess soa(self);
- art::StackHandleScope<1> hs(self);
- art::Handle<art::mirror::ClassLoader> class_loader(
- hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(loader)));
- std::vector<const art::DexFile*> dex_files;
- art::VisitClassLoaderDexFiles(
- self,
- class_loader,
- [&](const art::DexFile* dex_file) {
- dex_files.push_back(dex_file);
- return true; // Continue with other dex files.
- });
// We hold the loader so the dex files won't go away until after this call at worst.
- return CopyClassDescriptors(env, dex_files, count_ptr, classes);
+ DCHECK(dex_files != nullptr);
+ return CopyClassDescriptors(env, *dex_files, count_ptr, classes);
}
jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env,
@@ -973,19 +975,17 @@ jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env,
return ERR(NULL_POINTER);
}
art::Thread* self = art::Thread::Current();
- if (!self->GetJniEnv()->IsInstanceOf(initiating_loader,
- art::WellKnownClasses::java_lang_ClassLoader)) {
- return ERR(ILLEGAL_ARGUMENT);
- }
- if (self->GetJniEnv()->IsInstanceOf(initiating_loader,
- art::WellKnownClasses::java_lang_BootClassLoader)) {
- // Need to use null for the BootClassLoader.
- initiating_loader = nullptr;
- }
-
art::ScopedObjectAccess soa(self);
art::ObjPtr<art::mirror::ClassLoader> class_loader =
soa.Decode<art::mirror::ClassLoader>(initiating_loader);
+ if (class_loader == nullptr) {
+ // Keep null, meaning the boot class loader.
+ } else if (!class_loader->InstanceOf(art::WellKnownClasses::java_lang_ClassLoader.Get())) {
+ return ERR(ILLEGAL_ARGUMENT);
+ } else if (class_loader->InstanceOf(art::WellKnownClasses::java_lang_BootClassLoader.Get())) {
+ // Need to use null for the BootClassLoader.
+ class_loader = nullptr;
+ }
art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
diff --git a/openjdkjvmti/ti_class_loader.cc b/openjdkjvmti/ti_class_loader.cc
index 72d57f0588..c117937f5f 100644
--- a/openjdkjvmti/ti_class_loader.cc
+++ b/openjdkjvmti/ti_class_loader.cc
@@ -57,6 +57,7 @@
#include "object_lock.h"
#include "runtime.h"
#include "transform.h"
+#include "well_known_classes-inl.h"
namespace openjdkjvmti {
@@ -139,9 +140,8 @@ art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> ClassLoaderHelper::Ge
art::Handle<art::mirror::ClassLoader> loader) {
art::StackHandleScope<4> hs(self);
- art::Handle<art::mirror::Class>
- base_dex_loader_class(hs.NewHandle(self->DecodeJObject(
- art::WellKnownClasses::dalvik_system_BaseDexClassLoader)->AsClass()));
+ art::Handle<art::mirror::Class> base_dex_loader_class =
+ hs.NewHandle(art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get());
// Get all the ArtFields so we can look in the BaseDexClassLoader
art::ArtField* path_list_field =
diff --git a/openjdkjvmti/ti_search.cc b/openjdkjvmti/ti_search.cc
index 5c1677fea3..4d96732494 100644
--- a/openjdkjvmti/ti_search.cc
+++ b/openjdkjvmti/ti_search.cc
@@ -60,7 +60,7 @@
#include "thread_list.h"
#include "ti_logging.h"
#include "ti_phase.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace openjdkjvmti {
@@ -339,33 +339,33 @@ jvmtiError SearchUtil::AddToDexClassLoader(jvmtiEnv* jvmti_env,
// exceptions are swallowed.
art::Thread* self = art::Thread::Current();
- JNIEnv* env = self->GetJniEnv();
- if (!env->IsInstanceOf(classloader, art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) {
+ art::ScopedObjectAccess soa(self);
+ art::StackHandleScope<2u> hs(self);
+ art::Handle<art::mirror::ClassLoader> class_loader =
+ hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(classloader));
+ if (!class_loader->InstanceOf(art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) {
JVMTI_LOG(ERROR, jvmti_env) << "Unable to add " << segment << " to non BaseDexClassLoader!";
return ERR(CLASS_LOADER_UNSUPPORTED);
}
- jmethodID add_dex_path_id = env->GetMethodID(
- art::WellKnownClasses::dalvik_system_BaseDexClassLoader,
- "addDexPath",
- "(Ljava/lang/String;)V");
+ art::ArtMethod* add_dex_path_id =
+ art::WellKnownClasses::dalvik_system_BaseDexClassLoader->FindClassMethod(
+ "addDexPath", "(Ljava/lang/String;)V", art::kRuntimePointerSize);
if (add_dex_path_id == nullptr) {
return ERR(INTERNAL);
}
- ScopedLocalRef<jstring> dex_path(env, env->NewStringUTF(segment));
- if (dex_path.get() == nullptr) {
+ art::Handle<art::mirror::String> dex_path =
+ hs.NewHandle(art::mirror::String::AllocFromModifiedUtf8(self, segment));
+ if (dex_path == nullptr) {
return ERR(INTERNAL);
}
- env->CallVoidMethod(classloader, add_dex_path_id, dex_path.get());
- if (env->ExceptionCheck()) {
- {
- art::ScopedObjectAccess soa(self);
- JVMTI_LOG(ERROR, jvmti_env) << "Failed to add " << segment << " to classloader. Error was "
- << self->GetException()->Dump();
- }
- env->ExceptionClear();
+ add_dex_path_id->InvokeVirtual<'V', 'L'>(self, class_loader.Get(), dex_path.Get());
+ if (self->IsExceptionPending()) {
+ JVMTI_LOG(ERROR, jvmti_env) << "Failed to add " << segment << " to classloader. Error was "
+ << self->GetException()->Dump();
+ self->ClearException();
return ERR(ILLEGAL_ARGUMENT);
}
return OK;
@@ -392,10 +392,13 @@ jvmtiError SearchUtil::AddToSystemClassLoaderSearch(jvmtiEnv* jvmti_env, const c
return ERR(INTERNAL);
}
- art::Thread* self = art::Thread::Current();
- JNIEnv* env = self->GetJniEnv();
- if (!env->IsInstanceOf(loader, art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) {
- return ERR(INTERNAL);
+ {
+ art::ScopedObjectAccess soa(art::Thread::Current());
+ art::ObjPtr<art::mirror::ClassLoader> class_loader =
+ soa.Decode<art::mirror::ClassLoader>(loader);
+ if (!class_loader->InstanceOf(art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) {
+ return ERR(INTERNAL);
+ }
}
return AddToDexClassLoader(jvmti_env, loader, segment);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6480dfd249..a421461d96 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1141,6 +1141,13 @@ void ClassLinker::RunRootClinits(Thread* self) {
WellKnownClasses::java_lang_Integer_valueOf,
WellKnownClasses::java_lang_Long_valueOf,
WellKnownClasses::java_lang_Short_valueOf,
+ // Ensure class loader classes are initialized (avoid check at runtime).
+ // Superclasses `ClassLoader` and `BaseDexClassLoader` are initialized implicitly.
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader_init,
+ WellKnownClasses::dalvik_system_DexClassLoader_init,
+ WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init,
+ WellKnownClasses::dalvik_system_PathClassLoader_init,
+ WellKnownClasses::java_lang_BootClassLoader_init,
// Ensure `Thread` and `ThreadGroup` classes are initialized (avoid check at runtime).
WellKnownClasses::java_lang_Thread_init,
WellKnownClasses::java_lang_ThreadGroup_add,
@@ -1159,6 +1166,10 @@ void ClassLinker::RunRootClinits(Thread* self) {
EnsureRootInitialized(this, self, method->GetDeclaringClass());
}
ArtField* static_fields_of_classes_to_initialize[] = {
+ // Ensure classes used by class loaders are initialized (avoid check at runtime).
+ WellKnownClasses::dalvik_system_DexFile_cookie,
+ WellKnownClasses::dalvik_system_DexPathList_dexElements,
+ WellKnownClasses::dalvik_system_DexPathList__Element_dexFile,
// Ensure `VMRuntime` is initialized (avoid check at runtime).
WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer,
// Initialize empty arrays needed by `StackOverflowError`.
@@ -1410,8 +1421,7 @@ void ClassLinker::AddExtraBootDexFiles(
bool ClassLinker::IsBootClassLoader(ObjPtr<mirror::ClassLoader> class_loader) {
return class_loader == nullptr ||
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader) ==
- class_loader->GetClass();
+ WellKnownClasses::java_lang_BootClassLoader == class_loader->GetClass();
}
class CHAOnDeleteUpdateClassVisitor {
@@ -3054,29 +3064,23 @@ ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
"%s",
class_name_string.c_str());
} else {
- ScopedLocalRef<jobject> class_loader_object(
- soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get()));
- ScopedLocalRef<jobject> result(soa.Env(), nullptr);
- {
- ScopedThreadStateChange tsc(self, ThreadState::kNative);
- ScopedLocalRef<jobject> class_name_object(
- soa.Env(), soa.Env()->NewStringUTF(class_name_string.c_str()));
- if (class_name_object.get() == nullptr) {
- DCHECK(self->IsExceptionPending()); // OOME.
- return nullptr;
- }
- CHECK(class_loader_object.get() != nullptr);
- result.reset(soa.Env()->CallObjectMethod(class_loader_object.get(),
- WellKnownClasses::java_lang_ClassLoader_loadClass,
- class_name_object.get()));
+ StackHandleScope<1u> hs(self);
+ Handle<mirror::String> class_name_object = hs.NewHandle(
+ mirror::String::AllocFromModifiedUtf8(self, class_name_string.c_str()));
+ if (class_name_object == nullptr) {
+ DCHECK(self->IsExceptionPending()); // OOME.
+ return nullptr;
}
- if (result.get() == nullptr && !self->IsExceptionPending()) {
+ DCHECK(class_loader != nullptr);
+ result_ptr = ObjPtr<mirror::Class>::DownCast(
+ WellKnownClasses::java_lang_ClassLoader_loadClass->InvokeVirtual<'L', 'L'>(
+ self, class_loader.Get(), class_name_object.Get()));
+ if (result_ptr == nullptr && !self->IsExceptionPending()) {
// broken loader - throw NPE to be compatible with Dalvik
ThrowNullPointerException(StringPrintf("ClassLoader.loadClass returned null for %s",
class_name_string.c_str()).c_str());
return nullptr;
}
- result_ptr = soa.Decode<mirror::Class>(result.get());
// Check the name of the returned class.
descriptor_equals = (result_ptr != nullptr) && result_ptr->DescriptorEquals(descriptor);
}
@@ -10088,6 +10092,9 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader(
Handle<mirror::ClassLoader> parent_loader,
Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries,
Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_after) {
+ CHECK(loader_class.Get() == WellKnownClasses::dalvik_system_PathClassLoader ||
+ loader_class.Get() == WellKnownClasses::dalvik_system_DelegateLastClassLoader ||
+ loader_class.Get() == WellKnownClasses::dalvik_system_InMemoryDexClassLoader);
StackHandleScope<5> hs(self);
@@ -10190,9 +10197,8 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader(
ArtField* const parent_field = WellKnownClasses::java_lang_ClassLoader_parent;
DCHECK(parent_field != nullptr);
if (parent_loader.Get() == nullptr) {
- ScopedObjectAccessUnchecked soa(self);
- ObjPtr<mirror::Object> boot_loader(WellKnownClasses::ToClass(
- WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self));
+ ObjPtr<mirror::Object> boot_loader(
+ WellKnownClasses::java_lang_BootClassLoader->AllocObject(self));
parent_field->SetObject<false>(h_class_loader.Get(), boot_loader);
} else {
parent_field->SetObject<false>(h_class_loader.Get(), parent_loader.Get());
@@ -10211,55 +10217,16 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader(
return h_class_loader.Get();
}
-jobject ClassLinker::CreateWellKnownClassLoader(Thread* self,
- const std::vector<const DexFile*>& dex_files,
- jclass loader_class,
- jobject parent_loader,
- jobject shared_libraries,
- jobject shared_libraries_after) {
- CHECK(self->GetJniEnv()->IsSameObject(loader_class,
- WellKnownClasses::dalvik_system_PathClassLoader) ||
- self->GetJniEnv()->IsSameObject(loader_class,
- WellKnownClasses::dalvik_system_DelegateLastClassLoader) ||
- self->GetJniEnv()->IsSameObject(loader_class,
- WellKnownClasses::dalvik_system_InMemoryDexClassLoader));
-
- // SOAAlreadyRunnable is protected, and we need something to add a global reference.
- // We could move the jobject to the callers, but all call-sites do this...
- ScopedObjectAccessUnchecked soa(self);
-
- // For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex.
- StackHandleScope<5> hs(self);
-
- Handle<mirror::Class> h_loader_class =
- hs.NewHandle<mirror::Class>(soa.Decode<mirror::Class>(loader_class));
- Handle<mirror::ClassLoader> h_parent =
- hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(parent_loader));
- Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries =
- hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries));
- Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries_after =
- hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries_after));
-
- ObjPtr<mirror::ClassLoader> loader = CreateWellKnownClassLoader(
- self,
- dex_files,
- h_loader_class,
- h_parent,
- h_shared_libraries,
- h_shared_libraries_after);
-
- // Make it a global ref and return.
- ScopedLocalRef<jobject> local_ref(
- soa.Env(), soa.Env()->AddLocalReference<jobject>(loader));
- return soa.Env()->NewGlobalRef(local_ref.get());
-}
-
jobject ClassLinker::CreatePathClassLoader(Thread* self,
const std::vector<const DexFile*>& dex_files) {
- return CreateWellKnownClassLoader(self,
- dex_files,
- WellKnownClasses::dalvik_system_PathClassLoader,
- nullptr);
+ StackHandleScope<3u> hs(self);
+ Handle<mirror::Class> d_s_pcl =
+ hs.NewHandle(WellKnownClasses::dalvik_system_PathClassLoader.Get());
+ auto null_parent = hs.NewHandle<mirror::ClassLoader>(nullptr);
+ auto null_libs = hs.NewHandle<mirror::ObjectArray<mirror::ClassLoader>>(nullptr);
+ ObjPtr<mirror::ClassLoader> class_loader =
+ CreateWellKnownClassLoader(self, dex_files, d_s_pcl, null_parent, null_libs, null_libs);
+ return Runtime::Current()->GetJavaVM()->AddGlobalRef(self, class_loader);
}
void ClassLinker::DropFindArrayClassCache() {
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 5f674b855a..37e9979395 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -670,31 +670,19 @@ class ClassLinker {
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Creates a GlobalRef PathClassLoader or DelegateLastClassLoader (specified by loader_class)
- // that can be used to load classes from the given dex files. The parent of the class loader
- // will be set to `parent_loader`. If `parent_loader` is null the parent will be
- // the boot class loader.
- // If class_loader points to a different class than PathClassLoader or DelegateLastClassLoader
- // this method will abort.
- // Note: the objects are not completely set up. Do not use this outside of tests and the compiler.
- jobject CreateWellKnownClassLoader(Thread* self,
- const std::vector<const DexFile*>& dex_files,
- jclass loader_class,
- jobject parent_loader,
- jobject shared_libraries = nullptr,
- jobject shared_libraries_after = nullptr)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!Locks::dex_lock_);
-
- // Calls CreateWellKnownClassLoader(self,
- // dex_files,
- // WellKnownClasses::dalvik_system_PathClassLoader,
- // nullptr)
+ // Calls `CreateWellKnownClassLoader()` with `WellKnownClasses::dalvik_system_PathClassLoader`,
+ // and null parent and libraries. Wraps the result in a JNI global reference.
jobject CreatePathClassLoader(Thread* self, const std::vector<const DexFile*>& dex_files)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
- // Non-GlobalRef version of CreateWellKnownClassLoader
+ // Creates a `PathClassLoader`, `DelegateLastClassLoader` or `InMemoryDexClassLoader`
+ // (specified by loader_class) that can be used to load classes from the given dex files.
+ // The parent of the class loader will be set to `parent_loader`. If `parent_loader` is
+ // null the parent will be the boot class loader.
+ // If `loader_class` points to a different class than `PathClassLoader`,
+ // `DelegateLastClassLoader` or `InMemoryDexClassLoader` this method will abort.
+ // Note: the objects are not completely set up. Do not use this outside of tests and the compiler.
ObjPtr<mirror::ClassLoader> CreateWellKnownClassLoader(
Thread* self,
const std::vector<const DexFile*>& dex_files,
diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc
index f2988c1fbc..722b8f7a64 100644
--- a/runtime/class_loader_context.cc
+++ b/runtime/class_loader_context.cc
@@ -778,14 +778,15 @@ void ClassLoaderContext::EncodeSharedLibAndParent(const ClassLoaderInfo& info,
}
// Returns the WellKnownClass for the given class loader type.
-static jclass GetClassLoaderClass(ClassLoaderContext::ClassLoaderType type) {
+static ObjPtr<mirror::Class> GetClassLoaderClass(ClassLoaderContext::ClassLoaderType type)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
switch (type) {
case ClassLoaderContext::kPathClassLoader:
- return WellKnownClasses::dalvik_system_PathClassLoader;
+ return WellKnownClasses::dalvik_system_PathClassLoader.Get();
case ClassLoaderContext::kDelegateLastClassLoader:
- return WellKnownClasses::dalvik_system_DelegateLastClassLoader;
+ return WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get();
case ClassLoaderContext::kInMemoryDexClassLoader:
- return WellKnownClasses::dalvik_system_InMemoryDexClassLoader;
+ return WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get();
case ClassLoaderContext::kInvalidClassLoader: break; // will fail after the switch.
}
LOG(FATAL) << "Invalid class loader type " << type;
@@ -883,8 +884,7 @@ static ObjPtr<mirror::ClassLoader> CreateClassLoaderInternal(
compilation_sources.begin(),
compilation_sources.end());
}
- Handle<mirror::Class> loader_class = hs.NewHandle<mirror::Class>(
- soa.Decode<mirror::Class>(GetClassLoaderClass(info.type)));
+ Handle<mirror::Class> loader_class = hs.NewHandle<mirror::Class>(GetClassLoaderClass(info.type));
ObjPtr<mirror::ClassLoader> loader =
Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
self,
diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc
index cb7726d4ec..d89c5b6b33 100644
--- a/runtime/class_loader_context_test.cc
+++ b/runtime/class_loader_context_test.cc
@@ -40,7 +40,7 @@
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -240,14 +240,14 @@ class ClassLoaderContextTest : public CommonRuntimeTest {
ASSERT_FALSE(context->owns_the_dex_files_);
}
- void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
+ void VerifyClassLoaderDexFiles(Thread* self,
Handle<mirror::ClassLoader> class_loader,
- jclass type,
+ ObjPtr<mirror::Class> type,
std::vector<const DexFile*>& expected_dex_files)
REQUIRES_SHARED(Locks::mutator_lock_) {
- ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
+ ASSERT_TRUE(class_loader->GetClass() == type);
- std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa.Self(), class_loader);
+ std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(self, class_loader);
ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
for (size_t i = 0; i < expected_dex_files.size(); i++) {
@@ -677,10 +677,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoader) {
Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
soa.Decode<mirror::ClassLoader>(jclass_loader));
- ASSERT_TRUE(class_loader->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader));
+ ASSERT_TRUE(class_loader->GetClass() == WellKnownClasses::dalvik_system_PathClassLoader);
ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
// For the first class loader the class path dex files must come first and then the
// compilation sources.
@@ -689,9 +688,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoader) {
expected_classpath.push_back(dex);
}
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
expected_classpath);
}
@@ -714,12 +713,12 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
soa.Decode<mirror::ClassLoader>(jclass_loader));
// An empty context should create a single PathClassLoader with only the compilation sources.
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
compilation_sources_raw);
ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
}
TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
@@ -765,31 +764,31 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
for (auto& dex : compilation_sources_raw) {
class_loader_1_dex_files.push_back(dex);
}
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_1,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_1_dex_files);
// Verify the second class loader
Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
std::vector<const DexFile*> class_loader_2_dex_files =
MakeNonOwningPointerVector(classpath_dex_c);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_2,
- WellKnownClasses::dalvik_system_DelegateLastClassLoader,
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
class_loader_2_dex_files);
// Verify the third class loader
Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
std::vector<const DexFile*> class_loader_3_dex_files =
MakeNonOwningPointerVector(classpath_dex_d);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_3,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_3_dex_files);
// The last class loader should have the BootClassLoader as a parent.
ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
}
TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
@@ -833,9 +832,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
for (auto& dex : compilation_sources_raw) {
class_loader_1_dex_files.push_back(dex);
}
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_1,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_1_dex_files);
// Verify the shared libraries.
@@ -851,9 +850,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
std::vector<const DexFile*> class_loader_2_dex_files =
MakeNonOwningPointerVector(classpath_dex_c);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_2,
- WellKnownClasses::dalvik_system_DelegateLastClassLoader,
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
class_loader_2_dex_files);
raw_shared_libraries = field->GetObject(class_loader_2.Get());
ASSERT_TRUE(raw_shared_libraries == nullptr);
@@ -862,20 +861,20 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
std::vector<const DexFile*> class_loader_3_dex_files =
MakeNonOwningPointerVector(classpath_dex_d);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_3,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_3_dex_files);
raw_shared_libraries = field->GetObject(class_loader_3.Get());
ASSERT_TRUE(raw_shared_libraries == nullptr);
// All class loaders should have the BootClassLoader as a parent.
ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
}
TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
@@ -917,9 +916,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo)
for (auto& dex : compilation_sources_raw) {
class_loader_1_dex_files.push_back(dex);
}
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_1,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_1_dex_files);
// Verify its shared library.
@@ -934,9 +933,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo)
Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
std::vector<const DexFile*> class_loader_2_dex_files =
MakeNonOwningPointerVector(classpath_dex_b);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_2,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_2_dex_files);
raw_shared_libraries = field->GetObject(class_loader_2.Get());
ASSERT_TRUE(raw_shared_libraries == nullptr);
@@ -945,9 +944,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo)
Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
std::vector<const DexFile*> class_loader_3_dex_files =
MakeNonOwningPointerVector(classpath_dex_c);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_3,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_3_dex_files);
// Verify its shared library.
@@ -961,20 +960,20 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo)
Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
std::vector<const DexFile*> class_loader_4_dex_files =
MakeNonOwningPointerVector(classpath_dex_d);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_4,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_4_dex_files);
raw_shared_libraries = field->GetObject(class_loader_4.Get());
ASSERT_TRUE(raw_shared_libraries == nullptr);
// Class loaders should have the BootClassLoader as a parent.
ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
}
TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
@@ -1016,9 +1015,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies)
for (auto& dex : compilation_sources_raw) {
class_loader_1_dex_files.push_back(dex);
}
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_1,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_1_dex_files);
// Verify its shared library.
@@ -1033,9 +1032,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies)
Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
std::vector<const DexFile*> class_loader_2_dex_files =
MakeNonOwningPointerVector(classpath_dex_b);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_2,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_2_dex_files);
// Verify the shared library dependency of the shared library.
@@ -1049,9 +1048,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies)
Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
std::vector<const DexFile*> class_loader_3_dex_files =
MakeNonOwningPointerVector(classpath_dex_c);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_3,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_3_dex_files);
raw_shared_libraries = field->GetObject(class_loader_3.Get());
ASSERT_TRUE(raw_shared_libraries == nullptr);
@@ -1060,20 +1059,20 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies)
Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
std::vector<const DexFile*> class_loader_4_dex_files =
MakeNonOwningPointerVector(classpath_dex_d);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_4,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_4_dex_files);
raw_shared_libraries = field->GetObject(class_loader_4.Get());
ASSERT_TRUE(raw_shared_libraries == nullptr);
// Class loaders should have the BootClassLoader as a parent.
ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
}
TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
@@ -1130,9 +1129,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
for (auto& dex : compilation_sources_raw) {
class_loader_1_dex_files.push_back(dex);
}
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_1,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_1_dex_files);
// Verify its shared library.
@@ -1147,18 +1146,18 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
std::vector<const DexFile*> class_loader_2_dex_files =
MakeNonOwningPointerVector(classpath_dex_b);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_2,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_2_dex_files);
// Verify the parent.
Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
std::vector<const DexFile*> class_loader_3_dex_files =
MakeNonOwningPointerVector(classpath_dex_c);
- VerifyClassLoaderDexFiles(soa,
+ VerifyClassLoaderDexFiles(soa.Self(),
class_loader_3,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
class_loader_3_dex_files);
// Verify its shared library is the same as the child.
@@ -1171,9 +1170,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
// Class loaders should have the BootClassLoader as a parent.
ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader));
+ WellKnownClasses::java_lang_BootClassLoader);
}
TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
diff --git a/runtime/class_loader_utils.h b/runtime/class_loader_utils.h
index eae31cce30..908d06225b 100644
--- a/runtime/class_loader_utils.h
+++ b/runtime/class_loader_utils.h
@@ -26,15 +26,14 @@
#include "mirror/object.h"
#include "native/dalvik_system_DexFile.h"
#include "scoped_thread_state_change-inl.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
// Returns true if the given class loader derives from BaseDexClassLoader.
inline bool IsInstanceOfBaseDexClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
- return class_loader->InstanceOf(
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_BaseDexClassLoader));
+ return class_loader->InstanceOf(WellKnownClasses::dalvik_system_BaseDexClassLoader.Get());
}
// Returns true if the given class loader is either a PathClassLoader or a DexClassLoader.
@@ -42,26 +41,21 @@ inline bool IsInstanceOfBaseDexClassLoader(Handle<mirror::ClassLoader> class_loa
inline bool IsPathOrDexClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass();
- return
- (class_loader_class ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader)) ||
- (class_loader_class ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DexClassLoader));
+ return (class_loader_class == WellKnownClasses::dalvik_system_PathClassLoader) ||
+ (class_loader_class == WellKnownClasses::dalvik_system_DexClassLoader);
}
// Returns true if the given class loader is an InMemoryDexClassLoader.
inline bool IsInMemoryDexClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass();
- return (class_loader_class ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_InMemoryDexClassLoader));
+ return (class_loader_class == WellKnownClasses::dalvik_system_InMemoryDexClassLoader);
}
inline bool IsDelegateLastClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass();
- return class_loader_class ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DelegateLastClassLoader);
+ return class_loader_class == WellKnownClasses::dalvik_system_DelegateLastClassLoader;
}
// Visit the DexPathList$Element instances in the given classloader with the given visitor.
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index f1139d446f..6a22a6680d 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -63,7 +63,7 @@
#include "runtime_intrinsics.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -199,11 +199,8 @@ std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_lo
std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
Thread* self,
Handle<mirror::ClassLoader> class_loader) {
- DCHECK(
- (class_loader->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader)) ||
- (class_loader->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
+ DCHECK((class_loader->GetClass() == WellKnownClasses::dalvik_system_PathClassLoader) ||
+ (class_loader->GetClass() == WellKnownClasses::dalvik_system_DelegateLastClassLoader));
std::vector<const DexFile*> ret;
VisitClassLoaderDexFiles(self,
@@ -257,8 +254,9 @@ jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
}
jobject
-CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::vector<std::string>& dex_names,
- jclass loader_class,
+CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(ScopedObjectAccess& soa,
+ const std::vector<std::string>& dex_names,
+ ObjPtr<mirror::Class> loader_class,
jobject parent_loader,
jobject shared_libraries,
jobject shared_libraries_after) {
@@ -271,39 +269,44 @@ CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::vector<std::stri
loaded_dex_files_.push_back(std::move(dex_file));
}
}
- Thread* self = Thread::Current();
- ScopedObjectAccess soa(self);
-
- jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
- self,
+ StackHandleScope<4> hs(soa.Self());
+ Handle<mirror::Class> h_loader_class = hs.NewHandle(loader_class);
+ Handle<mirror::ClassLoader> h_parent_loader =
+ hs.NewHandle(soa.Decode<mirror::ClassLoader>(parent_loader));
+ Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries =
+ hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries));
+ Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries_after =
+ hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries_after));
+
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ ObjPtr<mirror::ClassLoader> result = class_linker->CreateWellKnownClassLoader(
+ soa.Self(),
class_path,
- loader_class,
- parent_loader,
- shared_libraries,
- shared_libraries_after);
+ h_loader_class,
+ h_parent_loader,
+ h_shared_libraries,
+ h_shared_libraries_after);
{
// Verify we build the correct chain.
- ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
// Verify that the result has the correct class.
- CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
+ CHECK_EQ(h_loader_class.Get(), result->GetClass());
// Verify that the parent is not null. The boot class loader will be set up as a
// proper object.
- ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
+ ObjPtr<mirror::ClassLoader> actual_parent(result->GetParent());
CHECK(actual_parent != nullptr);
if (parent_loader != nullptr) {
// We were given a parent. Verify that it's what we expect.
- ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
- CHECK_EQ(expected_parent, actual_parent);
+ CHECK_EQ(h_parent_loader.Get(), actual_parent);
} else {
// No parent given. The parent must be the BootClassLoader.
- CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(actual_parent));
+ CHECK(class_linker->IsBootClassLoader(actual_parent));
}
}
- return result;
+ return soa.Env()->GetVm()->AddGlobalRef(soa.Self(), result);
}
jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
@@ -320,8 +323,10 @@ jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::vector<std::s
jobject parent_loader,
jobject shared_libraries,
jobject shared_libraries_after) {
- return LoadDexInWellKnownClassLoader(names,
- WellKnownClasses::dalvik_system_PathClassLoader,
+ ScopedObjectAccess soa(Thread::Current());
+ return LoadDexInWellKnownClassLoader(soa,
+ names,
+ WellKnownClasses::dalvik_system_PathClassLoader.Get(),
parent_loader,
shared_libraries,
shared_libraries_after);
@@ -329,16 +334,22 @@ jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::vector<std::s
jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
jobject parent_loader) {
- return LoadDexInWellKnownClassLoader({ dex_name },
- WellKnownClasses::dalvik_system_DelegateLastClassLoader,
- parent_loader);
+ ScopedObjectAccess soa(Thread::Current());
+ return LoadDexInWellKnownClassLoader(
+ soa,
+ { dex_name },
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
+ parent_loader);
}
jobject CommonRuntimeTestImpl::LoadDexInInMemoryDexClassLoader(const std::string& dex_name,
jobject parent_loader) {
- return LoadDexInWellKnownClassLoader({ dex_name },
- WellKnownClasses::dalvik_system_InMemoryDexClassLoader,
- parent_loader);
+ ScopedObjectAccess soa(Thread::Current());
+ return LoadDexInWellKnownClassLoader(
+ soa,
+ { dex_name },
+ WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get(),
+ parent_loader);
}
void CommonRuntimeTestImpl::FillHeap(Thread* self,
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 1b69c32b76..7904aeb086 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -152,6 +152,7 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl {
jobject LoadMultiDex(const char* first_dex_name, const char* second_dex_name)
REQUIRES_SHARED(Locks::mutator_lock_);
+ // The following helper functions return global JNI references to the class loader.
jobject LoadDexInPathClassLoader(const std::string& dex_name,
jobject parent_loader,
jobject shared_libraries = nullptr,
@@ -162,11 +163,13 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl {
jobject shared_libraries_after = nullptr);
jobject LoadDexInDelegateLastClassLoader(const std::string& dex_name, jobject parent_loader);
jobject LoadDexInInMemoryDexClassLoader(const std::string& dex_name, jobject parent_loader);
- jobject LoadDexInWellKnownClassLoader(const std::vector<std::string>& dex_names,
- jclass loader_class,
+ jobject LoadDexInWellKnownClassLoader(ScopedObjectAccess& soa,
+ const std::vector<std::string>& dex_names,
+ ObjPtr<mirror::Class> loader_class,
jobject parent_loader,
jobject shared_libraries = nullptr,
- jobject shared_libraries_after = nullptr);
+ jobject shared_libraries_after = nullptr)
+ REQUIRES_SHARED(Locks::mutator_lock_);
void VisitDexes(ArrayRef<const std::string> dexes,
const std::function<void(MethodReference)>& method_visitor,
diff --git a/runtime/debug_print.cc b/runtime/debug_print.cc
index f84b6b1d4a..fd9e050a7d 100644
--- a/runtime/debug_print.cc
+++ b/runtime/debug_print.cc
@@ -29,7 +29,7 @@
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -63,12 +63,10 @@ std::string DescribeSpace(ObjPtr<mirror::Class> klass) {
std::string DescribeLoaders(ObjPtr<mirror::ClassLoader> loader, const char* class_descriptor) {
std::ostringstream oss;
uint32_t hash = ComputeModifiedUtf8Hash(class_descriptor);
- ObjPtr<mirror::Class> path_class_loader =
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader);
- ObjPtr<mirror::Class> dex_class_loader =
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DexClassLoader);
+ ObjPtr<mirror::Class> path_class_loader = WellKnownClasses::dalvik_system_PathClassLoader.Get();
+ ObjPtr<mirror::Class> dex_class_loader = WellKnownClasses::dalvik_system_DexClassLoader.Get();
ObjPtr<mirror::Class> delegate_last_class_loader =
- WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DelegateLastClassLoader);
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get();
// Print the class loader chain.
bool found_class = false;
diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc
index 781fcd1ffa..a3d5db1f79 100644
--- a/runtime/hidden_api_test.cc
+++ b/runtime/hidden_api_test.cc
@@ -26,7 +26,7 @@
#include "common_runtime_test.h"
#include "jni/jni_internal.h"
#include "proxy_test.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -75,8 +75,8 @@ static bool LoadDexFiles(const std::string& path,
ClassLinker* const linker = Runtime::Current()->GetClassLinker();
StackHandleScope<2> hs(self);
- Handle<mirror::Class> h_class = hs.NewHandle(WellKnownClasses::ToClass(
- WellKnownClasses::dalvik_system_PathClassLoader));
+ Handle<mirror::Class> h_class =
+ hs.NewHandle(WellKnownClasses::dalvik_system_PathClassLoader.Get());
Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
self,
MakeNonOwningPointerVector(*dex_files),
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index c1cae6f124..0d40e13f51 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -61,7 +61,7 @@
#include "thread-inl.h"
#include "transaction.h"
#include "unstarted_runtime_list.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
namespace interpreter {
@@ -658,8 +658,7 @@ void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
StackHandleScope<1> hs(self);
Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
- if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
- this_classloader_class.Get()) {
+ if (WellKnownClasses::java_lang_BootClassLoader != this_classloader_class.Get()) {
AbortTransactionOrFail(self,
"Unsupported classloader type %s for getResourceAsStream",
mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc
index c55c7be10b..f1d4c3b305 100644
--- a/runtime/jni/java_vm_ext.cc
+++ b/runtime/jni/java_vm_ext.cc
@@ -52,7 +52,7 @@
#include "thread-inl.h"
#include "thread_list.h"
#include "ti/agent.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -1185,12 +1185,14 @@ jstring JavaVMExt::GetLibrarySearchPath(JNIEnv* env, jobject class_loader) {
if (class_loader == nullptr) {
return nullptr;
}
- if (!env->IsInstanceOf(class_loader, WellKnownClasses::dalvik_system_BaseDexClassLoader)) {
+ ScopedObjectAccess soa(env);
+ ObjPtr<mirror::Object> mirror_class_loader = soa.Decode<mirror::Object>(class_loader);
+ if (!mirror_class_loader->InstanceOf(WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) {
return nullptr;
}
- return reinterpret_cast<jstring>(env->CallObjectMethod(
- class_loader,
- WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath));
+ return soa.AddLocalReference<jstring>(
+ WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath->InvokeVirtual<'L'>(
+ soa.Self(), mirror_class_loader));
}
// JNI Invocation interface.
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index a861f25fab..fb48bb8d3c 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -19,7 +19,7 @@
#include <iostream>
#include "art_field-inl.h"
-#include "art_method-inl.h"
+#include "art_method-alloc-inl.h"
#include "base/enums.h"
#include "class_linker-inl.h"
#include "class_root-inl.h"
@@ -54,7 +54,7 @@
#include "reflective_handle_scope-inl.h"
#include "scoped_fast_native_object_access-inl.h"
#include "scoped_thread_state_change-inl.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -90,14 +90,17 @@ ALWAYS_INLINE static inline ObjPtr<mirror::Class> DecodeClass(
static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize,
jobject javaLoader) {
ScopedFastNativeObjectAccess soa(env);
- ScopedUtfChars name(env, javaName);
- if (name.c_str() == nullptr) {
+ StackHandleScope<3> hs(soa.Self());
+ Handle<mirror::String> mirror_name = hs.NewHandle(soa.Decode<mirror::String>(javaName));
+ if (mirror_name == nullptr) {
+ soa.Self()->ThrowNewWrappedException("Ljava/lang/NullPointerException;", /*msg=*/ nullptr);
return nullptr;
}
// We need to validate and convert the name (from x.y.z to x/y/z). This
// is especially handy for array types, since we want to avoid
// auto-generating bogus array classes.
+ std::string name = mirror_name->ToModifiedUtf8();
if (!IsValidBinaryClassName(name.c_str())) {
soa.Self()->ThrowNewExceptionF("Ljava/lang/ClassNotFoundException;",
"Invalid name: %s", name.c_str());
@@ -105,23 +108,21 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean
}
std::string descriptor(DotToDescriptor(name.c_str()));
- StackHandleScope<2> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader)));
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Handle<mirror::Class> c(
hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader)));
- if (c == nullptr) {
- ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
- env->ExceptionClear();
- jthrowable cnfe = reinterpret_cast<jthrowable>(
- env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException,
- WellKnownClasses::java_lang_ClassNotFoundException_init,
- javaName,
- cause.get()));
+ if (UNLIKELY(c == nullptr)) {
+ StackHandleScope<2> hs2(soa.Self());
+ Handle<mirror::Object> cause = hs2.NewHandle(soa.Self()->GetException());
+ soa.Self()->ClearException();
+ Handle<mirror::Object> cnfe =
+ WellKnownClasses::java_lang_ClassNotFoundException_init->NewObject<'L', 'L'>(
+ hs2, soa.Self(), mirror_name, cause);
if (cnfe != nullptr) {
// Make sure allocation didn't fail with an OOME.
- env->Throw(cnfe);
+ soa.Self()->SetException(ObjPtr<mirror::Throwable>::DownCast(cnfe.Get()));
}
return nullptr;
}
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index c963de466c..4322a614af 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -48,16 +48,8 @@ jclass WellKnownClasses::dalvik_annotation_optimization_CriticalNative;
jclass WellKnownClasses::dalvik_annotation_optimization_FastNative;
jclass WellKnownClasses::dalvik_annotation_optimization_NeverCompile;
jclass WellKnownClasses::dalvik_annotation_optimization_NeverInline;
-jclass WellKnownClasses::dalvik_system_BaseDexClassLoader;
-jclass WellKnownClasses::dalvik_system_DelegateLastClassLoader;
-jclass WellKnownClasses::dalvik_system_DexClassLoader;
jclass WellKnownClasses::dalvik_system_EmulatedStackFrame;
-jclass WellKnownClasses::dalvik_system_InMemoryDexClassLoader;
-jclass WellKnownClasses::dalvik_system_PathClassLoader;
jclass WellKnownClasses::java_lang_annotation_Annotation__array;
-jclass WellKnownClasses::java_lang_BootClassLoader;
-jclass WellKnownClasses::java_lang_ClassLoader;
-jclass WellKnownClasses::java_lang_ClassNotFoundException;
jclass WellKnownClasses::java_lang_Daemons;
jclass WellKnownClasses::java_lang_Error;
jclass WellKnownClasses::java_lang_IllegalAccessError;
@@ -76,13 +68,18 @@ jclass WellKnownClasses::java_lang_System;
jclass WellKnownClasses::java_lang_Void;
jclass WellKnownClasses::libcore_reflect_AnnotationMember__array;
-jmethodID WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath;
+ArtMethod* WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath;
+ArtMethod* WellKnownClasses::dalvik_system_DelegateLastClassLoader_init;
+ArtMethod* WellKnownClasses::dalvik_system_DexClassLoader_init;
+ArtMethod* WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init;
+ArtMethod* WellKnownClasses::dalvik_system_PathClassLoader_init;
ArtMethod* WellKnownClasses::dalvik_system_VMRuntime_hiddenApiUsed;
ArtMethod* WellKnownClasses::java_lang_Boolean_valueOf;
+ArtMethod* WellKnownClasses::java_lang_BootClassLoader_init;
ArtMethod* WellKnownClasses::java_lang_Byte_valueOf;
ArtMethod* WellKnownClasses::java_lang_Character_valueOf;
-jmethodID WellKnownClasses::java_lang_ClassLoader_loadClass;
-jmethodID WellKnownClasses::java_lang_ClassNotFoundException_init;
+ArtMethod* WellKnownClasses::java_lang_ClassLoader_loadClass;
+ArtMethod* WellKnownClasses::java_lang_ClassNotFoundException_init;
jmethodID WellKnownClasses::java_lang_Daemons_start;
jmethodID WellKnownClasses::java_lang_Daemons_stop;
jmethodID WellKnownClasses::java_lang_Daemons_waitForDaemonStart;
@@ -357,17 +354,9 @@ void WellKnownClasses::Init(JNIEnv* env) {
CacheClass(env, "dalvik/annotation/optimization/NeverCompile");
dalvik_annotation_optimization_NeverInline =
CacheClass(env, "dalvik/annotation/optimization/NeverInline");
- dalvik_system_BaseDexClassLoader = CacheClass(env, "dalvik/system/BaseDexClassLoader");
- dalvik_system_DelegateLastClassLoader = CacheClass(env, "dalvik/system/DelegateLastClassLoader");
- dalvik_system_DexClassLoader = CacheClass(env, "dalvik/system/DexClassLoader");
dalvik_system_EmulatedStackFrame = CacheClass(env, "dalvik/system/EmulatedStackFrame");
- dalvik_system_InMemoryDexClassLoader = CacheClass(env, "dalvik/system/InMemoryDexClassLoader");
- dalvik_system_PathClassLoader = CacheClass(env, "dalvik/system/PathClassLoader");
java_lang_annotation_Annotation__array = CacheClass(env, "[Ljava/lang/annotation/Annotation;");
- java_lang_BootClassLoader = CacheClass(env, "java/lang/BootClassLoader");
- java_lang_ClassLoader = CacheClass(env, "java/lang/ClassLoader");
- java_lang_ClassNotFoundException = CacheClass(env, "java/lang/ClassNotFoundException");
java_lang_Daemons = CacheClass(env, "java/lang/Daemons");
java_lang_Object = CacheClass(env, "java/lang/Object");
java_lang_OutOfMemoryError = CacheClass(env, "java/lang/OutOfMemoryError");
@@ -414,11 +403,6 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) {
java_lang_Short_valueOf =
CachePrimitiveBoxingMethod(class_linker, self, 'S', "Ljava/lang/Short;");
- dalvik_system_BaseDexClassLoader_getLdLibraryPath = CacheMethod(env, dalvik_system_BaseDexClassLoader, false, "getLdLibraryPath", "()Ljava/lang/String;");
-
- java_lang_ClassNotFoundException_init = CacheMethod(env, java_lang_ClassNotFoundException, false, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
- java_lang_ClassLoader_loadClass = CacheMethod(env, java_lang_ClassLoader, false, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
-
java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V");
java_lang_Daemons_stop = CacheMethod(env, java_lang_Daemons, true, "stop", "()V");
java_lang_Daemons_waitForDaemonStart = CacheMethod(env, java_lang_Daemons, true, "waitForDaemonStart", "()V");
@@ -430,17 +414,33 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) {
java_lang_reflect_Parameter_init = CacheMethod(env, java_lang_reflect_Parameter, false, "<init>", "(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V");
java_lang_String_charAt = CacheMethod(env, java_lang_String, false, "charAt", "(I)C");
- StackHandleScope<21u> hs(self);
+ StackHandleScope<29u> hs(self);
+ Handle<mirror::Class> d_s_bdcl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/BaseDexClassLoader;"));
+ Handle<mirror::Class> d_s_dlcl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DelegateLastClassLoader;"));
+ Handle<mirror::Class> d_s_dcl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexClassLoader;"));
Handle<mirror::Class> d_s_df =
hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexFile;"));
Handle<mirror::Class> d_s_dpl =
hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexPathList;"));
Handle<mirror::Class> d_s_dpl_e =
hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexPathList$Element;"));
+ Handle<mirror::Class> d_s_imdcl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/InMemoryDexClassLoader;"));
+ Handle<mirror::Class> d_s_pcl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/PathClassLoader;"));
Handle<mirror::Class> d_s_vmr =
hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/VMRuntime;"));
Handle<mirror::Class> j_i_fd =
hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/io/FileDescriptor;"));
+ Handle<mirror::Class> j_l_bcl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/BootClassLoader;"));
+ Handle<mirror::Class> j_l_cl =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ClassLoader;"));
+ Handle<mirror::Class> j_l_cnfe =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ClassNotFoundException;"));
Handle<mirror::Class> j_l_Thread =
hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Thread;"));
Handle<mirror::Class> j_l_tg =
@@ -477,6 +477,37 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) {
ScopedAssertNoThreadSuspension sants(__FUNCTION__);
PointerSize pointer_size = class_linker->GetImagePointerSize();
+ dalvik_system_BaseDexClassLoader_getLdLibraryPath = CacheMethod(
+ d_s_bdcl.Get(),
+ /*is_static=*/ false,
+ "getLdLibraryPath",
+ "()Ljava/lang/String;",
+ pointer_size);
+ dalvik_system_DelegateLastClassLoader_init = CacheMethod(
+ d_s_dlcl.Get(),
+ /*is_static=*/ false,
+ "<init>",
+ "(Ljava/lang/String;Ljava/lang/ClassLoader;)V",
+ pointer_size);
+ dalvik_system_DexClassLoader_init = CacheMethod(
+ d_s_dcl.Get(),
+ /*is_static=*/ false,
+ "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V",
+ pointer_size);
+ dalvik_system_InMemoryDexClassLoader_init = CacheMethod(
+ d_s_imdcl.Get(),
+ /*is_static=*/ false,
+ "<init>",
+ "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V",
+ pointer_size);
+ dalvik_system_PathClassLoader_init = CacheMethod(
+ d_s_pcl.Get(),
+ /*is_static=*/ false,
+ "<init>",
+ "(Ljava/lang/String;Ljava/lang/ClassLoader;)V",
+ pointer_size);
+
dalvik_system_VMRuntime_hiddenApiUsed = CacheMethod(
d_s_vmr.Get(),
/*is_static=*/ true,
@@ -484,6 +515,22 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) {
"(ILjava/lang/String;Ljava/lang/String;IZ)V",
pointer_size);
+ java_lang_BootClassLoader_init =
+ CacheMethod(j_l_bcl.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+ java_lang_ClassLoader_loadClass = CacheMethod(
+ j_l_cl.Get(),
+ /*is_static=*/ false,
+ "loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;",
+ pointer_size);
+
+ java_lang_ClassNotFoundException_init = CacheMethod(
+ j_l_cnfe.Get(),
+ /*is_static=*/ false,
+ "<init>",
+ "(Ljava/lang/String;Ljava/lang/Throwable;)V",
+ pointer_size);
+
ObjPtr<mirror::Class> j_l_Double = java_lang_Double_valueOf->GetDeclaringClass();
java_lang_Double_doubleToRawLongBits =
CacheMethod(j_l_Double, /*is_static=*/ true, "doubleToRawLongBits", "(D)J", pointer_size);
@@ -569,13 +616,15 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) {
"(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;",
pointer_size);
- ObjPtr<mirror::Class> d_s_bdcl = soa.Decode<mirror::Class>(dalvik_system_BaseDexClassLoader);
dalvik_system_BaseDexClassLoader_pathList = CacheField(
- d_s_bdcl, /*is_static=*/ false, "pathList", "Ldalvik/system/DexPathList;");
+ d_s_bdcl.Get(), /*is_static=*/ false, "pathList", "Ldalvik/system/DexPathList;");
dalvik_system_BaseDexClassLoader_sharedLibraryLoaders = CacheField(
- d_s_bdcl, /*is_static=*/ false, "sharedLibraryLoaders", "[Ljava/lang/ClassLoader;");
+ d_s_bdcl.Get(), /*is_static=*/ false, "sharedLibraryLoaders", "[Ljava/lang/ClassLoader;");
dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter = CacheField(
- d_s_bdcl, /*is_static=*/ false, "sharedLibraryLoadersAfter", "[Ljava/lang/ClassLoader;");
+ d_s_bdcl.Get(),
+ /*is_static=*/ false,
+ "sharedLibraryLoadersAfter",
+ "[Ljava/lang/ClassLoader;");
dalvik_system_DexFile_cookie = CacheField(
d_s_df.Get(), /*is_static=*/ false, "mCookie", "Ljava/lang/Object;");
dalvik_system_DexFile_fileName = CacheField(
@@ -594,9 +643,8 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) {
java_io_FileDescriptor_descriptor = CacheField(
j_i_fd.Get(), /*is_static=*/ false, "descriptor", "I");
- ObjPtr<mirror::Class> j_l_cl = soa.Decode<mirror::Class>(java_lang_ClassLoader);
java_lang_ClassLoader_parent = CacheField(
- j_l_cl, /*is_static=*/ false, "parent", "Ljava/lang/ClassLoader;");
+ j_l_cl.Get(), /*is_static=*/ false, "parent", "Ljava/lang/ClassLoader;");
java_lang_Thread_parkBlocker =
CacheField(j_l_Thread.Get(), /*is_static=*/ false, "parkBlocker", "Ljava/lang/Object;");
@@ -699,15 +747,8 @@ void WellKnownClasses::Clear() {
dalvik_annotation_optimization_FastNative = nullptr;
dalvik_annotation_optimization_NeverCompile = nullptr;
dalvik_annotation_optimization_NeverInline = nullptr;
- dalvik_system_BaseDexClassLoader = nullptr;
- dalvik_system_DelegateLastClassLoader = nullptr;
- dalvik_system_DexClassLoader = nullptr;
dalvik_system_EmulatedStackFrame = nullptr;
- dalvik_system_PathClassLoader = nullptr;
java_lang_annotation_Annotation__array = nullptr;
- java_lang_BootClassLoader = nullptr;
- java_lang_ClassLoader = nullptr;
- java_lang_ClassNotFoundException = nullptr;
java_lang_Daemons = nullptr;
java_lang_Error = nullptr;
java_lang_IllegalAccessError = nullptr;
@@ -727,11 +768,16 @@ void WellKnownClasses::Clear() {
libcore_reflect_AnnotationMember__array = nullptr;
dalvik_system_BaseDexClassLoader_getLdLibraryPath = nullptr;
+ WellKnownClasses::dalvik_system_DelegateLastClassLoader_init = nullptr;
+ WellKnownClasses::dalvik_system_DexClassLoader_init = nullptr;
+ WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init = nullptr;
+ WellKnownClasses::dalvik_system_PathClassLoader_init = nullptr;
dalvik_system_VMRuntime_hiddenApiUsed = nullptr;
java_io_FileDescriptor_descriptor = nullptr;
java_lang_Boolean_valueOf = nullptr;
java_lang_Byte_valueOf = nullptr;
java_lang_Character_valueOf = nullptr;
+ java_lang_BootClassLoader_init = nullptr;
java_lang_ClassLoader_loadClass = nullptr;
java_lang_ClassNotFoundException_init = nullptr;
java_lang_Daemons_start = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index f8b50e3dd1..1a07d9ccd4 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -94,16 +94,8 @@ struct WellKnownClasses {
static jclass dalvik_annotation_optimization_FastNative;
static jclass dalvik_annotation_optimization_NeverCompile;
static jclass dalvik_annotation_optimization_NeverInline;
- static jclass dalvik_system_BaseDexClassLoader;
- static jclass dalvik_system_DelegateLastClassLoader;
- static jclass dalvik_system_DexClassLoader;
static jclass dalvik_system_EmulatedStackFrame;
- static jclass dalvik_system_InMemoryDexClassLoader;
- static jclass dalvik_system_PathClassLoader;
static jclass java_lang_annotation_Annotation__array;
- static jclass java_lang_BootClassLoader;
- static jclass java_lang_ClassLoader;
- static jclass java_lang_ClassNotFoundException;
static jclass java_lang_Daemons;
static jclass java_lang_Error;
static jclass java_lang_IllegalAccessError;
@@ -122,13 +114,18 @@ struct WellKnownClasses {
static jclass java_lang_Void;
static jclass libcore_reflect_AnnotationMember__array;
- static jmethodID dalvik_system_BaseDexClassLoader_getLdLibraryPath;
+ static ArtMethod* dalvik_system_BaseDexClassLoader_getLdLibraryPath;
+ static ArtMethod* dalvik_system_DelegateLastClassLoader_init; // Only for the declaring class.
+ static ArtMethod* dalvik_system_DexClassLoader_init; // Only for the declaring class.
+ static ArtMethod* dalvik_system_InMemoryDexClassLoader_init; // Only for the declaring class.
+ static ArtMethod* dalvik_system_PathClassLoader_init; // Only for the declaring class.
static ArtMethod* dalvik_system_VMRuntime_hiddenApiUsed;
static ArtMethod* java_lang_Boolean_valueOf;
+ static ArtMethod* java_lang_BootClassLoader_init; // Only for the declaring class.
static ArtMethod* java_lang_Byte_valueOf;
static ArtMethod* java_lang_Character_valueOf;
- static jmethodID java_lang_ClassLoader_loadClass;
- static jmethodID java_lang_ClassNotFoundException_init;
+ static ArtMethod* java_lang_ClassLoader_loadClass;
+ static ArtMethod* java_lang_ClassNotFoundException_init;
static jmethodID java_lang_Daemons_start;
static jmethodID java_lang_Daemons_stop;
static jmethodID java_lang_Daemons_waitForDaemonStart;
@@ -210,10 +207,22 @@ struct WellKnownClasses {
static ArtField* org_apache_harmony_dalvik_ddmc_Chunk_offset;
static ArtField* org_apache_harmony_dalvik_ddmc_Chunk_type;
+ static constexpr ClassFromField<&dalvik_system_BaseDexClassLoader_pathList>
+ dalvik_system_BaseDexClassLoader;
+ static constexpr ClassFromMethod<&dalvik_system_DelegateLastClassLoader_init>
+ dalvik_system_DelegateLastClassLoader;
+ static constexpr ClassFromMethod<&dalvik_system_DexClassLoader_init>
+ dalvik_system_DexClassLoader;
static constexpr ClassFromField<&dalvik_system_DexFile_cookie> dalvik_system_DexFile;
static constexpr ClassFromField<&dalvik_system_DexPathList_dexElements> dalvik_system_DexPathList;
static constexpr ClassFromField<&dalvik_system_DexPathList__Element_dexFile>
dalvik_system_DexPathList__Element;
+ static constexpr ClassFromMethod<&dalvik_system_InMemoryDexClassLoader_init>
+ dalvik_system_InMemoryDexClassLoader;
+ static constexpr ClassFromMethod<&dalvik_system_PathClassLoader_init>
+ dalvik_system_PathClassLoader;
+ static constexpr ClassFromMethod<&java_lang_BootClassLoader_init> java_lang_BootClassLoader;
+ static constexpr ClassFromField<&java_lang_ClassLoader_parent> java_lang_ClassLoader;
static constexpr ClassFromField<&java_lang_Thread_daemon> java_lang_Thread;
static constexpr ClassFromField<&java_lang_ThreadGroup_groups> java_lang_ThreadGroup;
static constexpr ClassFromField<&java_lang_Throwable_cause> java_lang_Throwable;
diff --git a/test/ti-agent/jni_helper.h b/test/ti-agent/jni_helper.h
index 0cbc6341fc..f99e627338 100644
--- a/test/ti-agent/jni_helper.h
+++ b/test/ti-agent/jni_helper.h
@@ -61,7 +61,7 @@ inline bool JniThrowNullPointerException(JNIEnv* env, const char* msg) {
ScopedLocalRef<jclass> exc_class(env, env->FindClass("java/lang/NullPointerException"));
if (exc_class.get() == nullptr) {
- return -1;
+ return false;
}
return env->ThrowNew(exc_class.get(), msg) == JNI_OK;