diff options
| -rw-r--r-- | dex2oat/dex2oat.cc | 13 | ||||
| -rw-r--r-- | dex2oat/dex2oat_test.cc | 32 |
2 files changed, 42 insertions, 3 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 6950b93e51..e2c53bbaa8 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -404,6 +404,7 @@ NO_RETURN static void Usage(const char* fmt, ...) { UsageError(" Example: --very-large-app-threshold=100000000"); UsageError(""); UsageError(" --app-image-fd=<file-descriptor>: specify output file descriptor for app image."); + UsageError(" The image is non-empty only if a profile is passed in."); UsageError(" Example: --app-image-fd=10"); UsageError(""); UsageError(" --app-image-file=<file-name>: specify a file name for app image."); @@ -1479,9 +1480,15 @@ class Dex2Oat FINAL { } void LoadClassProfileDescriptors() { - if (profile_compilation_info_ != nullptr && IsImage()) { - Runtime* runtime = Runtime::Current(); - CHECK(runtime != nullptr); + if (!IsImage()) { + return; + } + // If we don't have a profile, treat it as an empty set of classes. b/77340429 + if (image_classes_ == nullptr) { + // May be non-null when --image-classes is passed in, in that case avoid clearing the list. + image_classes_.reset(new std::unordered_set<std::string>()); + } + if (profile_compilation_info_ != nullptr) { // Filter out class path classes since we don't want to include these in the image. image_classes_.reset( new std::unordered_set<std::string>( diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index 0cd39ac11b..c890f8bef0 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -2093,4 +2093,36 @@ TEST_F(Dex2oatTest, CompactDexInZip) { ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_; } +TEST_F(Dex2oatTest, AppImageNoProfile) { + ScratchFile app_image_file; + const std::string out_dir = GetScratchDir(); + const std::string odex_location = out_dir + "/base.odex"; + GenerateOdexForTest(GetTestDexFileName("ManyMethods"), + odex_location, + CompilerFilter::Filter::kSpeedProfile, + { "--app-image-fd=" + std::to_string(app_image_file.GetFd()) }, + true, // expect_success + false, // use_fd + [](const OatFile&) {}); + // Open our generated oat file. + std::string error_msg; + std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + odex_location.c_str(), + nullptr, + nullptr, + false, + /*low_4gb*/false, + odex_location.c_str(), + &error_msg)); + ASSERT_TRUE(odex_file != nullptr); + ImageHeader header = {}; + ASSERT_TRUE(app_image_file.GetFile()->PreadFully( + reinterpret_cast<void*>(&header), + sizeof(header), + /*offset*/ 0u)) << app_image_file.GetFile()->GetLength(); + EXPECT_GT(header.GetImageSection(ImageHeader::kSectionObjects).Size(), 0u); + EXPECT_EQ(header.GetImageSection(ImageHeader::kSectionArtMethods).Size(), 0u); + EXPECT_EQ(header.GetImageSection(ImageHeader::kSectionArtFields).Size(), 0u); +} + } // namespace art |