summaryrefslogtreecommitdiff
path: root/compiler/image_writer.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/image_writer.h')
-rw-r--r--compiler/image_writer.h119
1 files changed, 70 insertions, 49 deletions
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index ee204c5081..dba9dd71fc 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -27,6 +27,7 @@
#include <ostream>
#include "base/bit_utils.h"
+#include "base/dchecked_vector.h"
#include "base/length_prefixed_array.h"
#include "base/macros.h"
#include "driver/compiler_driver.h"
@@ -59,20 +60,19 @@ class ImageWriter FINAL {
bool compile_pic,
bool compile_app_image,
ImageHeader::StorageMode image_storage_mode,
- const std::vector<const char*> oat_filenames,
- const std::unordered_map<const DexFile*, const char*>& dex_file_oat_filename_map);
+ const std::vector<const char*>& oat_filenames,
+ const std::unordered_map<const DexFile*, size_t>& dex_file_oat_index_map);
bool PrepareImageAddressSpace();
bool IsImageAddressSpaceReady() const {
- bool ready = !image_info_map_.empty();
- for (auto& pair : image_info_map_) {
- const ImageInfo& image_info = pair.second;
+ DCHECK(!image_infos_.empty());
+ for (const ImageInfo& image_info : image_infos_) {
if (image_info.image_roots_address_ == 0u) {
return false;
}
}
- return ready;
+ return true;
}
template <typename T>
@@ -80,8 +80,8 @@ class ImageWriter FINAL {
if (object == nullptr || IsInBootImage(object)) {
return object;
} else {
- const char* oat_filename = GetOatFilename(object);
- const ImageInfo& image_info = GetConstImageInfo(oat_filename);
+ size_t oat_index = GetOatIndex(object);
+ const ImageInfo& image_info = GetImageInfo(oat_index);
return reinterpret_cast<T*>(image_info.image_begin_ + GetImageOffset(object));
}
}
@@ -91,9 +91,9 @@ class ImageWriter FINAL {
template <typename PtrType>
PtrType GetDexCacheArrayElementImageAddress(const DexFile* dex_file, uint32_t offset)
const SHARED_REQUIRES(Locks::mutator_lock_) {
- auto oat_it = dex_file_oat_filename_map_.find(dex_file);
- DCHECK(oat_it != dex_file_oat_filename_map_.end());
- const ImageInfo& image_info = GetConstImageInfo(oat_it->second);
+ auto oat_it = dex_file_oat_index_map_.find(dex_file);
+ DCHECK(oat_it != dex_file_oat_index_map_.end());
+ const ImageInfo& image_info = GetImageInfo(oat_it->second);
auto it = image_info.dex_cache_array_starts_.find(dex_file);
DCHECK(it != image_info.dex_cache_array_starts_.end());
return reinterpret_cast<PtrType>(
@@ -101,7 +101,13 @@ class ImageWriter FINAL {
it->second + offset);
}
- uint8_t* GetOatFileBegin(const char* oat_filename) const;
+ size_t GetOatFileOffset(size_t oat_index) const {
+ return GetImageInfo(oat_index).oat_offset_;
+ }
+
+ const uint8_t* GetOatFileBegin(size_t oat_index) const {
+ return GetImageInfo(oat_index).oat_file_begin_;
+ }
// If image_fd is not kInvalidFd, then we use that for the image file. Otherwise we open
// the names in image_filenames.
@@ -109,21 +115,32 @@ class ImageWriter FINAL {
// the names in oat_filenames.
bool Write(int image_fd,
const std::vector<const char*>& image_filenames,
- int oat_fd,
- const std::vector<const char*>& oat_filenames,
- const std::string& oat_location)
+ const std::vector<const char*>& oat_filenames)
REQUIRES(!Locks::mutator_lock_);
- uintptr_t GetOatDataBegin(const char* oat_filename) {
- return reinterpret_cast<uintptr_t>(GetImageInfo(oat_filename).oat_data_begin_);
+ uintptr_t GetOatDataBegin(size_t oat_index) {
+ return reinterpret_cast<uintptr_t>(GetImageInfo(oat_index).oat_data_begin_);
}
- const char* GetOatFilenameForDexCache(mirror::DexCache* dex_cache) const
+ // Get the index of the oat file containing the dex file.
+ //
+ // This "oat_index" is used to retrieve information about the the memory layout
+ // of the oat file and its associated image file, needed for link-time patching
+ // of references to the image or across oat files.
+ size_t GetOatIndexForDexFile(const DexFile* dex_file) const;
+
+ // Get the index of the oat file containing the dex file served by the dex cache.
+ size_t GetOatIndexForDexCache(mirror::DexCache* dex_cache) const
SHARED_REQUIRES(Locks::mutator_lock_);
- // Update the oat size for the given oat file. This will make the oat_offset for the next oat
- // file valid.
- void UpdateOatFile(File* oat_file, const char* oat_filename);
+ // Update the oat layout for the given oat file.
+ // This will make the oat_offset for the next oat file valid.
+ void UpdateOatFileLayout(size_t oat_index,
+ size_t oat_loaded_size,
+ size_t oat_data_offset,
+ size_t oat_data_size);
+ // Update information about the oat header, i.e. checksum and trampoline offsets.
+ void UpdateOatFileHeader(size_t oat_index, const OatHeader& oat_header);
private:
bool AllocMemory();
@@ -247,10 +264,13 @@ class ImageWriter FINAL {
// Offset of the oat file for this image from start of oat files. This is
// valid when the previous oat file has been written.
size_t oat_offset_ = 0;
- // Start of oatdata in the corresponding oat file. This is
- // valid when the images have been layed out.
- uint8_t* oat_data_begin_ = nullptr;
+ // Layout of the loaded ELF file containing the oat file, valid after UpdateOatFileLayout().
+ const uint8_t* oat_file_begin_ = nullptr;
+ size_t oat_loaded_size_ = 0;
+ const uint8_t* oat_data_begin_ = nullptr;
size_t oat_size_ = 0; // Size of the corresponding oat data.
+ // The oat header checksum, valid after UpdateOatFileHeader().
+ uint32_t oat_checksum_ = 0u;
// Image bitmap which lets us know where the objects inside of the image reside.
std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> image_bitmap_;
@@ -310,8 +330,8 @@ class ImageWriter FINAL {
mirror::Object* GetLocalAddress(mirror::Object* object) const
SHARED_REQUIRES(Locks::mutator_lock_) {
size_t offset = GetImageOffset(object);
- const char* oat_filename = GetOatFilename(object);
- const ImageInfo& image_info = GetConstImageInfo(oat_filename);
+ size_t oat_index = GetOatIndex(object);
+ const ImageInfo& image_info = GetImageInfo(oat_index);
uint8_t* dst = image_info.image_->Begin() + offset;
return reinterpret_cast<mirror::Object*>(dst);
}
@@ -348,9 +368,9 @@ class ImageWriter FINAL {
// Lays out where the image objects will be at runtime.
void CalculateNewObjectOffsets()
SHARED_REQUIRES(Locks::mutator_lock_);
- void CreateHeader(size_t oat_loaded_size, size_t oat_data_offset)
+ void CreateHeader(size_t oat_index)
SHARED_REQUIRES(Locks::mutator_lock_);
- mirror::ObjectArray<mirror::Object>* CreateImageRoots(const char* oat_filename) const
+ mirror::ObjectArray<mirror::Object>* CreateImageRoots(size_t oat_index) const
SHARED_REQUIRES(Locks::mutator_lock_);
void CalculateObjectBinSlots(mirror::Object* obj)
SHARED_REQUIRES(Locks::mutator_lock_);
@@ -367,7 +387,7 @@ class ImageWriter FINAL {
SHARED_REQUIRES(Locks::mutator_lock_);
// Creates the contiguous image in memory and adjusts pointers.
- void CopyAndFixupNativeData() SHARED_REQUIRES(Locks::mutator_lock_);
+ void CopyAndFixupNativeData(size_t oat_index) SHARED_REQUIRES(Locks::mutator_lock_);
void CopyAndFixupObjects() SHARED_REQUIRES(Locks::mutator_lock_);
static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg)
SHARED_REQUIRES(Locks::mutator_lock_);
@@ -392,9 +412,6 @@ class ImageWriter FINAL {
bool* quick_is_interpreted)
SHARED_REQUIRES(Locks::mutator_lock_);
- // Patches references in OatFile to expect runtime addresses.
- void SetOatChecksumFromElfFile(File* elf_file);
-
// Calculate the sum total of the bin slot sizes in [0, up_to). Defaults to all bins.
size_t GetBinSizeSum(ImageInfo& image_info, Bin up_to = kBinSize) const;
@@ -404,7 +421,7 @@ class ImageWriter FINAL {
// Assign the offset for an ArtMethod.
void AssignMethodOffset(ArtMethod* method,
NativeObjectRelocationType type,
- const char* oat_filename)
+ size_t oat_index)
SHARED_REQUIRES(Locks::mutator_lock_);
// Return true if klass is loaded by the boot class loader but not in the boot image.
@@ -443,15 +460,21 @@ class ImageWriter FINAL {
// Return true if ptr is within the boot oat file.
bool IsInBootOatFile(const void* ptr) const;
- const char* GetOatFilename(mirror::Object* object) const SHARED_REQUIRES(Locks::mutator_lock_);
+ // Get the index of the oat file associated with the object.
+ size_t GetOatIndex(mirror::Object* object) const SHARED_REQUIRES(Locks::mutator_lock_);
- const char* GetDefaultOatFilename() const {
- return default_oat_filename_;
+ // The oat index for shared data in multi-image and all data in single-image compilation.
+ size_t GetDefaultOatIndex() const {
+ return 0u;
}
- ImageInfo& GetImageInfo(const char* oat_filename);
- const ImageInfo& GetConstImageInfo(const char* oat_filename) const;
- const ImageInfo& GetImageInfo(size_t index) const;
+ ImageInfo& GetImageInfo(size_t oat_index) {
+ return image_infos_[oat_index];
+ }
+
+ const ImageInfo& GetImageInfo(size_t oat_index) const {
+ return image_infos_[oat_index];
+ }
// Find an already strong interned string in the other images or in the boot image. Used to
// remove duplicates in the multi image and app image case.
@@ -465,9 +488,6 @@ class ImageWriter FINAL {
// Offset from image_begin_ to where the first object is in image_.
size_t image_objects_offset_begin_;
- // oat file with code for this image
- OatFile* oat_file_;
-
// Pointer arrays that need to be updated. Since these are only some int and long arrays, we need
// to keep track. These include vtable arrays, iftable arrays, and dex caches.
std::unordered_map<mirror::PointerArray*, Bin> pointer_arrays_;
@@ -483,14 +503,14 @@ class ImageWriter FINAL {
// Size of pointers on the target architecture.
size_t target_ptr_size_;
- // Mapping of oat filename to image data.
- std::unordered_map<std::string, ImageInfo> image_info_map_;
+ // Image data indexed by the oat file index.
+ dchecked_vector<ImageInfo> image_infos_;
// ArtField, ArtMethod relocating map. These are allocated as array of structs but we want to
// have one entry per art field for convenience. ArtFields are placed right after the end of the
// image objects (aka sum of bin_slot_sizes_). ArtMethods are placed right after the ArtFields.
struct NativeObjectRelocation {
- const char* oat_filename;
+ size_t oat_index;
uintptr_t offset;
NativeObjectRelocationType type;
@@ -522,10 +542,11 @@ class ImageWriter FINAL {
// Which mode the image is stored as, see image.h
const ImageHeader::StorageMode image_storage_mode_;
- // Map of dex files to the oat filenames that they were compiled into.
- const std::unordered_map<const DexFile*, const char*>& dex_file_oat_filename_map_;
- const std::vector<const char*> oat_filenames_;
- const char* default_oat_filename_;
+ // The file names of oat files.
+ const std::vector<const char*>& oat_filenames_;
+
+ // Map of dex files to the indexes of oat files that they were compiled into.
+ const std::unordered_map<const DexFile*, size_t>& dex_file_oat_index_map_;
friend class ContainsBootClassLoaderNonImageClassVisitor;
friend class FixupClassVisitor;