diff options
| -rw-r--r-- | dex2oat/linker/image_writer.cc | 57 | ||||
| -rw-r--r-- | dex2oat/linker/image_writer.h | 12 |
2 files changed, 48 insertions, 21 deletions
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc index 00080a080c..947fdcbfd8 100644 --- a/dex2oat/linker/image_writer.cc +++ b/dex2oat/linker/image_writer.cc @@ -223,24 +223,6 @@ bool ImageWriter::IsImageDexCache(ObjPtr<mirror::DexCache> dex_cache) const { return true; } -// Return true if an object is already in an image space. -bool ImageWriter::IsInBootImage(const void* obj) const { - gc::Heap* const heap = Runtime::Current()->GetHeap(); - if (compiler_options_.IsBootImage()) { - DCHECK(heap->GetBootImageSpaces().empty()); - return false; - } - for (gc::space::ImageSpace* boot_image_space : heap->GetBootImageSpaces()) { - const uint8_t* image_begin = boot_image_space->Begin(); - // Real image end including ArtMethods and ArtField sections. - const uint8_t* image_end = image_begin + boot_image_space->GetImageHeader().GetImageSize(); - if (image_begin <= obj && obj < image_end) { - return true; - } - } - return false; -} - bool ImageWriter::IsInBootOatFile(const void* ptr) const { gc::Heap* const heap = Runtime::Current()->GetHeap(); if (compiler_options_.IsBootImage()) { @@ -3634,6 +3616,43 @@ void ImageWriter::UpdateOatFileHeader(size_t oat_index, const OatHeader& oat_hea } } +static uintptr_t GetBootImageBegin(const CompilerOptions& compiler_options) { + if (compiler_options.IsBootImage()) { + DCHECK(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty()); + return 0u; + } else { + const std::vector<gc::space::ImageSpace*>& image_spaces = + Runtime::Current()->GetHeap()->GetBootImageSpaces(); + DCHECK(!image_spaces.empty()); + return reinterpret_cast<uintptr_t>(image_spaces.front()->Begin()); + } +} + +static size_t GetBootImageSize(const CompilerOptions& compiler_options) { + if (compiler_options.IsBootImage()) { + DCHECK(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty()); + return 0u; + } else { + const std::vector<gc::space::ImageSpace*>& image_spaces = + Runtime::Current()->GetHeap()->GetBootImageSpaces(); + DCHECK(!image_spaces.empty()); + size_t boot_image_size = 0u; + for (size_t i = 0, num_spaces = image_spaces.size(); i != num_spaces; ) { + const ImageHeader& image_header = image_spaces[i]->GetImageHeader(); + DCHECK_NE(image_header.GetComponentCount(), 0u); + DCHECK_LE(image_header.GetComponentCount(), num_spaces - i); + if (kIsDebugBuild) { + for (size_t j = 1u; j != image_header.GetComponentCount(); ++j) { + DCHECK_EQ(image_spaces[i + j]->GetImageHeader().GetComponentCount(), 0u); + } + } + boot_image_size += image_header.GetImageReservationSize(); + i += image_header.GetComponentCount(); + } + return boot_image_size; + } +} + ImageWriter::ImageWriter( const CompilerOptions& compiler_options, uintptr_t image_begin, @@ -3643,6 +3662,8 @@ ImageWriter::ImageWriter( jobject class_loader, const HashSet<std::string>* dirty_image_objects) : compiler_options_(compiler_options), + boot_image_begin_(GetBootImageBegin(compiler_options_)), + boot_image_size_(GetBootImageSize(compiler_options_)), global_image_begin_(reinterpret_cast<uint8_t*>(image_begin)), image_objects_offset_begin_(0), target_ptr_size_(InstructionSetPointerSize(compiler_options.GetInstructionSet())), diff --git a/dex2oat/linker/image_writer.h b/dex2oat/linker/image_writer.h index 11d35e7974..4d1adb6e77 100644 --- a/dex2oat/linker/image_writer.h +++ b/dex2oat/linker/image_writer.h @@ -610,9 +610,11 @@ class ImageWriter final { bool IsImageDexCache(ObjPtr<mirror::DexCache> dex_cache) const REQUIRES_SHARED(Locks::mutator_lock_); - // Return true if `obj` is inside of the boot image space. This may only return true if we are - // compiling an app image. - bool IsInBootImage(const void* obj) const; + // Return true if `obj` is inside of a boot image space that we're compiling against. + // (Always false when compiling the boot image.) + ALWAYS_INLINE bool IsInBootImage(const void* obj) const { + return reinterpret_cast<uintptr_t>(obj) - boot_image_begin_ < boot_image_size_; + } // Return true if ptr is within the boot oat file. bool IsInBootOatFile(const void* ptr) const; @@ -666,6 +668,10 @@ class ImageWriter final { const CompilerOptions& compiler_options_; + // Cached boot image begin and size. This includes heap, native objects and oat files. + const uintptr_t boot_image_begin_; + const size_t boot_image_size_; + // Beginning target image address for the first image. uint8_t* global_image_begin_; |