Add image compressed blocks
Add support for splitting the image into a set of solid blocks.
Added dex2oat option --max-image-block-size and correspodning image
unit test.
Motivation: Enable parallel image decompression in the future.
Bug: 116052292
Test: test-art-host
Change-Id: I37c6c6a43ef94c4a62bf38a0cf51f26ce06347ac
diff --git a/runtime/image.cc b/runtime/image.cc
index f50c39c..ae3d8e3 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -16,6 +16,9 @@
#include "image.h"
+#include <lz4.h>
+#include <sstream>
+
#include "base/bit_utils.h"
#include "base/length_prefixed_array.h"
#include "base/utils.h"
@@ -26,7 +29,7 @@
namespace art {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '7', '0', '\0' }; // Store ImtIndex.
+const uint8_t ImageHeader::kImageVersion[] = { '0', '7', '1', '\0' }; // Add image blocks.
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_size,
@@ -39,9 +42,7 @@
uint32_t oat_file_end,
uint32_t boot_image_begin,
uint32_t boot_image_size,
- uint32_t pointer_size,
- StorageMode storage_mode,
- size_t data_size)
+ uint32_t pointer_size)
: image_begin_(image_begin),
image_size_(image_size),
image_checksum_(0u),
@@ -53,9 +54,7 @@
boot_image_begin_(boot_image_begin),
boot_image_size_(boot_image_size),
image_roots_(image_roots),
- pointer_size_(pointer_size),
- storage_mode_(storage_mode),
- data_size_(data_size) {
+ pointer_size_(pointer_size) {
CHECK_EQ(image_begin, RoundUp(image_begin, kPageSize));
CHECK_EQ(oat_file_begin, RoundUp(oat_file_begin, kPageSize));
CHECK_EQ(oat_data_begin, RoundUp(oat_data_begin, kPageSize));
@@ -144,4 +143,34 @@
return ConvertToPointerSize(pointer_size_);
}
+bool ImageHeader::Block::Decompress(uint8_t* out_ptr,
+ const uint8_t* in_ptr,
+ std::string* error_msg) const {
+ switch (storage_mode_) {
+ case kStorageModeUncompressed: {
+ CHECK_EQ(image_size_, data_size_);
+ memcpy(out_ptr + image_offset_, in_ptr + data_offset_, data_size_);
+ break;
+ }
+ case kStorageModeLZ4:
+ case kStorageModeLZ4HC: {
+ // LZ4HC and LZ4 have same internal format, both use LZ4_decompress.
+ const size_t decompressed_size = LZ4_decompress_safe(
+ reinterpret_cast<const char*>(in_ptr) + data_offset_,
+ reinterpret_cast<char*>(out_ptr) + image_offset_,
+ data_size_,
+ image_size_);
+ CHECK_EQ(decompressed_size, image_size_);
+ break;
+ }
+ default: {
+ if (error_msg != nullptr) {
+ *error_msg = (std::ostringstream() << "Invalid image format " << storage_mode_).str();
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace art