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 %"