diff options
author | 2024-08-18 16:37:00 +0100 | |
---|---|---|
committer | 2024-08-23 12:37:42 +0000 | |
commit | f797b3fabb29f93fe07ec70b9892184d599727bc (patch) | |
tree | 12996527d2dd3732d9f88d77e7890555dc25793d /libdexfile/dex/dex_file_loader.cc | |
parent | b17478f8e8f1b27dc8994d991cd0e8ec7c249c1b (diff) |
Get Multidex checksums without opening dex files.
This speeds up profman when processing compressed apks because it avoids
extracting dex files into the memory.
Bug: 358502198
Test: atest art_standalone_profman_tests
Change-Id: I98f28653ac4e80f3e3c225bde370401c974199ae
Diffstat (limited to 'libdexfile/dex/dex_file_loader.cc')
-rw-r--r-- | libdexfile/dex/dex_file_loader.cc | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc index d524dfceb1..e92a5ac813 100644 --- a/libdexfile/dex/dex_file_loader.cc +++ b/libdexfile/dex/dex_file_loader.cc @@ -161,12 +161,10 @@ std::string DexFileLoader::GetMultiDexLocation(size_t index, const char* dex_loc return StringPrintf("%s%cclasses%zu.dex", dex_location, kMultiDexSeparator, index + 1); } -bool DexFileLoader::GetMultiDexChecksum(std::optional<uint32_t>* checksum, - std::string* error_msg, - bool* only_contains_uncompressed_dex) { - CHECK(checksum != nullptr); - checksum->reset(); // Return nullopt for an empty zip archive. - +bool DexFileLoader::GetMultiDexChecksums( + /*out*/ std::vector<std::pair<std::string, uint32_t>>* checksums, + /*out*/ std::string* error_msg, + /*out*/ bool* only_contains_uncompressed_dex) { uint32_t magic; if (!InitAndReadMagic(/*header_offset=*/0, &magic, error_msg)) { return false; @@ -196,7 +194,7 @@ bool DexFileLoader::GetMultiDexChecksum(std::optional<uint32_t>* checksum, *only_contains_uncompressed_dex = false; } } - *checksum = checksum->value_or(kEmptyMultiDexChecksum) ^ zip_entry->GetCrc32(); + checksums->emplace_back(GetMultiDexLocation(i, location_.c_str()), zip_entry->GetCrc32()); } return true; } @@ -205,6 +203,7 @@ bool DexFileLoader::GetMultiDexChecksum(std::optional<uint32_t>* checksum, } const uint8_t* begin = root_container_->Begin(); const uint8_t* end = root_container_->End(); + size_t i = 0; for (const uint8_t* ptr = begin; ptr < end;) { const auto* header = reinterpret_cast<const DexFile::Header*>(ptr); size_t size = dchecked_integral_cast<size_t>(end - ptr); @@ -216,12 +215,28 @@ bool DexFileLoader::GetMultiDexChecksum(std::optional<uint32_t>* checksum, *error_msg = StringPrintf("Truncated dex file: '%s'", filename_.c_str()); return false; } - *checksum = checksum->value_or(kEmptyMultiDexChecksum) ^ header->checksum_; + checksums->emplace_back(GetMultiDexLocation(i++, location_.c_str()), header->checksum_); ptr += header->file_size_; } return true; } +bool DexFileLoader::GetMultiDexChecksum(std::optional<uint32_t>* checksum, + std::string* error_msg, + bool* only_contains_uncompressed_dex) { + CHECK(checksum != nullptr); + checksum->reset(); // Return nullopt for an empty zip archive. + + std::vector<std::pair<std::string, uint32_t>> checksums; + if (!GetMultiDexChecksums(&checksums, error_msg, only_contains_uncompressed_dex)) { + return false; + } + for (const auto& [location, current_checksum] : checksums) { + *checksum = checksum->value_or(kEmptyMultiDexChecksum) ^ current_checksum; + } + return true; +} + std::string DexFileLoader::GetDexCanonicalLocation(const char* dex_location) { CHECK_NE(dex_location, static_cast<const char*>(nullptr)); std::string base_location = GetBaseLocation(dex_location); |