Continue image space initialization if the primary boot image is valid.
`BootImageLoader::LoadFromSystem` checks the return value of
`BootImageLayout::LoadFromSystem` and continues only if the return value
is true. Therefore, `BootImageLayout::LoadFromSystem` shouldn't return
false to abort image space initialization even if it fails to load a
boot image extension. However, before this change, when
`allow_in_memory_compilation` is false, `BootImageLayout::LoadFromSystem`
returns false when a boot image extension is unusable. This isn't
expected. It wasn't a problem before because
`allow_in_memory_compilation` was always true, but
`allow_in_memory_compilation` can be false starting from aosp/2219944,
so we need to fix this issue.
Bug: 247055146
Test: ArtGtestsTargetChroot
Change-Id: I866e8acd38df270896b4acb362876cd9addf02a1
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 41bb62f..00b4f47 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -2016,17 +2016,17 @@
std::string base_filename;
if (!filename_fn(base_location, &base_filename, &local_error_msg) ||
!ReadHeader(base_location, base_filename, bcp_index, &local_error_msg)) {
- if (!allow_in_memory_compilation) {
- // The boot image is unusable and we can't continue by generating a boot image in memory.
- // All we can do is to return.
- *error_msg = std::move(local_error_msg);
- return false;
- }
LOG(ERROR) << "Error reading named image component header for " << base_location
<< ", error: " << local_error_msg;
// If the primary boot image is invalid, we generate a single full image. This is faster than
// generating the primary boot image and the extension separately.
if (bcp_index == 0) {
+ if (!allow_in_memory_compilation) {
+ // The boot image is unusable and we can't continue by generating a boot image in memory.
+ // All we can do is to return.
+ *error_msg = std::move(local_error_msg);
+ return false;
+ }
// We must at least have profiles for the core libraries.
if (profile_filenames.empty()) {
*error_msg = "Full boot image cannot be compiled because no profile is provided.";
@@ -2050,14 +2050,15 @@
// No extensions are needed.
return true;
}
- if (profile_filenames.empty() ||
+ bool should_compile_extension = allow_in_memory_compilation && !profile_filenames.empty();
+ if (!should_compile_extension ||
!CompileBootclasspathElements(base_location,
base_filename,
bcp_index,
profile_filenames,
components.SubArray(/*pos=*/ 0, /*length=*/ 1),
&local_error_msg)) {
- if (!profile_filenames.empty()) {
+ if (should_compile_extension) {
LOG(ERROR) << "Error compiling boot image extension for " << boot_class_path_[bcp_index]
<< ", error: " << local_error_msg;
}
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index bf9cda2..472ae40 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -444,6 +444,7 @@
ArrayRef<const std::string> dependencies,
/*out*/ std::string* error_msg);
+ // Returns true if a least one chuck has been loaded.
template <typename FilenameFn>
bool Load(FilenameFn&& filename_fn,
bool allow_in_memory_compilation,
diff --git a/runtime/oat_file_assistant_context.cc b/runtime/oat_file_assistant_context.cc
index becc329..4bd83b7 100644
--- a/runtime/oat_file_assistant_context.cc
+++ b/runtime/oat_file_assistant_context.cc
@@ -131,9 +131,11 @@
std::string error_msg;
if (!layout.LoadFromSystem(isa, /*allow_in_memory_compilation=*/false, &error_msg)) {
- // At this point, `layout` contains a subset of boot images that can be loaded.
+ // At this point, `layout` contains nothing.
VLOG(oat) << "Some error occurred when loading boot images for oat file validation: "
<< error_msg;
+ // Create an empty entry so that we don't have to retry when the function is called again.
+ return boot_image_info_list_by_isa_[isa];
}
std::vector<BootImageInfo>& boot_image_info_list = boot_image_info_list_by_isa_[isa];