Do not generate an app image without a boot image.
We used to not do compilation at all. Now we will compile, but not
generate an app image.
Test: test.py
Test: dex2oat_tests
Bug: 214376933
Change-Id: Ia8adffec9d1919b128f5ed0fe2e763ee863dc4b3
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 7a27ab6..c8bef9e 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -958,7 +958,6 @@
key_value_store_->Put(OatHeader::kCompilerFilter,
CompilerFilter::NameOfFilter(compiler_options_->GetCompilerFilter()));
key_value_store_->Put(OatHeader::kConcurrentCopying, kUseReadBarrier);
- key_value_store_->Put(OatHeader::kRequiresImage, compiler_options_->IsGeneratingImage());
if (invocation_file_.get() != -1) {
std::ostringstream oss;
for (int i = 0; i < argc; ++i) {
@@ -1525,10 +1524,10 @@
}
if (runtime_->GetHeap()->GetBootImageSpaces().empty() &&
(IsBootImageExtension() || IsAppImage())) {
- LOG(ERROR) << "Cannot create "
- << (IsBootImageExtension() ? "boot image extension" : "app image")
- << " without a primary boot image.";
- return dex2oat::ReturnCode::kOther;
+ LOG(WARNING) << "Cannot create "
+ << (IsBootImageExtension() ? "boot image extension" : "app image")
+ << " without a primary boot image.";
+ compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
}
ArrayRef<const DexFile* const> bcp_dex_files(runtime_->GetClassLinker()->GetBootClassPath());
if (IsBootImage() || IsBootImageExtension()) {
@@ -1667,6 +1666,10 @@
key_value_store_->Put(OatHeader::kApexVersionsKey, versions);
}
+ // Now that we have adjusted whether we generate an image, encode it in the
+ // key/value store.
+ key_value_store_->Put(OatHeader::kRequiresImage, compiler_options_->IsGeneratingImage());
+
// Now that we have finalized key_value_store_, start writing the .rodata section.
// Among other things, this creates type lookup tables that speed up the compilation.
{
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index c38c720..9ee532a 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -884,7 +884,21 @@
/*use_fd=*/ false,
/*num_profile_classes=*/ 1,
/*extra_args=*/ {"--boot-image=/nonx/boot.art"},
- /*expect_success=*/ false);
+ /*expect_success=*/ true);
+
+ // Verify the odex file does not require an image.
+ std::string error_msg;
+ std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1,
+ odex_location.c_str(),
+ odex_location.c_str(),
+ /*executable=*/ false,
+ /*low_4gb=*/ false,
+ dex_location,
+ &error_msg));
+ ASSERT_TRUE(odex_file != nullptr) << "Could not open odex file: " << error_msg;
+
+ CheckFilter(CompilerFilter::kSpeedProfile, odex_file->GetCompilerFilter());
+ ASSERT_FALSE(odex_file->GetOatHeader().RequiresImage());
}
TEST_F(Dex2oatLayoutTest, TestLayoutMultipleProfiles) {
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index aaa6600..c3a268d 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -308,7 +308,7 @@
if (oat_file->RequiresImage()) {
LOG(WARNING) << "Loading "
<< oat_file->GetLocation()
- << "non-executable as it requires an image which we failed to load";
+ << " non-executable as it requires an image which we failed to load";
// file as non-executable.
OatFileAssistant nonexecutable_oat_file_assistant(dex_location,
kRuntimeISA,