diff options
author | 2017-02-22 11:37:41 +0000 | |
---|---|---|
committer | 2017-03-02 09:29:25 +0000 | |
commit | 95e0967b8aa7a0f9abcb148f58dbf697a482e886 (patch) | |
tree | 585186d4c4c63482f785c312b549f5baa54505df | |
parent | 48b795efcb504b71fbf038fabdd3d05366793197 (diff) |
Clean up OatFileAssistant getting of image info.
* ImageInfo.oat_checksum is no longer unused.
* Don't abort if we can't read secondary isa images.
Test: m art-test-host
Bug: 34385298
Bug: 34800919
Change-Id: I4d1ad4e2435cc62d38cd7143bc71313e319e952d
-rw-r--r-- | runtime/oat_file_assistant.cc | 110 | ||||
-rw-r--r-- | runtime/oat_file_assistant.h | 9 |
2 files changed, 65 insertions, 54 deletions
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 5ae2fc51b7..48bf1e72a4 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -430,8 +430,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& // starts up. LOG(WARNING) << "Dex location " << dex_location_ << " does not seem to include dex file. " << "Allow oat file use. This is potentially dangerous."; - } else if (file.GetOatHeader().GetImageFileLocationOatChecksum() - != GetCombinedImageChecksum()) { + } else if (file.GetOatHeader().GetImageFileLocationOatChecksum() != image_info->oat_checksum) { VLOG(oat) << "Oat image checksum does not match image checksum."; return kOatBootImageOutOfDate; } @@ -726,68 +725,81 @@ const std::vector<uint32_t>* OatFileAssistant::GetRequiredDexChecksums() { return required_dex_checksums_found_ ? &cached_required_dex_checksums_ : nullptr; } -const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() { - if (!image_info_load_attempted_) { - image_info_load_attempted_ = true; - - Runtime* runtime = Runtime::Current(); - std::vector<gc::space::ImageSpace*> image_spaces = runtime->GetHeap()->GetBootImageSpaces(); - if (!image_spaces.empty()) { - cached_image_info_.location = image_spaces[0]->GetImageLocation(); - - if (isa_ == kRuntimeISA) { - const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); - cached_image_info_.oat_checksum = image_header.GetOatChecksum(); - cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>( - image_header.GetOatDataBegin()); - cached_image_info_.patch_delta = image_header.GetPatchDelta(); - } else { - std::string error_msg; - std::unique_ptr<ImageHeader> image_header( - gc::space::ImageSpace::ReadImageHeader(cached_image_info_.location.c_str(), - isa_, - &error_msg)); - CHECK(image_header != nullptr) << error_msg; - cached_image_info_.oat_checksum = image_header->GetOatChecksum(); - cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>( - image_header->GetOatDataBegin()); - cached_image_info_.patch_delta = image_header->GetPatchDelta(); - } - } - image_info_load_succeeded_ = (!image_spaces.empty()); +// TODO: Use something better than xor for the combined image checksum. +std::unique_ptr<OatFileAssistant::ImageInfo> +OatFileAssistant::ImageInfo::GetRuntimeImageInfo(InstructionSet isa, std::string* error_msg) { + CHECK(error_msg != nullptr); - combined_image_checksum_ = CalculateCombinedImageChecksum(isa_); + // Use the currently loaded image to determine the image locations for all + // the image spaces, regardless of the isa requested. Otherwise we would + // need to read from the boot image's oat file to determine the rest of the + // image locations in the case of multi-image. + Runtime* runtime = Runtime::Current(); + std::vector<gc::space::ImageSpace*> image_spaces = runtime->GetHeap()->GetBootImageSpaces(); + if (image_spaces.empty()) { + *error_msg = "There are no boot image spaces"; + return nullptr; } - return image_info_load_succeeded_ ? &cached_image_info_ : nullptr; -} -// TODO: Use something better than xor. -uint32_t OatFileAssistant::CalculateCombinedImageChecksum(InstructionSet isa) { - uint32_t checksum = 0; - std::vector<gc::space::ImageSpace*> image_spaces = - Runtime::Current()->GetHeap()->GetBootImageSpaces(); + std::unique_ptr<ImageInfo> info(new ImageInfo()); + info->location = image_spaces[0]->GetImageLocation(); + + // TODO: Special casing on isa == kRuntimeISA is presumably motivated by + // performance: 'it's faster to use an already loaded image header than read + // the image header from disk'. But the loaded image is not necessarily the + // same as kRuntimeISA, so this behavior is suspect (b/35659889). if (isa == kRuntimeISA) { + const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); + info->oat_data_begin = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()); + info->patch_delta = image_header.GetPatchDelta(); + + info->oat_checksum = 0; for (gc::space::ImageSpace* image_space : image_spaces) { - checksum ^= image_space->GetImageHeader().GetOatChecksum(); + info->oat_checksum ^= image_space->GetImageHeader().GetOatChecksum(); } } else { + std::unique_ptr<ImageHeader> image_header( + gc::space::ImageSpace::ReadImageHeader(info->location.c_str(), isa, error_msg)); + if (image_header == nullptr) { + return nullptr; + } + info->oat_data_begin = reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()); + info->patch_delta = image_header->GetPatchDelta(); + + info->oat_checksum = 0; for (gc::space::ImageSpace* image_space : image_spaces) { std::string location = image_space->GetImageLocation(); - std::string error_msg; - std::unique_ptr<ImageHeader> image_header( - gc::space::ImageSpace::ReadImageHeader(location.c_str(), isa, &error_msg)); - CHECK(image_header != nullptr) << error_msg; - checksum ^= image_header->GetOatChecksum(); + image_header.reset( + gc::space::ImageSpace::ReadImageHeader(location.c_str(), isa, error_msg)); + if (image_header == nullptr) { + return nullptr; + } + info->oat_checksum ^= image_header->GetOatChecksum(); } } - return checksum; + return info; } -uint32_t OatFileAssistant::GetCombinedImageChecksum() { +const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() { if (!image_info_load_attempted_) { - GetImageInfo(); + image_info_load_attempted_ = true; + std::string error_msg; + cached_image_info_ = ImageInfo::GetRuntimeImageInfo(isa_, &error_msg); + if (cached_image_info_ == nullptr) { + LOG(WARNING) << "Unable to get runtime image info: " << error_msg; + } + } + return cached_image_info_.get(); +} + +uint32_t OatFileAssistant::CalculateCombinedImageChecksum(InstructionSet isa) { + std::string error_msg; + std::unique_ptr<ImageInfo> info = ImageInfo::GetRuntimeImageInfo(isa, &error_msg); + if (info == nullptr) { + LOG(WARNING) << "Unable to get runtime image info for checksum: " << error_msg; + return 0; } - return combined_image_checksum_; + return info->oat_checksum; } OatFileAssistant::OatFileInfo& OatFileAssistant::GetBestInfo() { diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index 3ede29f5e0..eec87f0768 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -284,6 +284,9 @@ class OatFileAssistant { uintptr_t oat_data_begin = 0; int32_t patch_delta = 0; std::string location; + + static std::unique_ptr<ImageInfo> GetRuntimeImageInfo(InstructionSet isa, + std::string* error_msg); }; class OatFileInfo { @@ -414,8 +417,6 @@ class OatFileAssistant { // The caller shouldn't clean up or free the returned pointer. const ImageInfo* GetImageInfo(); - uint32_t GetCombinedImageChecksum(); - // To implement Lock(), we lock a dummy file where the oat file would go // (adding ".flock" to the target file name) and retain the lock for the // remaining lifetime of the OatFileAssistant object. @@ -445,9 +446,7 @@ class OatFileAssistant { // TODO: The image info should probably be moved out of the oat file // assistant to an image file manager. bool image_info_load_attempted_ = false; - bool image_info_load_succeeded_ = false; - ImageInfo cached_image_info_; - uint32_t combined_image_checksum_ = 0; + std::unique_ptr<ImageInfo> cached_image_info_; DISALLOW_COPY_AND_ASSIGN(OatFileAssistant); }; |