return ClassPathEntry(nullptr, nullptr);
}
-bool ClassLinker::FindClassInPathClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
- Thread* self,
- const char* descriptor,
- size_t hash,
- Handle<mirror::ClassLoader> class_loader,
- ObjPtr<mirror::Class>* result) {
+bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
+ Thread* self,
+ const char* descriptor,
+ size_t hash,
+ Handle<mirror::ClassLoader> class_loader,
+ ObjPtr<mirror::Class>* result) {
// Termination case: boot class-loader.
if (IsBootClassLoader(soa, class_loader.Get())) {
// The boot class loader, search the boot class path.
// Unsupported class-loader?
if (soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader) !=
class_loader->GetClass()) {
- *result = nullptr;
- return false;
+ // PathClassLoader is the most common case, so it's the one we check first. For secondary dex
+ // files, we also check DexClassLoader here.
+ if (soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DexClassLoader) !=
+ class_loader->GetClass()) {
+ *result = nullptr;
+ return false;
+ }
}
// Handles as RegisterDexFile may allocate dex caches (and cause thread suspension).
StackHandleScope<4> hs(self);
Handle<mirror::ClassLoader> h_parent(hs.NewHandle(class_loader->GetParent()));
- bool recursive_result = FindClassInPathClassLoader(soa, self, descriptor, hash, h_parent, result);
+ bool recursive_result = FindClassInBaseDexClassLoader(soa,
+ self,
+ descriptor,
+ hash,
+ h_parent,
+ result);
if (!recursive_result) {
// Something wrong up the chain.
} else {
ScopedObjectAccessUnchecked soa(self);
ObjPtr<mirror::Class> cp_klass;
- if (FindClassInPathClassLoader(soa, self, descriptor, hash, class_loader, &cp_klass)) {
+ if (FindClassInBaseDexClassLoader(soa, self, descriptor, hash, class_loader, &cp_klass)) {
// The chain was understood. So the value in cp_klass is either the class we were looking
// for, or not found.
if (cp_klass != nullptr) {
return cp_klass.Ptr();
}
- // TODO: We handle the boot classpath loader in FindClassInPathClassLoader. Try to unify this
- // and the branch above. TODO: throw the right exception here.
+ // TODO: We handle the boot classpath loader in FindClassInBaseDexClassLoader. Try to unify
+ // this and the branch above. TODO: throw the right exception here.
// We'll let the Java-side rediscover all this and throw the exception with the right stack
// trace.
void FixupStaticTrampolines(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
- // Finds a class in the path class loader, loading it if necessary without using JNI. Hash
+ // Finds a class in a Path- or DexClassLoader, loading it if necessary without using JNI. Hash
// function is supposed to be ComputeModifiedUtf8Hash(descriptor). Returns true if the
// class-loader chain could be handled, false otherwise, i.e., a non-supported class-loader
// was encountered while walking the parent chain (currently only BootClassLoader and
// PathClassLoader are supported).
- bool FindClassInPathClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
- Thread* self,
- const char* descriptor,
- size_t hash,
- Handle<mirror::ClassLoader> class_loader,
- ObjPtr<mirror::Class>* result)
+ bool FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
+ Thread* self,
+ const char* descriptor,
+ size_t hash,
+ Handle<mirror::ClassLoader> class_loader,
+ ObjPtr<mirror::Class>* result)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!dex_lock_);
friend struct CompilationHelper; // For Compile in ImageTest.
friend class ImageDumper; // for DexLock
friend class ImageWriter; // for GetClassRoots
- friend class VMClassLoader; // for LookupClass and FindClassInPathClassLoader.
+ friend class VMClassLoader; // for LookupClass and FindClassInBaseDexClassLoader.
friend class JniCompilerTest; // for GetRuntimeQuickGenericJniStub
friend class JniInternalTest; // for GetRuntimeQuickGenericJniStub
ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName); // for DexLock, and RegisterDexFileLocked
Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> result;
- if (cl->FindClassInPathClassLoader(soa, self, descriptor, hash, class_loader, &result)) {
+ if (cl->FindClassInBaseDexClassLoader(soa, self, descriptor, hash, class_loader, &result)) {
return result;
}
return nullptr;
jclass WellKnownClasses::dalvik_annotation_optimization_CriticalNative;
jclass WellKnownClasses::dalvik_annotation_optimization_FastNative;
jclass WellKnownClasses::dalvik_system_BaseDexClassLoader;
+jclass WellKnownClasses::dalvik_system_DexClassLoader;
jclass WellKnownClasses::dalvik_system_DexFile;
jclass WellKnownClasses::dalvik_system_DexPathList;
jclass WellKnownClasses::dalvik_system_DexPathList__Element;
CacheClass(env, "dalvik/annotation/optimization/CriticalNative");
dalvik_annotation_optimization_FastNative = CacheClass(env, "dalvik/annotation/optimization/FastNative");
dalvik_system_BaseDexClassLoader = CacheClass(env, "dalvik/system/BaseDexClassLoader");
+ dalvik_system_DexClassLoader = CacheClass(env, "dalvik/system/DexClassLoader");
dalvik_system_DexFile = CacheClass(env, "dalvik/system/DexFile");
dalvik_system_DexPathList = CacheClass(env, "dalvik/system/DexPathList");
dalvik_system_DexPathList__Element = CacheClass(env, "dalvik/system/DexPathList$Element");
static jclass dalvik_annotation_optimization_CriticalNative;
static jclass dalvik_annotation_optimization_FastNative;
static jclass dalvik_system_BaseDexClassLoader;
+ static jclass dalvik_system_DexClassLoader;
static jclass dalvik_system_DexFile;
static jclass dalvik_system_DexPathList;
static jclass dalvik_system_DexPathList__Element;