summaryrefslogtreecommitdiff
path: root/dex2oat/dex2oat_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dex2oat/dex2oat_test.cc')
-rw-r--r--dex2oat/dex2oat_test.cc97
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) {