summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/linker/image_writer.cc57
-rw-r--r--dex2oat/linker/image_writer.h12
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_;