diff options
Diffstat (limited to 'dex2oat/dex2oat_test.cc')
| -rw-r--r-- | dex2oat/dex2oat_test.cc | 97 |
1 files changed, 88 insertions, 9 deletions
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index b79050e9d0..e7277bceae 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -63,6 +63,7 @@ class Dex2oatTest : public Dex2oatEnvironmentTest { oat_file.reset(OS::CreateEmptyFile(odex_location.c_str())); CHECK(oat_file != nullptr) << odex_location; args.push_back("--oat-fd=" + std::to_string(oat_file->Fd())); + args.push_back("--oat-location=" + odex_location); } else { args.push_back("--oat-file=" + odex_location); } @@ -583,13 +584,16 @@ class Dex2oatLayoutTest : public Dex2oatTest { // Emits a profile with a single dex file with the given location and a single class index of 1. void GenerateProfile(const std::string& test_profile, const std::string& dex_location, + size_t num_classes, uint32_t checksum) { int profile_test_fd = open(test_profile.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); CHECK_GE(profile_test_fd, 0); ProfileCompilationInfo info; std::string profile_key = ProfileCompilationInfo::GetProfileDexFileKey(dex_location); - info.AddClassIndex(profile_key, checksum, dex::TypeIndex(1)); + for (size_t i = 0; i < num_classes; ++i) { + info.AddClassIndex(profile_key, checksum, dex::TypeIndex(1 + i)); + } bool result = info.Save(profile_test_fd); close(profile_test_fd); ASSERT_TRUE(result); @@ -597,7 +601,9 @@ class Dex2oatLayoutTest : public Dex2oatTest { void CompileProfileOdex(const std::string& dex_location, const std::string& odex_location, + const std::string& app_image_file_name, bool use_fd, + size_t num_profile_classes, const std::vector<std::string>& extra_args = {}) { const std::string profile_location = GetScratchDir() + "/primary.prof"; const char* location = dex_location.c_str(); @@ -606,33 +612,86 @@ class Dex2oatLayoutTest : public Dex2oatTest { ASSERT_TRUE(DexFile::Open(location, location, true, &error_msg, &dex_files)); EXPECT_EQ(dex_files.size(), 1U); std::unique_ptr<const DexFile>& dex_file = dex_files[0]; - GenerateProfile(profile_location, dex_location, dex_file->GetLocationChecksum()); + GenerateProfile(profile_location, + dex_location, + num_profile_classes, + dex_file->GetLocationChecksum()); std::vector<std::string> copy(extra_args); copy.push_back("--profile-file=" + profile_location); + std::unique_ptr<File> app_image_file; + if (!app_image_file_name.empty()) { + if (use_fd) { + app_image_file.reset(OS::CreateEmptyFile(app_image_file_name.c_str())); + copy.push_back("--app-image-fd=" + std::to_string(app_image_file->Fd())); + } else { + copy.push_back("--app-image-file=" + app_image_file_name); + } + } GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeedProfile, copy, /* expect_success */ true, use_fd); + if (app_image_file != nullptr) { + ASSERT_EQ(app_image_file->FlushCloseOrErase(), 0) << "Could not flush and close art file"; + } } - void RunTest() { + uint64_t GetImageSize(const std::string& image_file_name) { + EXPECT_FALSE(image_file_name.empty()); + std::unique_ptr<File> file(OS::OpenFileForReading(image_file_name.c_str())); + CHECK(file != nullptr); + ImageHeader image_header; + const bool success = file->ReadFully(&image_header, sizeof(image_header)); + CHECK(success); + CHECK(image_header.IsValid()); + ReaderMutexLock mu(Thread::Current(), *Locks::mutator_lock_); + return image_header.GetImageSize(); + } + + void RunTest(bool app_image) { std::string dex_location = GetScratchDir() + "/DexNoOat.jar"; std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex"; + std::string app_image_file = app_image ? (GetOdexDir() + "/DexOdexNoOat.art"): ""; Copy(GetDexSrc2(), dex_location); - CompileProfileOdex(dex_location, odex_location, /* use_fd */ false); - + uint64_t image_file_empty_profile = 0; + if (app_image) { + CompileProfileOdex(dex_location, + odex_location, + app_image_file, + /* use_fd */ false, + /* num_profile_classes */ 0); + CheckValidity(); + ASSERT_TRUE(success_); + // Don't check the result since CheckResult relies on the class being in the profile. + image_file_empty_profile = GetImageSize(app_image_file); + EXPECT_GT(image_file_empty_profile, 0u); + } + + // Small profile. + CompileProfileOdex(dex_location, + odex_location, + app_image_file, + /* use_fd */ false, + /* num_profile_classes */ 1); CheckValidity(); ASSERT_TRUE(success_); - CheckResult(dex_location, odex_location); + CheckResult(dex_location, odex_location, app_image_file); + + if (app_image) { + // Test that the profile made a difference by adding more classes. + const uint64_t image_file_small_profile = GetImageSize(app_image_file); + CHECK_LT(image_file_empty_profile, image_file_small_profile); + } } void RunTestVDex() { std::string dex_location = GetScratchDir() + "/DexNoOat.jar"; std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex"; std::string vdex_location = GetOdexDir() + "/DexOdexNoOat.vdex"; + std::string app_image_file_name = GetOdexDir() + "/DexOdexNoOat.art"; Copy(GetDexSrc2(), dex_location); std::unique_ptr<File> vdex_file1(OS::CreateEmptyFile(vdex_location.c_str())); @@ -643,7 +702,9 @@ class Dex2oatLayoutTest : public Dex2oatTest { std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_file1->Fd()); CompileProfileOdex(dex_location, odex_location, + app_image_file_name, /* use_fd */ true, + /* num_profile_classes */ 1, { input_vdex, output_vdex }); EXPECT_GT(vdex_file1->GetLength(), 0u); } @@ -652,17 +713,21 @@ class Dex2oatLayoutTest : public Dex2oatTest { std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_file2.GetFd()); CompileProfileOdex(dex_location, odex_location, + app_image_file_name, /* use_fd */ true, + /* num_profile_classes */ 1, { input_vdex, output_vdex }); EXPECT_GT(vdex_file2.GetFile()->GetLength(), 0u); } ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file"; CheckValidity(); ASSERT_TRUE(success_); - CheckResult(dex_location, odex_location); + CheckResult(dex_location, odex_location, app_image_file_name); } - void CheckResult(const std::string& dex_location, const std::string& odex_location) { + void CheckResult(const std::string& dex_location, + const std::string& odex_location, + const std::string& app_image_file_name) { // Host/target independent checks. std::string error_msg; std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), @@ -698,6 +763,16 @@ class Dex2oatLayoutTest : public Dex2oatTest { } EXPECT_EQ(odex_file->GetCompilerFilter(), CompilerFilter::kSpeedProfile); + + if (!app_image_file_name.empty()) { + // Go peek at the image header to make sure it was large enough to contain the class. + std::unique_ptr<File> file(OS::OpenFileForReading(app_image_file_name.c_str())); + ImageHeader image_header; + bool success = file->ReadFully(&image_header, sizeof(image_header)); + ASSERT_TRUE(success); + ASSERT_TRUE(image_header.IsValid()); + EXPECT_GT(image_header.GetImageSection(ImageHeader::kSectionObjects).Size(), 0u); + } } // Check whether the dex2oat run was really successful. @@ -720,7 +795,11 @@ class Dex2oatLayoutTest : public Dex2oatTest { }; TEST_F(Dex2oatLayoutTest, TestLayout) { - RunTest(); + RunTest(/* app-image */ false); +} + +TEST_F(Dex2oatLayoutTest, TestLayoutAppImage) { + RunTest(/* app-image */ true); } TEST_F(Dex2oatLayoutTest, TestVdexLayout) { |