Further clean up boot image address checks.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Change-Id: Ib7abd10e94e995e61549b3a3111a640802b5e700
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 07704fa..eab292c 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -167,6 +167,44 @@
   return Runtime::Current()->InJankPerceptibleProcessState();
 }
 
+static void VerifyBootImagesContiguity(const std::vector<gc::space::ImageSpace*>& image_spaces) {
+  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();
+
+    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) {
+      const ImageHeader& current_header = image_spaces[i + j]->GetImageHeader();
+      CHECK_EQ(current_heap, image_spaces[i + j]->Begin());
+      CHECK_EQ(current_oat, current_header.GetOatFileBegin());
+      current_heap += RoundUp(current_header.GetImageSize(), kPageSize);
+      CHECK_GT(current_header.GetOatFileEnd(), current_header.GetOatFileBegin());
+      current_oat = current_header.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_size += reservation_size;
+    i += component_count;
+  }
+}
+
 Heap::Heap(size_t initial_size,
            size_t growth_limit,
            size_t min_free,
@@ -308,7 +346,10 @@
       unique_backtrace_count_(0u),
       gc_disabled_for_shutdown_(false),
       dump_region_info_before_gc_(dump_region_info_before_gc),
-      dump_region_info_after_gc_(dump_region_info_after_gc) {
+      dump_region_info_after_gc_(dump_region_info_after_gc),
+      boot_image_spaces_(),
+      boot_images_start_address_(0u),
+      boot_images_size_(0u) {
   if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {
     LOG(INFO) << "Heap() entering";
   }
@@ -387,6 +428,13 @@
       boot_image_spaces_.push_back(space.get());
       AddSpace(space.release());
     }
+    boot_images_start_address_ = PointerToLowMemUInt32(boot_image_spaces_.front()->Begin());
+    uint32_t boot_images_end =
+        PointerToLowMemUInt32(boot_image_spaces_.back()->GetImageHeader().GetOatFileEnd());
+    boot_images_size_ = boot_images_end - boot_images_start_address_;
+    if (kIsDebugBuild) {
+      VerifyBootImagesContiguity(boot_image_spaces_);
+    }
   } else {
     if (foreground_collector_type_ == kCollectorTypeCC) {
       // Need to use a low address so that we can allocate a contiguous 2 * Xmx space
@@ -3991,63 +4039,23 @@
 }
 
 bool Heap::ObjectIsInBootImageSpace(ObjPtr<mirror::Object> obj) const {
-  for (gc::space::ImageSpace* space : boot_image_spaces_) {
-    if (space->HasAddress(obj.Ptr())) {
-      return true;
-    }
-  }
-  return false;
+  DCHECK_EQ(IsBootImageAddress(obj.Ptr()),
+            any_of(boot_image_spaces_.begin(),
+                   boot_image_spaces_.end(),
+                   [obj](gc::space::ImageSpace* space) REQUIRES_SHARED(Locks::mutator_lock_) {
+                     return space->HasAddress(obj.Ptr());
+                   }));
+  return IsBootImageAddress(obj.Ptr());
 }
 
 bool Heap::IsInBootImageOatFile(const void* p) const {
-  for (gc::space::ImageSpace* space : boot_image_spaces_) {
-    if (space->GetOatFile()->Contains(p)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-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_size += reservation_size;
-    i += component_count;
-  }
-  return boot_image_size;
+  DCHECK_EQ(IsBootImageAddress(p),
+            any_of(boot_image_spaces_.begin(),
+                   boot_image_spaces_.end(),
+                   [p](gc::space::ImageSpace* space) REQUIRES_SHARED(Locks::mutator_lock_) {
+                     return space->GetOatFile()->Contains(p);
+                   }));
+  return IsBootImageAddress(p);
 }
 
 void Heap::SetAllocationListener(AllocationListener* l) {