diff options
author | 2022-10-18 09:49:00 +0000 | |
---|---|---|
committer | 2022-10-18 15:58:58 +0000 | |
commit | 5be5ce773a683439792c799827fcef2fea0cf157 (patch) | |
tree | 0010a7309d5b8b955f5418515cd3fd54aa32a984 | |
parent | b47fc9709ca8d36c44dca81dcb8cc211e933f082 (diff) |
Reland "Change well known `ClassLoader` fields to `ArtField*`."
This reverts commit 839193ee2031d28aac2ce16c4b76ad40531b07cc.
Reason for revert: Reland with a fix - make CompilerDriver
reponsible for initializing required `ClassLoader` classes
for boot image.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Manually run Golem benchmark ArrayListStress.
Bug: 253570082
Change-Id: I2ddb70566352f8728f089b3a6c58473270240e25
-rw-r--r-- | dex2oat/driver/compiler_driver.cc | 77 | ||||
-rw-r--r-- | dex2oat/linker/image_writer.cc | 4 | ||||
-rw-r--r-- | openjdkjvmti/ti_class_loader-inl.h | 4 | ||||
-rw-r--r-- | openjdkjvmti/ti_class_loader.cc | 6 | ||||
-rw-r--r-- | runtime/class_linker.cc | 27 | ||||
-rw-r--r-- | runtime/class_loader_context.cc | 24 | ||||
-rw-r--r-- | runtime/class_loader_context_test.cc | 12 | ||||
-rw-r--r-- | runtime/class_loader_utils.h | 12 | ||||
-rw-r--r-- | runtime/runtime_callbacks_test.cc | 1 | ||||
-rw-r--r-- | runtime/well_known_classes.cc | 72 | ||||
-rw-r--r-- | runtime/well_known_classes.h | 17 |
11 files changed, 168 insertions, 88 deletions
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc index 1cf7e2ffa8..fc94957704 100644 --- a/dex2oat/driver/compiler_driver.cc +++ b/dex2oat/driver/compiler_driver.cc @@ -87,6 +87,7 @@ #include "verifier/class_verifier.h" #include "verifier/verifier_deps.h" #include "verifier/verifier_enums.h" +#include "well_known_classes.h" namespace art { @@ -1010,13 +1011,67 @@ class RecordImageClassesVisitor : public ClassVisitor { HashSet<std::string>* const image_classes_; }; -// Add classes which contain intrinsics methods to the list of image classes. -static void AddClassesContainingIntrinsics(/* out */ HashSet<std::string>* image_classes) { -#define ADD_INTRINSIC_OWNER_CLASS(_, __, ___, ____, _____, ClassName, ______, _______) \ - image_classes->insert(ClassName); +// Verify that classes which contain intrinsics methods are in the list of image classes. +static void VerifyClassesContainingIntrinsicsAreImageClasses(HashSet<std::string>* image_classes) { +#define CHECK_INTRINSIC_OWNER_CLASS(_, __, ___, ____, _____, ClassName, ______, _______) \ + CHECK(image_classes->find(std::string_view(ClassName)) != image_classes->end()); - INTRINSICS_LIST(ADD_INTRINSIC_OWNER_CLASS) -#undef ADD_INTRINSIC_OWNER_CLASS + INTRINSICS_LIST(CHECK_INTRINSIC_OWNER_CLASS) +#undef CHECK_INTRINSIC_OWNER_CLASS +} + +// We need to put classes required by app class loaders to the boot image, +// otherwise we would not be able to store app class loaders in app images. +static void AddClassLoaderClasses(/* out */ HashSet<std::string>* image_classes) { + ScopedObjectAccess soa(Thread::Current()); + // Well known classes have been loaded and shall be added to image classes + // by the `RecordImageClassesVisitor`. However, there are fields with array + // types which we need to add to the image classes explicitly. + ArtField* class_loader_array_fields[] = { + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders, + // BaseDexClassLoader.sharedLibraryLoadersAfter has the same array type as above. + WellKnownClasses::dalvik_system_DexPathList_dexElements, + }; + for (ArtField* field : class_loader_array_fields) { + const char* field_type_descriptor = field->GetTypeDescriptor(); + DCHECK_EQ(field_type_descriptor[0], '['); + image_classes->insert(field_type_descriptor); + } +} + +static void VerifyClassLoaderClassesAreImageClasses(/* out */ HashSet<std::string>* image_classes) { + ScopedObjectAccess soa(Thread::Current()); + jclass class_loader_classes[] = { + WellKnownClasses::dalvik_system_BaseDexClassLoader, + WellKnownClasses::dalvik_system_DelegateLastClassLoader, + WellKnownClasses::dalvik_system_DexClassLoader, + WellKnownClasses::dalvik_system_DexFile, + WellKnownClasses::dalvik_system_DexPathList, + WellKnownClasses::dalvik_system_DexPathList__Element, + WellKnownClasses::dalvik_system_InMemoryDexClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::java_lang_BootClassLoader, + WellKnownClasses::java_lang_ClassLoader, + }; + for (jclass klass : class_loader_classes) { + std::string temp; + std::string_view descriptor = soa.Decode<mirror::Class>(klass)->GetDescriptor(&temp); + CHECK(image_classes->find(descriptor) != image_classes->end()); + } + ArtField* class_loader_fields[] = { + WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList, + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders, + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter, + WellKnownClasses::dalvik_system_DexFile_cookie, + WellKnownClasses::dalvik_system_DexFile_fileName, + WellKnownClasses::dalvik_system_DexPathList_dexElements, + WellKnownClasses::dalvik_system_DexPathList__Element_dexFile, + WellKnownClasses::java_lang_ClassLoader_parent, + }; + for (ArtField* field : class_loader_fields) { + std::string_view field_type_descriptor = field->GetTypeDescriptor(); + CHECK(image_classes->find(field_type_descriptor) != image_classes->end()); + } } // Make a list of descriptors for classes to include in the image @@ -1030,7 +1085,10 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings, TimingLogger::ScopedTiming t("LoadImageClasses", timings); if (GetCompilerOptions().IsBootImage()) { - AddClassesContainingIntrinsics(image_classes); + // Image classes of intrinsics are loaded and shall be added + // to image classes by the `RecordImageClassesVisitor`. + // Add classes needed for storing class loaders in app images. + AddClassLoaderClasses(image_classes); } // Make a first pass to load all classes explicitly listed in the file @@ -1101,6 +1159,11 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings, RecordImageClassesVisitor visitor(image_classes); class_linker->VisitClasses(&visitor); + if (kIsDebugBuild && GetCompilerOptions().IsBootImage()) { + VerifyClassesContainingIntrinsicsAreImageClasses(image_classes); + VerifyClassLoaderClassesAreImageClasses(image_classes); + } + if (GetCompilerOptions().IsBootImage()) { CHECK(!image_classes->empty()); } diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc index 483165a762..a8bd965be8 100644 --- a/dex2oat/linker/image_writer.cc +++ b/dex2oat/linker/image_writer.cc @@ -273,7 +273,7 @@ static void ClearDexFileCookies() REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(obj != nullptr); Class* klass = obj->GetClass(); if (klass == WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DexFile)) { - ArtField* field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); + ArtField* field = WellKnownClasses::dalvik_system_DexFile_cookie; // Null out the cookie to enable determinism. b/34090128 field->SetObject</*kTransactionActive*/false>(obj, nullptr); } @@ -2229,7 +2229,7 @@ void ImageWriter::LayoutHelper::VerifyImageBinSlotsAssigned() { // Note: The app class loader is used only for checking against the runtime // class loader, the dex file cookie is cleared and therefore we do not need // to run the finalizer even if we implement app image objects collection. - ArtField* field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); + ArtField* field = WellKnownClasses::dalvik_system_DexFile_cookie; CHECK(field->GetObject<kWithoutReadBarrier>(ref) == nullptr); return; } diff --git a/openjdkjvmti/ti_class_loader-inl.h b/openjdkjvmti/ti_class_loader-inl.h index 29ea684779..f6b012620b 100644 --- a/openjdkjvmti/ti_class_loader-inl.h +++ b/openjdkjvmti/ti_class_loader-inl.h @@ -48,8 +48,8 @@ inline void ClassLoaderHelper::VisitDexFileObjects(art::Thread* self, art::Handle<art::mirror::ClassLoader> loader, const Visitor& visitor) { art::StackHandleScope<1> hs(self); - art::ArtField* element_dex_file_field = art::jni::DecodeArtField( - art::WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + art::ArtField* element_dex_file_field = + art::WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; art::Handle<art::mirror::ObjectArray<art::mirror::Object>> dex_elements_list( hs.NewHandle(GetDexElementList(self, loader))); diff --git a/openjdkjvmti/ti_class_loader.cc b/openjdkjvmti/ti_class_loader.cc index cf825344a6..41b8771979 100644 --- a/openjdkjvmti/ti_class_loader.cc +++ b/openjdkjvmti/ti_class_loader.cc @@ -145,10 +145,10 @@ art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> ClassLoaderHelper::Ge art::WellKnownClasses::dalvik_system_BaseDexClassLoader)->AsClass())); // Get all the ArtFields so we can look in the BaseDexClassLoader - art::ArtField* path_list_field = art::jni::DecodeArtField( - art::WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList); + art::ArtField* path_list_field = + art::WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList; art::ArtField* dex_path_list_element_field = - art::jni::DecodeArtField(art::WellKnownClasses::dalvik_system_DexPathList_dexElements); + art::WellKnownClasses::dalvik_system_DexPathList_dexElements; // Check if loader is a BaseDexClassLoader art::Handle<art::mirror::Class> loader_class(hs.NewHandle(loader->GetClass())); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 663b2b9c37..47f332526e 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2681,8 +2681,7 @@ bool ClassLinker::FindClassInSharedLibraries(ScopedObjectAccessAlreadyRunnable& size_t hash, Handle<mirror::ClassLoader> class_loader, /*out*/ ObjPtr<mirror::Class>* result) { - ArtField* field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; return FindClassInSharedLibrariesHelper(soa, self, descriptor, hash, class_loader, field, result); } @@ -2718,8 +2717,7 @@ bool ClassLinker::FindClassInSharedLibrariesAfter(ScopedObjectAccessAlreadyRunna size_t hash, Handle<mirror::ClassLoader> class_loader, /*out*/ ObjPtr<mirror::Class>* result) { - ArtField* field = jni::DecodeArtField( - WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; return FindClassInSharedLibrariesHelper(soa, self, descriptor, hash, class_loader, field, result); } @@ -10039,8 +10037,7 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( StackHandleScope<5> hs(self); - ArtField* dex_elements_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements); + ArtField* dex_elements_field = WellKnownClasses::dalvik_system_DexPathList_dexElements; Handle<mirror::Class> dex_elements_class(hs.NewHandle(dex_elements_field->ResolveType())); DCHECK(dex_elements_class != nullptr); @@ -10052,14 +10049,13 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( Handle<mirror::Class> h_dex_element_class = hs.NewHandle(dex_elements_class->GetComponentType()); - ArtField* element_file_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + ArtField* element_file_field = WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; DCHECK_EQ(h_dex_element_class.Get(), element_file_field->GetDeclaringClass()); - ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); + ArtField* cookie_field = WellKnownClasses::dalvik_system_DexFile_cookie; DCHECK_EQ(cookie_field->GetDeclaringClass(), element_file_field->LookupResolvedType()); - ArtField* file_name_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_fileName); + ArtField* file_name_field = WellKnownClasses::dalvik_system_DexFile_fileName; DCHECK_EQ(file_name_field->GetDeclaringClass(), element_file_field->LookupResolvedType()); // Fill the elements array. @@ -10131,15 +10127,13 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( ObjPtr<mirror::ClassLoader>::DownCast(loader_class->AllocObject(self))); DCHECK(h_class_loader != nullptr); // Set DexPathList. - ArtField* path_list_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList); + ArtField* path_list_field = WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList; DCHECK(path_list_field != nullptr); path_list_field->SetObject<false>(h_class_loader.Get(), h_dex_path_list.Get()); // Make a pretend boot-classpath. // TODO: Should we scan the image? - ArtField* const parent_field = - jni::DecodeArtField(WellKnownClasses::java_lang_ClassLoader_parent); + ArtField* const parent_field = WellKnownClasses::java_lang_ClassLoader_parent; DCHECK(parent_field != nullptr); if (parent_loader.Get() == nullptr) { ScopedObjectAccessUnchecked soa(self); @@ -10151,13 +10145,12 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( } ArtField* shared_libraries_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; DCHECK(shared_libraries_field != nullptr); shared_libraries_field->SetObject<false>(h_class_loader.Get(), shared_libraries.Get()); ArtField* shared_libraries_after_field = - jni::DecodeArtField( - WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter); + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; DCHECK(shared_libraries_after_field != nullptr); shared_libraries_after_field->SetObject<false>(h_class_loader.Get(), shared_libraries_after.Get()); diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc index 2ab905ba05..2efa2d6bc6 100644 --- a/runtime/class_loader_context.cc +++ b/runtime/class_loader_context.cc @@ -1028,13 +1028,10 @@ static bool CollectDexFilesFromSupportedClassLoader(ScopedObjectAccessAlreadyRun // All supported class loaders inherit from BaseDexClassLoader. // We need to get the DexPathList and loop through it. - ArtField* const cookie_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); - ArtField* const dex_file_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + ArtField* const cookie_field = WellKnownClasses::dalvik_system_DexFile_cookie; + ArtField* const dex_file_field = WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; ObjPtr<mirror::Object> dex_path_list = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)-> - GetObject(class_loader.Get()); + WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList->GetObject(class_loader.Get()); CHECK(cookie_field != nullptr); CHECK(dex_file_field != nullptr); if (dex_path_list == nullptr) { @@ -1044,8 +1041,7 @@ static bool CollectDexFilesFromSupportedClassLoader(ScopedObjectAccessAlreadyRun } // DexPathList has an array dexElements of Elements[] which each contain a dex file. ObjPtr<mirror::Object> dex_elements_obj = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)-> - GetObject(dex_path_list); + WellKnownClasses::dalvik_system_DexPathList_dexElements->GetObject(dex_path_list); // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look // at the mCookie which is a DexFile vector. if (dex_elements_obj == nullptr) { @@ -1081,10 +1077,8 @@ static bool GetDexFilesFromDexElementsArray( std::vector<const DexFile*>* out_dex_files) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(dex_elements != nullptr); - ArtField* const cookie_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); - ArtField* const dex_file_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + ArtField* const cookie_field = WellKnownClasses::dalvik_system_DexFile_cookie; + ArtField* const dex_file_field = WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; const ObjPtr<mirror::Class> element_class = soa.Decode<mirror::Class>( WellKnownClasses::dalvik_system_DexPathList__Element); const ObjPtr<mirror::Class> dexfile_class = soa.Decode<mirror::Class>( @@ -1198,8 +1192,7 @@ bool ClassLoaderContext::CreateInfoFromClassLoader( // Add the shared libraries. StackHandleScope<5> hs(Thread::Current()); - ArtField* field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader.Get()); if (raw_shared_libraries != nullptr) { Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries = @@ -1217,8 +1210,7 @@ bool ClassLoaderContext::CreateInfoFromClassLoader( } } } - ArtField* field2 = jni::DecodeArtField( - WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter); + ArtField* field2 = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; ObjPtr<mirror::Object> raw_shared_libraries_after = field2->GetObject(class_loader.Get()); if (raw_shared_libraries_after != nullptr) { Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_after = diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc index 598670be82..9d3ceb2a70 100644 --- a/runtime/class_loader_context_test.cc +++ b/runtime/class_loader_context_test.cc @@ -839,8 +839,7 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) { class_loader_1_dex_files); // Verify the shared libraries. - ArtField* field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); ASSERT_TRUE(raw_shared_libraries != nullptr); @@ -924,8 +923,7 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) class_loader_1_dex_files); // Verify its shared library. - ArtField* field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); ASSERT_TRUE(raw_shared_libraries != nullptr); @@ -1024,8 +1022,7 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) class_loader_1_dex_files); // Verify its shared library. - ArtField* field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); ASSERT_TRUE(raw_shared_libraries != nullptr); @@ -1139,8 +1136,7 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) { class_loader_1_dex_files); // Verify its shared library. - ArtField* field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); ASSERT_TRUE(raw_shared_libraries != nullptr); diff --git a/runtime/class_loader_utils.h b/runtime/class_loader_utils.h index c7773709bf..aabc4ca91d 100644 --- a/runtime/class_loader_utils.h +++ b/runtime/class_loader_utils.h @@ -82,13 +82,11 @@ inline RetType VisitClassLoaderDexElements(ScopedObjectAccessAlreadyRunnable& so REQUIRES_SHARED(Locks::mutator_lock_) { Thread* self = soa.Self(); ObjPtr<mirror::Object> dex_path_list = - jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)-> - GetObject(class_loader.Get()); + WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList->GetObject(class_loader.Get()); if (dex_path_list != nullptr) { // DexPathList has an array dexElements of Elements[] which each contain a dex file. ObjPtr<mirror::Object> dex_elements_obj = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)-> - GetObject(dex_path_list); + WellKnownClasses::dalvik_system_DexPathList_dexElements->GetObject(dex_path_list); // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look // at the mCookie which is a DexFile vector. if (dex_elements_obj != nullptr) { @@ -122,10 +120,8 @@ inline RetType VisitClassLoaderDexFiles(ScopedObjectAccessAlreadyRunnable& soa, Visitor fn, RetType defaultReturn) REQUIRES_SHARED(Locks::mutator_lock_) { - ArtField* const cookie_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); - ArtField* const dex_file_field = - jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + ArtField* const cookie_field = WellKnownClasses::dalvik_system_DexFile_cookie; + ArtField* const dex_file_field = WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; if (dex_file_field == nullptr || cookie_field == nullptr) { return defaultReturn; } diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc index 7f64721a4f..40194cbf00 100644 --- a/runtime/runtime_callbacks_test.cc +++ b/runtime/runtime_callbacks_test.cc @@ -303,6 +303,7 @@ class ClassLoadCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest { TEST_F(ClassLoadCallbackRuntimeCallbacksTest, ClassLoadCallback) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); + cb_.data.clear(); // Clear class loading records from `LoadDex()`, if any. VariableSizedHandleScope hs(soa.Self()); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( soa.Decode<mirror::ClassLoader>(jclass_loader))); diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 888a2ed43c..615028acd1 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -132,16 +132,16 @@ jmethodID WellKnownClasses::libcore_reflect_AnnotationMember_init; jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast; jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch; -jfieldID WellKnownClasses::dalvik_system_DexFile_cookie; -jfieldID WellKnownClasses::dalvik_system_DexFile_fileName; -jfieldID WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList; -jfieldID WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; -jfieldID WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; -jfieldID WellKnownClasses::dalvik_system_DexPathList_dexElements; -jfieldID WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; +ArtField* WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList; +ArtField* WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; +ArtField* WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; +ArtField* WellKnownClasses::dalvik_system_DexFile_cookie; +ArtField* WellKnownClasses::dalvik_system_DexFile_fileName; +ArtField* WellKnownClasses::dalvik_system_DexPathList_dexElements; +ArtField* WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; jfieldID WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer; jfieldID WellKnownClasses::java_io_FileDescriptor_descriptor; -jfieldID WellKnownClasses::java_lang_ClassLoader_parent; +ArtField* WellKnownClasses::java_lang_ClassLoader_parent; jfieldID WellKnownClasses::java_lang_Thread_parkBlocker; jfieldID WellKnownClasses::java_lang_Thread_daemon; jfieldID WellKnownClasses::java_lang_Thread_group; @@ -213,6 +213,23 @@ static jfieldID CacheField(JNIEnv* env, jclass c, bool is_static, return fid; } +static ArtField* CacheField(ObjPtr<mirror::Class> klass, + bool is_static, + const char* name, + const char* signature) REQUIRES_SHARED(Locks::mutator_lock_) { + ArtField* field = is_static + ? klass->FindDeclaredStaticField(name, signature) + : klass->FindDeclaredInstanceField(name, signature); + if (UNLIKELY(field == nullptr)) { + std::ostringstream os; + klass->DumpClass(os, mirror::Class::kDumpClassFullDetail); + LOG(FATAL) << "Couldn't find " << (is_static ? "static" : "instance") << " field \"" + << name << "\" with signature \"" << signature << "\": " << os.str(); + UNREACHABLE(); + } + return field; +} + static jmethodID CacheMethod(JNIEnv* env, jclass c, bool is_static, const char* name, const char* signature) { jmethodID mid; @@ -401,6 +418,9 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { hiddenapi::ScopedHiddenApiEnforcementPolicySetting hiddenapi_exemption( hiddenapi::EnforcementPolicy::kDisabled); + Thread* self = Thread::Current(); + ScopedObjectAccess soa(self); + dalvik_system_BaseDexClassLoader_getLdLibraryPath = CacheMethod(env, dalvik_system_BaseDexClassLoader, false, "getLdLibraryPath", "()Ljava/lang/String;"); dalvik_system_VMRuntime_runFinalization = CacheMethod(env, dalvik_system_VMRuntime, true, "runFinalization", "(J)V"); dalvik_system_VMRuntime_hiddenApiUsed = CacheMethod(env, dalvik_system_VMRuntime, true, "hiddenApiUsed", "(ILjava/lang/String;Ljava/lang/String;IZ)V"); @@ -435,20 +455,38 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { org_apache_harmony_dalvik_ddmc_DdmServer_broadcast = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "broadcast", "(I)V"); org_apache_harmony_dalvik_ddmc_DdmServer_dispatch = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;"); - dalvik_system_BaseDexClassLoader_pathList = CacheField(env, dalvik_system_BaseDexClassLoader, false, "pathList", "Ldalvik/system/DexPathList;"); - dalvik_system_BaseDexClassLoader_sharedLibraryLoaders = CacheField(env, dalvik_system_BaseDexClassLoader, false, "sharedLibraryLoaders", "[Ljava/lang/ClassLoader;"); - dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter = CacheField(env, dalvik_system_BaseDexClassLoader, false, "sharedLibraryLoadersAfter", "[Ljava/lang/ClassLoader;"); - dalvik_system_DexFile_cookie = CacheField(env, dalvik_system_DexFile, false, "mCookie", "Ljava/lang/Object;"); - dalvik_system_DexFile_fileName = CacheField(env, dalvik_system_DexFile, false, "mFileName", "Ljava/lang/String;"); - dalvik_system_DexPathList_dexElements = CacheField(env, dalvik_system_DexPathList, false, "dexElements", "[Ldalvik/system/DexPathList$Element;"); - dalvik_system_DexPathList__Element_dexFile = CacheField(env, dalvik_system_DexPathList__Element, false, "dexFile", "Ldalvik/system/DexFile;"); + // TODO: There should be no thread suspension when searching for fields and methods. Enable this + // assertion when all well known fields and methods are converted to `ArtField*` and `ArtMethod*`. + // ScopedAssertNoThreadSuspension sants(__FUNCTION__); + + 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;"); + dalvik_system_BaseDexClassLoader_sharedLibraryLoaders = CacheField( + d_s_bdcl, /*is_static=*/ false, "sharedLibraryLoaders", "[Ljava/lang/ClassLoader;"); + dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter = CacheField( + d_s_bdcl, /*is_static=*/ false, "sharedLibraryLoadersAfter", "[Ljava/lang/ClassLoader;"); + ObjPtr<mirror::Class> d_s_df = soa.Decode<mirror::Class>(dalvik_system_DexFile); + dalvik_system_DexFile_cookie = CacheField( + d_s_df, /*is_static=*/ false, "mCookie", "Ljava/lang/Object;"); + dalvik_system_DexFile_fileName = CacheField( + d_s_df, /*is_static=*/ false, "mFileName", "Ljava/lang/String;"); + ObjPtr<mirror::Class> d_s_dpl = soa.Decode<mirror::Class>(dalvik_system_DexPathList); + dalvik_system_DexPathList_dexElements = CacheField( + d_s_dpl, /*is_static=*/ false, "dexElements", "[Ldalvik/system/DexPathList$Element;"); + ObjPtr<mirror::Class> d_s_dpl_e = soa.Decode<mirror::Class>(dalvik_system_DexPathList__Element); + dalvik_system_DexPathList__Element_dexFile = CacheField( + d_s_dpl_e, /*is_static=*/ false, "dexFile", "Ldalvik/system/DexFile;"); + dalvik_system_VMRuntime_nonSdkApiUsageConsumer = CacheField(env, dalvik_system_VMRuntime, true, "nonSdkApiUsageConsumer", "Ljava/util/function/Consumer;"); ScopedLocalRef<jclass> java_io_FileDescriptor(env, env->FindClass("java/io/FileDescriptor")); java_io_FileDescriptor_descriptor = CacheField(env, java_io_FileDescriptor.get(), false, "descriptor", "I"); - java_lang_ClassLoader_parent = - CacheField(env, java_lang_ClassLoader, false, "parent", "Ljava/lang/ClassLoader;"); + 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;"); + java_lang_Thread_parkBlocker = CacheField(env, java_lang_Thread, false, "parkBlocker", "Ljava/lang/Object;"); java_lang_Thread_daemon = CacheField(env, java_lang_Thread, false, "daemon", "Z"); diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index f575317105..893a50ecc6 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -23,6 +23,7 @@ namespace art { +class ArtField; class ArtMethod; namespace mirror { @@ -145,16 +146,16 @@ struct WellKnownClasses { static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_broadcast; static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_dispatch; - static jfieldID dalvik_system_BaseDexClassLoader_pathList; - static jfieldID dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; - static jfieldID dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; - static jfieldID dalvik_system_DexFile_cookie; - static jfieldID dalvik_system_DexFile_fileName; - static jfieldID dalvik_system_DexPathList_dexElements; - static jfieldID dalvik_system_DexPathList__Element_dexFile; + static ArtField* dalvik_system_BaseDexClassLoader_pathList; + static ArtField* dalvik_system_BaseDexClassLoader_sharedLibraryLoaders; + static ArtField* dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter; + static ArtField* dalvik_system_DexFile_cookie; + static ArtField* dalvik_system_DexFile_fileName; + static ArtField* dalvik_system_DexPathList_dexElements; + static ArtField* dalvik_system_DexPathList__Element_dexFile; static jfieldID dalvik_system_VMRuntime_nonSdkApiUsageConsumer; static jfieldID java_io_FileDescriptor_descriptor; - static jfieldID java_lang_ClassLoader_parent; + static ArtField* java_lang_ClassLoader_parent; static jfieldID java_lang_Thread_parkBlocker; static jfieldID java_lang_Thread_daemon; static jfieldID java_lang_Thread_group; |