// Header of image files written by ImageWriter, read and validated by Space. // Packed to object alignment since the first object follows directly after the header.
static_assert(kObjectAlignment == 8, "Alignment check"); class PACKED(8) ImageHeader { public: enum StorageMode : uint32_t {
kStorageModeUncompressed,
kStorageModeLZ4,
kStorageModeLZ4HC,
kStorageModeCount, // Number of elements in enum.
}; static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
// Solid block of the image. May be compressed or uncompressed. class PACKED(4) Block final { public:
Block(StorageMode storage_mode,
uint32_t data_offset,
uint32_t data_size,
uint32_t image_offset,
uint32_t image_size)
: storage_mode_(storage_mode),
data_offset_(data_offset),
data_size_(data_size),
image_offset_(image_offset),
image_size_(image_size) {}
// The location that the oat file was expected to be when the image was created. The actual // oat file may be at a different location for application images.
uint8_t* GetOatFileBegin() const { returnreinterpret_cast<uint8_t*>(oat_file_begin_);
}
enum ImageMethod {
kResolutionMethod,
kImtConflictMethod,
kImtUnimplementedMethod,
kSaveAllCalleeSavesMethod,
kSaveRefsOnlyMethod,
kSaveRefsAndArgsMethod,
kSaveEverythingMethod,
kSaveEverythingMethodForClinit,
kSaveEverythingMethodForSuspendCheck,
kImageMethodsCount, // Number of elements in enum.
};
enum ImageRoot {
kDexCaches,
kClassRoots,
kSpecialRoots, // Different for boot image and app image, see aliases below.
kImageRootsMax,
// Aliases.
kAppImageClassLoader = kSpecialRoots, // The class loader used to build the app image.
kBootImageLiveObjects = kSpecialRoots, // Array of boot image objects that must be kept live.
kAppImageOatHeader = kSpecialRoots, // A byte array containing 1) a fake OatHeader to check // if the image can be loaded against the current // runtime, and 2) the dex checksums.
};
enum BootImageLiveObjects {
kOomeWhenThrowingException, // Pre-allocated OOME when throwing exception.
kOomeWhenThrowingOome, // Pre-allocated OOME when throwing OOME.
kOomeWhenHandlingStackOverflow, // Pre-allocated OOME when handling StackOverflowError.
kNoClassDefFoundError, // Pre-allocated NoClassDefFoundError.
kClearedJniWeakSentinel, // Pre-allocated sentinel for cleared weak JNI references.
kIntrinsicObjectsStart
};
/* *ThisdescribesthenumberandorderingofsectionsinsideofBoot *andAppImages.Itisveryimportantthatchangestothisstruct *arereflectedinthecompilerandloader. * *See: *-ImageWriter::ImageInfo::CreateImageSections() *-ImageWriter::Write() *-ImageWriter::AllocMemory()
*/ enum ImageSections {
kSectionObjects,
kSectionArtFields,
kSectionArtMethods,
kSectionImTables,
kSectionIMTConflictTables,
kSectionRuntimeMethods,
kSectionJniStubMethods,
kSectionInternedStrings,
kSectionClassTable,
kSectionStringReferenceOffsets,
kSectionDexCacheArrays,
kSectionMetadata,
kSectionImageBitmap,
kSectionCount, // Number of elements in enum.
};
static size_t NumberOfImageRoots([[maybe_unused]] bool app_image) { // At the moment, boot image and app image have the same number of roots, // though the meaning of the kSpecialRoots is different. return kImageRootsMax;
}
// Visit mirror::Objects in the section starting at base. // TODO: Delete base parameter if it is always equal to GetImageBegin.
EXPORT void VisitObjects(ObjectVisitor* visitor, uint8_t* base, PointerSize pointer_size) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Visit ArtMethods in the section starting at base. Includes runtime methods. // TODO: Delete base parameter if it is always equal to GetImageBegin. // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern. template <typename Visitor> void VisitPackedArtMethods(const Visitor& visitor,
uint8_t* base,
PointerSize pointer_size) const NO_THREAD_SAFETY_ANALYSIS;
// Visit ArtMethods in the section starting at base. // TODO: Delete base parameter if it is always equal to GetImageBegin. // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern. template <typename Visitor> void VisitPackedArtFields(const Visitor& visitor, uint8_t* base) const NO_THREAD_SAFETY_ANALYSIS;
// Helper for writing `data` and `bitmap_data` into `image_file`, following // the information stored in this header and passed as arguments.
EXPORT bool WriteData(const ImageFileGuard& image_file, const uint8_t* data, const uint8_t* bitmap_data,
ImageHeader::StorageMode image_storage_mode,
uint32_t max_image_block_size, bool update_checksum,
std::string* error_msg);
// The total memory reservation size for the image. // For boot image or boot image extension, the primary image includes the reservation // for all image files and oat files, secondary images have the reservation set to 0. // App images have reservation equal to `image_size_` rounded up to page size because // their oat files are mmapped independently.
uint32_t image_reservation_size_ = 0u;
// The number of components (jar files contributing to the image). // For boot image or boot image extension, the primary image stores the total number // of components, secondary images have this set to 0. App images have 1 component. // The component count usually matches the total number of images (one image per component), but // if multiple components are compiled with --single-image there will only be 1 image associated // with those components.
uint32_t component_count_ = 0u;
// Required base address for mapping the image.
uint32_t image_begin_ = 0u;
// Image size, not page aligned.
uint32_t image_size_ = 0u;
// Image file checksum (calculated with the checksum field set to 0).
uint32_t image_checksum_ = 0u;
// Checksum of the oat file we link to for load time consistency check.
uint32_t oat_checksum_ = 0u;
// Start address for oat file. Will be before oat_data_begin_ for .so files.
uint32_t oat_file_begin_ = 0u;
// End of oat data address range for this image file.
uint32_t oat_data_end_ = 0u;
// End of oat file address range. will be after oat_data_end_ for // .so files. Used for positioning a following alloc spaces.
uint32_t oat_file_end_ = 0u;
// Boot image begin and end (only applies to boot image extension and app image headers).
uint32_t boot_image_begin_ = 0u;
uint32_t boot_image_size_ = 0u; // Includes heap (*.art) and code (.oat).
// Number of boot image components that this image depends on and their composite checksum // (only applies to boot image extension and app image headers).
uint32_t boot_image_component_count_ = 0u;
uint32_t boot_image_checksum_ = 0u;
// Absolute address of an Object[] of objects needed to reinitialize from an image.
uint32_t image_roots_ = 0u;
// Pointer size, this affects the size of the ArtMethods.
PointerSize pointer_size_;
// Image section sizes/offsets correspond to the uncompressed form.
ImageSection sections_[kSectionCount];
// Image methods, may be inside of the boot image for app images.
uint64_t image_methods_[kImageMethodsCount];
// Data size for the image data excluding the bitmap and the header. For compressed images, this // is the compressed size in the file.
uint32_t data_size_ = 0u;
// Image blocks, only used for compressed images.
uint32_t blocks_offset_ = 0u;
uint32_t blocks_count_ = 0u;
// Helper class that erases the image file if it isn't properly flushed and closed. class ImageFileGuard { public:
ImageFileGuard() noexcept = default;
ImageFileGuard(ImageFileGuard&& other) noexcept = default;
ImageFileGuard& operator=(ImageFileGuard&& other) noexcept = default;
~ImageFileGuard() { if (image_file_ != nullptr) { // Failure, erase the image file.
image_file_->Erase();
}
}
bool WriteHeaderAndClose(const std::string& image_filename, const ImageHeader* image_header,
std::string* error_msg) { // The header is uncompressed since it contains whether the image is compressed or not. if (!image_file_->PwriteFully(image_header, sizeof(ImageHeader), 0)) {
*error_msg = "Failed to write image file header "
+ image_filename + ": " + std::string(strerror(errno)); returnfalse;
}
// FlushCloseOrErase() takes care of erasing, so the destructor does not need // to do that whether the FlushCloseOrErase() succeeds or fails.
std::unique_ptr<File> image_file = std::move(image_file_); if (image_file->FlushCloseOrErase() != 0) {
*error_msg = "Failed to flush and close image file "
+ image_filename + ": " + std::string(strerror(errno)); returnfalse;
}
// Wrapper over LZ4_decompress_safe() that checks if return value is negative. See b/242914915. bool LZ4_decompress_safe_checked(constchar* source, char* dest, int compressed_size, int max_decompressed_size, /*out*/ size_t* decompressed_size_checked, /*out*/ std::string* error_msg);
} // namespace art
#endif// ART_RUNTIME_OAT_IMAGE_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.