diff options
author | Jiakai Zhang <jiakaiz@google.com> | 2023-05-18 16:30:38 +0100 |
---|---|---|
committer | Jiakai Zhang <jiakaiz@google.com> | 2023-05-22 00:35:55 +0100 |
commit | 79dae4e7479889de1eabed191e6e3fd39b1c0a06 (patch) | |
tree | 31d106a3d825d2f7cd58e5b9ea30eb942d95b9b4 | |
parent | 821266fd404a681eae31c603de9c612016944f9a (diff) | |
download | art-79dae4e7479889de1eabed191e6e3fd39b1c0a06.tar.gz |
Fix ArtDexFileLoader::GetMultiDexChecksums to handle .dex files properly
Runtime::RegisterAppInfo relies on
ArtDexFileLoader::GetMultiDexChecksums to check if the input files have
dex code, but that method doesn't propertly return dex_locations if the
input is a .dex file. This issue caused profiles not to be written for
.dex files. This CL fixes it.
Bug: 282191456
Test: art/test.py -b --host -r -t 595-profile-saving
Test: m test-art-host-gtest-art_libdexfile_tests
(cherry picked from https://android-review.googlesource.com/q/commit:a11d08f3369f6ebd5a40c7e99499f84a6b111c53)
Merged-In: Ia8597fa9c7e7c7c9a82df0708fe0867216362423
Change-Id: Ia8597fa9c7e7c7c9a82df0708fe0867216362423
-rw-r--r-- | libdexfile/Android.bp | 1 | ||||
-rw-r--r-- | libdexfile/dex/art_dex_file_loader.cc | 1 | ||||
-rw-r--r-- | libdexfile/dex/art_dex_file_loader_test.cc | 13 | ||||
-rw-r--r-- | test/595-profile-saving/res/art-gtest-jars-Main.dex | bin | 0 -> 736 bytes | |||
-rw-r--r-- | test/595-profile-saving/src/Main.java | 30 |
5 files changed, 39 insertions, 6 deletions
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp index 79dd10c2da..dfeac98dff 100644 --- a/libdexfile/Android.bp +++ b/libdexfile/Android.bp @@ -295,6 +295,7 @@ art_cc_defaults { ":art-gtest-jars-MainEmptyUncompressed", ":art-gtest-jars-MultiDex", ":art-gtest-jars-Nested", + ":art-gtest-jars-VerifierDeps", ], header_libs: ["jni_headers"], static_libs: [ diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc index 8e86160320..ac52ca04e3 100644 --- a/libdexfile/dex/art_dex_file_loader.cc +++ b/libdexfile/dex/art_dex_file_loader.cc @@ -111,6 +111,7 @@ bool ArtDexFileLoader::GetMultiDexChecksums(const char* filename, } for (auto& dex_file : dex_files) { checksums->push_back(dex_file->GetHeader().checksum_); + dex_locations->push_back(dex_file->GetLocation()); } return true; } diff --git a/libdexfile/dex/art_dex_file_loader_test.cc b/libdexfile/dex/art_dex_file_loader_test.cc index 833e73b614..d8911ece78 100644 --- a/libdexfile/dex/art_dex_file_loader_test.cc +++ b/libdexfile/dex/art_dex_file_loader_test.cc @@ -143,6 +143,19 @@ TEST_F(ArtDexFileLoaderTest, GetMultiDexChecksumsEmptyZip) { EXPECT_EQ(checksums.size(), 0); } +TEST_F(ArtDexFileLoaderTest, GetMultiDexChecksumsDexFile) { + std::string error_msg; + std::vector<uint32_t> checksums; + std::vector<std::string> dex_locations; + std::string multidex_file = GetTestDexFileName("VerifierDeps"); // This is a .dex file. + EXPECT_TRUE(ArtDexFileLoader::GetMultiDexChecksums( + multidex_file.c_str(), &checksums, &dex_locations, &error_msg)) + << error_msg; + + EXPECT_EQ(dex_locations.size(), 1); + EXPECT_EQ(checksums.size(), 1); +} + TEST_F(ArtDexFileLoaderTest, ClassDefs) { std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested")); ASSERT_TRUE(raw.get() != nullptr); diff --git a/test/595-profile-saving/res/art-gtest-jars-Main.dex b/test/595-profile-saving/res/art-gtest-jars-Main.dex Binary files differnew file mode 100644 index 0000000000..2747919a64 --- /dev/null +++ b/test/595-profile-saving/res/art-gtest-jars-Main.dex diff --git a/test/595-profile-saving/src/Main.java b/test/595-profile-saving/src/Main.java index 31dc4d2148..3229b53d7d 100644 --- a/test/595-profile-saving/src/Main.java +++ b/test/595-profile-saving/src/Main.java @@ -25,6 +25,7 @@ public class Main { File file = null; File file2 = null; + File file3 = null; try { // Register `file2` with an empty jar. Even though `file2` is registered before `file`, the // runtime should not write bootclasspath methods to `file2`, and it should not even create @@ -46,17 +47,34 @@ public class Main { new String[] {codePath}, VMRuntime.CODE_PATH_TYPE_PRIMARY_APK); - // Test that the profile saves an app method with a profiling info. - Method appMethod = Main.class.getDeclaredMethod("testAddMethodToProfile", - File.class, Method.class); - testAddMethodToProfile(file, appMethod); + file3 = createTempFile(); + String dexPath = System.getenv("DEX_LOCATION") + "/res/art-gtest-jars-Main.dex"; + VMRuntime.registerAppInfo("test.app", + file3.getPath(), + file3.getPath(), + new String[] {dexPath}, + VMRuntime.CODE_PATH_TYPE_SPLIT_APK); // Delete the files so that we can check if the runtime creates them. The runtime should - // create `file` but not `file2`. + // create `file` and `file3` but not `file2`. file.delete(); file2.delete(); + file3.delete(); + + // Test that the runtime saves the profiling info of an app method in a .jar file. + Method appMethod = Main.class.getDeclaredMethod("testAddMethodToProfile", + File.class, Method.class); + testAddMethodToProfile(file, appMethod); + + // Test that the runtime saves the profiling info of an app method in a .dex file. + ClassLoader dexClassLoader = (ClassLoader) Class.forName("dalvik.system.PathClassLoader") + .getDeclaredConstructor(String.class, ClassLoader.class) + .newInstance(dexPath, null /* parent */); + Class<?> c = Class.forName("Main", true /* initialize */, dexClassLoader); + Method methodInDex = c.getMethod("main", (new String[0]).getClass()); + testAddMethodToProfile(file3, methodInDex); - // Test that the profile saves a boot class path method with a profiling info. + // Test that the runtime saves the profiling info of a bootclasspath method. Method bootMethod = File.class.getDeclaredMethod("exists"); if (bootMethod.getDeclaringClass().getClassLoader() != Object.class.getClassLoader()) { System.out.println("Class loader does not match boot class"); |