Support running without a boot image.
Bug: 17000769
Change-Id: I6404d5050c8a2f4ee6e70d58532eb25ee9de248e
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index f0b7685..cd1cdd3 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -202,15 +202,21 @@
// Requested begin for the alloc space, to follow the mapped image and oat files
byte* requested_alloc_space_begin = nullptr;
if (!image_file_name.empty()) {
+ std::string error_msg;
space::ImageSpace* image_space = space::ImageSpace::Create(image_file_name.c_str(),
- image_instruction_set);
- CHECK(image_space != nullptr) << "Failed to create space for " << image_file_name;
- AddSpace(image_space);
- // Oat files referenced by image files immediately follow them in memory, ensure alloc space
- // isn't going to get in the middle
- byte* oat_file_end_addr = image_space->GetImageHeader().GetOatFileEnd();
- CHECK_GT(oat_file_end_addr, image_space->End());
- requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize);
+ image_instruction_set,
+ &error_msg);
+ if (image_space != nullptr) {
+ AddSpace(image_space);
+ // Oat files referenced by image files immediately follow them in memory, ensure alloc space
+ // isn't going to get in the middle
+ byte* oat_file_end_addr = image_space->GetImageHeader().GetOatFileEnd();
+ CHECK_GT(oat_file_end_addr, image_space->End());
+ requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize);
+ } else {
+ LOG(WARNING) << "Could not create image space with image file '" << image_file_name << "'. "
+ << "Attempting to fall back to imageless running. Error was: " << error_msg;
+ }
}
/*
requested_alloc_space_begin -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
@@ -579,6 +585,9 @@
}
bool Heap::IsCompilingBoot() const {
+ if (!Runtime::Current()->IsCompiler()) {
+ return false;
+ }
for (const auto& space : continuous_spaces_) {
if (space->IsImageSpace() || space->IsZygoteSpace()) {
return false;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 1d10af2..0139ecc 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -283,8 +283,8 @@
}
ImageSpace* ImageSpace::Create(const char* image_location,
- const InstructionSet image_isa) {
- std::string error_msg;
+ const InstructionSet image_isa,
+ std::string* error_msg) {
std::string system_filename;
bool has_system = false;
std::string cache_filename;
@@ -296,14 +296,18 @@
ImageSpace* space;
bool relocate = Runtime::Current()->ShouldRelocate();
+ bool can_compile = Runtime::Current()->IsImageDex2OatEnabled();
if (found_image) {
const std::string* image_filename;
bool is_system = false;
bool relocated_version_used = false;
if (relocate) {
- CHECK(dalvik_cache_exists) << "Requiring relocation for image " << image_location << " "
- << "at " << system_filename << " but we do not have any "
- << "dalvik_cache to find/place it in.";
+ if (!dalvik_cache_exists) {
+ *error_msg = StringPrintf("Requiring relocation for image '%s' at '%s' but we do not have "
+ "any dalvik_cache to find/place it in.",
+ image_location, system_filename.c_str());
+ return nullptr;
+ }
if (has_system) {
if (has_cache && ChecksumsMatch(system_filename.c_str(), cache_filename.c_str())) {
// We already have a relocated version
@@ -311,14 +315,20 @@
relocated_version_used = true;
} else {
// We cannot have a relocated version, Relocate the system one and use it.
- if (RelocateImage(image_location, cache_filename.c_str(), image_isa,
- &error_msg)) {
+ if (can_compile && RelocateImage(image_location, cache_filename.c_str(), image_isa,
+ error_msg)) {
relocated_version_used = true;
image_filename = &cache_filename;
} else {
- LOG(FATAL) << "Unable to relocate image " << image_location << " "
- << "from " << system_filename << " to " << cache_filename << ": "
- << error_msg;
+ std::string reason;
+ if (can_compile) {
+ reason = StringPrintf(": %s", error_msg->c_str());
+ } else {
+ reason = " because image dex2oat is disabled.";
+ }
+ *error_msg = StringPrintf("Unable to relocate image '%s' from '%s' to '%s'%s",
+ image_location, system_filename.c_str(),
+ cache_filename.c_str(), reason.c_str());
return nullptr;
}
}
@@ -351,7 +361,7 @@
// descriptor (and the associated exclusive lock) to be released when
// we leave Create.
ScopedFlock image_lock;
- image_lock.Init(image_filename->c_str(), &error_msg);
+ image_lock.Init(image_filename->c_str(), error_msg);
LOG(INFO) << "Using image file " << image_filename->c_str() << " for image location "
<< image_location;
// If we are in /system we can assume the image is good. We can also
@@ -359,7 +369,7 @@
// matches) since this is only different by the offset. We need this to
// make sure that host tests continue to work.
space = ImageSpace::Init(image_filename->c_str(), image_location,
- !(is_system || relocated_version_used), &error_msg);
+ !(is_system || relocated_version_used), error_msg);
}
if (space != nullptr) {
return space;
@@ -374,29 +384,38 @@
<< "but image failed to load: " << error_msg;
return nullptr;
} else if (is_system) {
- LOG(FATAL) << "Failed to load /system image '" << *image_filename << "': " << error_msg;
+ *error_msg = StringPrintf("Failed to load /system image '%s': %s",
+ image_filename->c_str(), error_msg->c_str());
return nullptr;
} else {
- LOG(WARNING) << error_msg;
+ LOG(WARNING) << *error_msg;
}
}
- CHECK(dalvik_cache_exists) << "No place to put generated image.";
- CHECK(GenerateImage(cache_filename, &error_msg))
- << "Failed to generate image '" << cache_filename << "': " << error_msg;
- {
+ if (!can_compile) {
+ *error_msg = "Not attempting to compile image because -Xnoimage-dex2oat";
+ return nullptr;
+ } else if (!dalvik_cache_exists) {
+ *error_msg = StringPrintf("No place to put generated image.");
+ return nullptr;
+ } else if (!GenerateImage(cache_filename, error_msg)) {
+ *error_msg = StringPrintf("Failed to generate image '%s': %s",
+ cache_filename.c_str(), error_msg->c_str());
+ return nullptr;
+ } else {
// Note that we must not use the file descriptor associated with
// ScopedFlock::GetFile to Init the image file. We want the file
// descriptor (and the associated exclusive lock) to be released when
// we leave Create.
ScopedFlock image_lock;
- image_lock.Init(cache_filename.c_str(), &error_msg);
- space = ImageSpace::Init(cache_filename.c_str(), image_location, true, &error_msg);
+ image_lock.Init(cache_filename.c_str(), error_msg);
+ space = ImageSpace::Init(cache_filename.c_str(), image_location, true, error_msg);
+ if (space == nullptr) {
+ *error_msg = StringPrintf("Failed to load generated image '%s': %s",
+ cache_filename.c_str(), error_msg->c_str());
+ }
+ return space;
}
- if (space == nullptr) {
- LOG(FATAL) << "Failed to load generated image '" << cache_filename << "': " << error_msg;
- }
- return space;
}
void ImageSpace::VerifyImageAllocations() {
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 6be3b8f..28ebca6 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -43,7 +43,7 @@
// creation of the alloc space. The ReleaseOatFile will later be
// used to transfer ownership of the OatFile to the ClassLinker when
// it is initialized.
- static ImageSpace* Create(const char* image, InstructionSet image_isa)
+ static ImageSpace* Create(const char* image, InstructionSet image_isa, std::string* error_msg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Reads the image header from the specified image location for the