diff options
| -rw-r--r-- | dex2oat/dex2oat.cc | 3 | ||||
| -rw-r--r-- | runtime/oat_file_assistant.cc | 25 | ||||
| -rw-r--r-- | runtime/oat_file_assistant.h | 5 | ||||
| -rw-r--r-- | runtime/oat_file_assistant_test.cc | 3 |
4 files changed, 31 insertions, 5 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 0889098fa6..370583e3ba 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -68,6 +68,7 @@ #include "mirror/class_loader.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" +#include "oat_file_assistant.h" #include "oat_writer.h" #include "os.h" #include "runtime.h" @@ -1325,7 +1326,7 @@ class Dex2Oat FINAL { TimingLogger::ScopedTiming t3("Loading image checksum", timings_); std::vector<gc::space::ImageSpace*> image_spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces(); - image_file_location_oat_checksum_ = image_spaces[0]->GetImageHeader().GetOatChecksum(); + image_file_location_oat_checksum_ = OatFileAssistant::CalculateCombinedImageChecksum(); image_file_location_oat_data_begin_ = reinterpret_cast<uintptr_t>(image_spaces[0]->GetImageHeader().GetOatDataBegin()); image_patch_delta_ = image_spaces[0]->GetImageHeader().GetPatchDelta(); diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 32e95e7459..f0768f9ff1 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -495,7 +495,7 @@ bool OatFileAssistant::GivenOatFileIsOutOfDate(const OatFile& file) { return true; } - if (file.GetOatHeader().GetImageFileLocationOatChecksum() != image_info->oat_checksum) { + if (file.GetOatHeader().GetImageFileLocationOatChecksum() != GetCombinedImageChecksum()) { VLOG(oat) << "Oat image checksum does not match image checksum."; return true; } @@ -931,8 +931,7 @@ const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() { cached_image_info_.patch_delta = image_header.GetPatchDelta(); } else { std::unique_ptr<ImageHeader> image_header( - gc::space::ImageSpace::ReadImageHeaderOrDie( - cached_image_info_.location.c_str(), isa_)); + gc::space::ImageSpace::ReadImageHeaderOrDie(cached_image_info_.location.c_str(), isa_)); cached_image_info_.oat_checksum = image_header->GetOatChecksum(); cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>( image_header->GetOatDataBegin()); @@ -940,10 +939,30 @@ const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() { } } image_info_load_succeeded_ = (!image_spaces.empty()); + + combined_image_checksum_ = CalculateCombinedImageChecksum(); } return image_info_load_succeeded_ ? &cached_image_info_ : nullptr; } +// TODO: Use something better than xor. +uint32_t OatFileAssistant::CalculateCombinedImageChecksum() { + uint32_t checksum = 0; + std::vector<gc::space::ImageSpace*> image_spaces = + Runtime::Current()->GetHeap()->GetBootImageSpaces(); + for (gc::space::ImageSpace* image_space : image_spaces) { + checksum ^= image_space->GetImageHeader().GetOatChecksum(); + } + return checksum; +} + +uint32_t OatFileAssistant::GetCombinedImageChecksum() { + if (!image_info_load_attempted_) { + GetImageInfo(); + } + return combined_image_checksum_; +} + gc::space::ImageSpace* OatFileAssistant::OpenImageSpace(const OatFile* oat_file) { DCHECK(oat_file != nullptr); std::string art_file = ArtFileName(oat_file); diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index 17f72febea..63b1573faa 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -279,6 +279,8 @@ class OatFileAssistant { static bool DexFilenameToOdexFilename(const std::string& location, InstructionSet isa, std::string* odex_filename, std::string* error_msg); + static uint32_t CalculateCombinedImageChecksum(); + private: struct ImageInfo { uint32_t oat_checksum = 0; @@ -352,6 +354,8 @@ 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. @@ -423,6 +427,7 @@ class OatFileAssistant { bool image_info_load_attempted_ = false; bool image_info_load_succeeded_ = false; ImageInfo cached_image_info_; + uint32_t combined_image_checksum_ = 0; // For debugging only. // If this flag is set, the oat or odex file has been released to the user diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc index bddfa4f21a..f50d1cb748 100644 --- a/runtime/oat_file_assistant_test.cc +++ b/runtime/oat_file_assistant_test.cc @@ -239,7 +239,8 @@ class OatFileAssistantTest : public CommonRuntimeTest { ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr); const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); const OatHeader& oat_header = odex_file->GetOatHeader(); - EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum()); + uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum(); + EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum()); EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), oat_header.GetImageFileLocationOatDataBegin()); EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta()); |