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) {