summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiakai Zhang <jiakaiz@google.com>2023-05-18 16:30:38 +0100
committerJiakai Zhang <jiakaiz@google.com>2023-05-22 00:35:55 +0100
commit79dae4e7479889de1eabed191e6e3fd39b1c0a06 (patch)
tree31d106a3d825d2f7cd58e5b9ea30eb942d95b9b4
parent821266fd404a681eae31c603de9c612016944f9a (diff)
downloadart-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.bp1
-rw-r--r--libdexfile/dex/art_dex_file_loader.cc1
-rw-r--r--libdexfile/dex/art_dex_file_loader_test.cc13
-rw-r--r--test/595-profile-saving/res/art-gtest-jars-Main.dexbin0 -> 736 bytes
-rw-r--r--test/595-profile-saving/src/Main.java30
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
new file mode 100644
index 0000000000..2747919a64
--- /dev/null
+++ b/test/595-profile-saving/res/art-gtest-jars-Main.dex
Binary files differ
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");