diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 105 |
1 files changed, 36 insertions, 69 deletions
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() { |