Change well known class loader methods to `ArtMethod*`.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: atest CtsJdwpTestCases
Change-Id: I7b94a481304f8899bcb828ed5875fe165dd90dda
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6480dfd..a421461 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1141,6 +1141,13 @@
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 @@
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 @@
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 @@
"%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 @@
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 @@
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 @@
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() {