Clean up retrieving boot image address range.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I8f36ae59399e4fa97576bbb8d71e29f9f40c0c91
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 947fdcb..e52fe9c 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -2687,13 +2687,6 @@
               << " Oat data end=" << reinterpret_cast<uintptr_t>(oat_data_end)
               << " Oat file end=" << reinterpret_cast<uintptr_t>(oat_file_end);
   }
-  // Store boot image info for app image so that we can relocate.
-  uint32_t boot_image_begin = 0;
-  uint32_t boot_image_end = 0;
-  uint32_t boot_oat_begin = 0;
-  uint32_t boot_oat_end = 0;
-  gc::Heap* const heap = Runtime::Current()->GetHeap();
-  heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end);
 
   // Create the header, leave 0 for data size since we will fill this in as we are writing the
   // image.
@@ -2709,8 +2702,8 @@
       PointerToLowMemUInt32(image_info.oat_data_begin_),
       PointerToLowMemUInt32(oat_data_end),
       PointerToLowMemUInt32(oat_file_end),
-      boot_image_begin,
-      boot_oat_end - boot_image_begin,
+      boot_image_begin_,
+      boot_image_size_,
       static_cast<uint32_t>(target_ptr_size_));
 }
 
@@ -3616,43 +3609,6 @@
   }
 }
 
-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,
@@ -3662,8 +3618,8 @@
     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_)),
+      boot_image_begin_(Runtime::Current()->GetHeap()->GetBootImagesStartAddress()),
+      boot_image_size_(Runtime::Current()->GetHeap()->GetBootImagesSize()),
       global_image_begin_(reinterpret_cast<uint8_t*>(image_begin)),
       image_objects_offset_begin_(0),
       target_ptr_size_(InstructionSetPointerSize(compiler_options.GetInstructionSet())),
@@ -3677,6 +3633,8 @@
       dex_file_oat_index_map_(dex_file_oat_index_map),
       dirty_image_objects_(dirty_image_objects) {
   DCHECK(compiler_options.IsBootImage() || compiler_options.IsAppImage());
+  DCHECK_EQ(compiler_options.IsBootImage(), boot_image_begin_ == 0u);
+  DCHECK_EQ(compiler_options.IsBootImage(), boot_image_size_ == 0u);
   CHECK_NE(image_begin, 0U);
   std::fill_n(image_methods_, arraysize(image_methods_), nullptr);
   CHECK_EQ(compiler_options.IsBootImage(),
diff --git a/dex2oat/linker/image_writer.h b/dex2oat/linker/image_writer.h
index 4d1adb6..c13c7c2 100644
--- a/dex2oat/linker/image_writer.h
+++ b/dex2oat/linker/image_writer.h
@@ -669,8 +669,8 @@
   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_;
+  const uint32_t boot_image_begin_;
+  const uint32_t boot_image_size_;
 
   // Beginning target image address for the first image.
   uint8_t* global_image_begin_;
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 59d7953..07704fa 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -4008,33 +4008,46 @@
   return false;
 }
 
-void Heap::GetBootImagesSize(uint32_t* boot_image_begin,
-                             uint32_t* boot_image_end,
-                             uint32_t* boot_oat_begin,
-                             uint32_t* boot_oat_end) {
-  DCHECK(boot_image_begin != nullptr);
-  DCHECK(boot_image_end != nullptr);
-  DCHECK(boot_oat_begin != nullptr);
-  DCHECK(boot_oat_end != nullptr);
-  *boot_image_begin = 0u;
-  *boot_image_end = 0u;
-  *boot_oat_begin = 0u;
-  *boot_oat_end = 0u;
-  for (gc::space::ImageSpace* space_ : GetBootImageSpaces()) {
-    const uint32_t image_begin = PointerToLowMemUInt32(space_->Begin());
-    const uint32_t image_size = space_->GetImageHeader().GetImageSize();
-    if (*boot_image_begin == 0 || image_begin < *boot_image_begin) {
-      *boot_image_begin = image_begin;
+uint32_t Heap::GetBootImagesStartAddress() const {
+  const std::vector<gc::space::ImageSpace*>& image_spaces = GetBootImageSpaces();
+  return image_spaces.empty() ? 0u : PointerToLowMemUInt32(image_spaces.front()->Begin());
+}
+
+uint32_t Heap::GetBootImagesSize() const {
+  const std::vector<gc::space::ImageSpace*>& image_spaces = GetBootImageSpaces();
+  uint32_t boot_image_size = 0u;
+  for (size_t i = 0u, num_spaces = image_spaces.size(); i != num_spaces; ) {
+    const ImageHeader& image_header = image_spaces[i]->GetImageHeader();
+    uint32_t reservation_size = image_header.GetImageReservationSize();
+    uint32_t component_count = image_header.GetComponentCount();
+    if (kIsDebugBuild) {
+      CHECK_NE(component_count, 0u);
+      CHECK_LE(component_count, num_spaces - i);
+      CHECK_NE(reservation_size, 0u);
+      for (size_t j = 1u; j != image_header.GetComponentCount(); ++j) {
+        CHECK_EQ(image_spaces[i + j]->GetImageHeader().GetComponentCount(), 0u);
+        CHECK_EQ(image_spaces[i + j]->GetImageHeader().GetImageReservationSize(), 0u);
+      }
+      // Check the start of the heap.
+      CHECK_EQ(image_spaces[0]->Begin() + boot_image_size, image_spaces[i]->Begin());
+      // Check contiguous layout of images and oat files.
+      const uint8_t* current_heap = image_spaces[i]->Begin();
+      const uint8_t* current_oat = image_spaces[i]->GetImageHeader().GetOatFileBegin();
+      for (size_t j = 0u; j != image_header.GetComponentCount(); ++j) {
+        CHECK_EQ(current_heap, image_spaces[i + j]->Begin());
+        CHECK_EQ(current_oat, image_spaces[i + j]->GetImageHeader().GetOatFileBegin());
+        current_heap += RoundUp(image_spaces[i + j]->GetImageHeader().GetImageSize(), kPageSize);
+        current_oat = image_spaces[i + j]->GetImageHeader().GetOatFileEnd();
+      }
+      // Check that oat files start at the end of images.
+      CHECK_EQ(current_heap, image_spaces[i]->GetImageHeader().GetOatFileBegin());
+      // Check that the reservation size equals the size of images and oat files.
+      CHECK_EQ(reservation_size, static_cast<size_t>(current_oat - image_spaces[i]->Begin()));
     }
-    *boot_image_end = std::max(*boot_image_end, image_begin + image_size);
-    const OatFile* boot_oat_file = space_->GetOatFile();
-    const uint32_t oat_begin = PointerToLowMemUInt32(boot_oat_file->Begin());
-    const uint32_t oat_size = boot_oat_file->Size();
-    if (*boot_oat_begin == 0 || oat_begin < *boot_oat_begin) {
-      *boot_oat_begin = oat_begin;
-    }
-    *boot_oat_end = std::max(*boot_oat_end, oat_begin + oat_size);
+    boot_image_size += reservation_size;
+    i += component_count;
   }
+  return boot_image_size;
 }
 
 void Heap::SetAllocationListener(AllocationListener* l) {
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index d2c5fcb..20feaf7 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -684,10 +684,11 @@
   bool IsInBootImageOatFile(const void* p) const
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  void GetBootImagesSize(uint32_t* boot_image_begin,
-                         uint32_t* boot_image_end,
-                         uint32_t* boot_oat_begin,
-                         uint32_t* boot_oat_end);
+  // Get the start address of the boot images if any; otherwise returns 0.
+  uint32_t GetBootImagesStartAddress() const;
+
+  // Get the size of all boot images, including the heap and oat areas.
+  uint32_t GetBootImagesSize() const;
 
   space::DlMallocSpace* GetDlMallocSpace() const {
     return dlmalloc_space_;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 689c9ab..40b434d 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1143,21 +1143,13 @@
                               std::string* error_msg) {
     DCHECK(error_msg != nullptr);
     // Set up sections.
-    uint32_t boot_image_begin = 0;
-    uint32_t boot_image_end = 0;
-    uint32_t boot_oat_begin = 0;
-    uint32_t boot_oat_end = 0;
     gc::Heap* const heap = Runtime::Current()->GetHeap();
-    heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end);
-    if (boot_image_begin == boot_image_end) {
+    uint32_t boot_image_begin = heap->GetBootImagesStartAddress();
+    uint32_t boot_image_size = heap->GetBootImagesSize();
+    if (boot_image_size == 0u) {
       *error_msg = "Can not relocate app image without boot image space";
       return false;
     }
-    if (boot_oat_begin == boot_oat_end) {
-      *error_msg = "Can not relocate app image without boot oat file";
-      return false;
-    }
-    const uint32_t boot_image_size = boot_oat_end - boot_image_begin;
     const uint32_t image_header_boot_image_size = image_header.GetBootImageSize();
     if (boot_image_size != image_header_boot_image_size) {
       *error_msg = StringPrintf("Boot image size %" PRIu64 " does not match expected size %"