Fix app image generation and checking with shared libraries.
We can now have multiple class loaders in an app image.
bug: 111174995
Test: dex2oat_test, test.py
Change-Id: Ie45c030b483efa78df2605fbcafb4e641b80c59a
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 1fa21d5..97a5f24 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -1069,7 +1069,8 @@
void RunTest(const char* class_loader_context,
const char* expected_classpath_key,
bool expected_success,
- bool use_second_source = false) {
+ bool use_second_source = false,
+ bool generate_image = false) {
std::string dex_location = GetUsedDexLocation();
std::string odex_location = GetUsedOatLocation();
@@ -1080,6 +1081,9 @@
if (class_loader_context != nullptr) {
extra_args.push_back(std::string("--class-loader-context=") + class_loader_context);
}
+ if (generate_image) {
+ extra_args.push_back(std::string("--app-image-file=") + GetUsedImageLocation());
+ }
auto check_oat = [expected_classpath_key](const OatFile& oat_file) {
ASSERT_TRUE(expected_classpath_key != nullptr);
const char* classpath = oat_file.GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey);
@@ -1104,6 +1108,10 @@
return GetOdexDir() + "/Context.odex";
}
+ std::string GetUsedImageLocation() {
+ return GetOdexDir() + "/Context.art";
+ }
+
const char* kEmptyClassPathKey = "PCL[]";
};
@@ -1213,6 +1221,55 @@
RunTest(context.c_str(), expected_classpath_key.c_str(), true);
}
+TEST_F(Dex2oatClassLoaderContextTest, ContextWithSharedLibraryAndImage) {
+ std::vector<std::unique_ptr<const DexFile>> dex_files1 = OpenTestDexFiles("Nested");
+ std::vector<std::unique_ptr<const DexFile>> dex_files2 = OpenTestDexFiles("MultiDex");
+
+ std::string context = "PCL[" + GetTestDexFileName("Nested") + "]" +
+ "{PCL[" + GetTestDexFileName("MultiDex") + "]}";
+ std::string expected_classpath_key = "PCL[" + CreateClassPathWithChecksums(dex_files1) + "]" +
+ "{PCL[" + CreateClassPathWithChecksums(dex_files2) + "]}";
+ RunTest(context.c_str(),
+ expected_classpath_key.c_str(),
+ /*expected_success=*/ true,
+ /*use_second_source=*/ false,
+ /*generate_image=*/ true);
+}
+
+TEST_F(Dex2oatClassLoaderContextTest, ContextWithSameSharedLibrariesAndImage) {
+ std::vector<std::unique_ptr<const DexFile>> dex_files1 = OpenTestDexFiles("Nested");
+ std::vector<std::unique_ptr<const DexFile>> dex_files2 = OpenTestDexFiles("MultiDex");
+
+ std::string context = "PCL[" + GetTestDexFileName("Nested") + "]" +
+ "{PCL[" + GetTestDexFileName("MultiDex") + "]" +
+ "#PCL[" + GetTestDexFileName("MultiDex") + "]}";
+ std::string expected_classpath_key = "PCL[" + CreateClassPathWithChecksums(dex_files1) + "]" +
+ "{PCL[" + CreateClassPathWithChecksums(dex_files2) + "]" +
+ "#PCL[" + CreateClassPathWithChecksums(dex_files2) + "]}";
+ RunTest(context.c_str(),
+ expected_classpath_key.c_str(),
+ /*expected_success=*/ true,
+ /*use_second_source=*/ false,
+ /*generate_image=*/ true);
+}
+
+TEST_F(Dex2oatClassLoaderContextTest, ContextWithSharedLibrariesDependenciesAndImage) {
+ std::vector<std::unique_ptr<const DexFile>> dex_files1 = OpenTestDexFiles("Nested");
+ std::vector<std::unique_ptr<const DexFile>> dex_files2 = OpenTestDexFiles("MultiDex");
+
+ std::string context = "PCL[" + GetTestDexFileName("Nested") + "]" +
+ "{PCL[" + GetTestDexFileName("MultiDex") + "]" +
+ "{PCL[" + GetTestDexFileName("Nested") + "]}}";
+ std::string expected_classpath_key = "PCL[" + CreateClassPathWithChecksums(dex_files1) + "]" +
+ "{PCL[" + CreateClassPathWithChecksums(dex_files2) + "]" +
+ "{PCL[" + CreateClassPathWithChecksums(dex_files1) + "]}}";
+ RunTest(context.c_str(),
+ expected_classpath_key.c_str(),
+ /*expected_success=*/ true,
+ /*use_second_source=*/ false,
+ /*generate_image=*/ true);
+}
+
class Dex2oatDeterminism : public Dex2oatTest {};
TEST_F(Dex2oatDeterminism, UnloadCompile) {