Revert "Revert "Load app images""
This reverts commit 1bc977cf2f8199311a97f2ba9431a184540e3e9c.
Bug: 22858531
Change-Id: Ide00bf3a73a02cba3bb364177204ad1b13f70295
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 2fb5e34..8cd8d73 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -273,10 +273,11 @@
std::string& image_name = image_file_names[index];
ATRACE_BEGIN("ImageSpace::Create");
std::string error_msg;
- space::ImageSpace* boot_image_space = space::ImageSpace::Create(image_name.c_str(),
- image_instruction_set,
- index > 0,
- &error_msg);
+ space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage(
+ image_name.c_str(),
+ image_instruction_set,
+ index > 0,
+ &error_msg);
ATRACE_END();
if (boot_image_space != nullptr) {
AddSpace(boot_image_space);
@@ -491,7 +492,15 @@
ATRACE_END();
// Allocate the card table.
ATRACE_BEGIN("Create card table");
- card_table_.reset(accounting::CardTable::Create(heap_begin, heap_capacity));
+ // We currently don't support dynamically resizing the card table.
+ // Since we don't know where in the low_4gb the app image will be located, make the card table
+ // cover the whole low_4gb. TODO: Extend the card table in AddSpace.
+ UNUSED(heap_capacity);
+ // Start at 64 KB, we can be sure there are no spaces mapped this low since the address range is
+ // reserved by the kernel.
+ static constexpr size_t kMinHeapAddress = 4 * KB;
+ card_table_.reset(accounting::CardTable::Create(reinterpret_cast<uint8_t*>(kMinHeapAddress),
+ 4 * GB - kMinHeapAddress));
CHECK(card_table_.get() != nullptr) << "Failed to create card table";
ATRACE_END();
if (foreground_collector_type_ == kCollectorTypeCC && kUseTableLookupReadBarrier) {
@@ -1252,10 +1261,6 @@
return FindDiscontinuousSpaceFromObject(obj, fail_ok);
}
-std::vector<space::ImageSpace*> Heap::GetBootImageSpaces() const {
- return boot_image_spaces_;
-}
-
void Heap::ThrowOutOfMemoryError(Thread* self, size_t byte_count, AllocatorType allocator_type) {
std::ostringstream oss;
size_t total_bytes_free = GetFreeMemory();
@@ -3194,7 +3199,13 @@
} else if (process_alloc_space_cards) {
TimingLogger::ScopedTiming t2("AllocSpaceClearCards", timings);
if (clear_alloc_space_cards) {
- card_table_->ClearCardRange(space->Begin(), space->End());
+ uint8_t* end = space->End();
+ if (space->IsImageSpace()) {
+ // Image space end is the end of the mirror objects, it is not necessarily page or card
+ // aligned. Align up so that the check in ClearCardRange does not fail.
+ end = AlignUp(end, accounting::CardTable::kCardSize);
+ }
+ card_table_->ClearCardRange(space->Begin(), end);
} else {
// No mod union table for the AllocSpace. Age the cards so that the GC knows that these
// cards were dirty before the GC started.
@@ -3989,5 +4000,43 @@
gc_disabled_for_shutdown_ = true;
}
+bool Heap::ObjectIsInBootImageSpace(mirror::Object* obj) const {
+ for (gc::space::ImageSpace* space : boot_image_spaces_) {
+ if (space->HasAddress(obj)) {
+ return true;
+ }
+ }
+ 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;
+ }
+ *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);
+ }
+}
+
} // namespace gc
} // namespace art