summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/sharpening.cc18
-rw-r--r--runtime/gc/heap.cc118
-rw-r--r--runtime/gc/heap.h17
-rw-r--r--runtime/oat_file.cc3
4 files changed, 88 insertions, 68 deletions
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 03d277f648..77b41abf7d 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -38,15 +38,15 @@
namespace art {
static bool IsInBootImage(ArtMethod* method) {
- const std::vector<gc::space::ImageSpace*>& image_spaces =
- Runtime::Current()->GetHeap()->GetBootImageSpaces();
- for (gc::space::ImageSpace* image_space : image_spaces) {
- const ImageSection& method_section = image_space->GetImageHeader().GetMethodsSection();
- if (method_section.Contains(reinterpret_cast<uint8_t*>(method) - image_space->Begin())) {
- return true;
- }
- }
- return false;
+ gc::Heap* heap = Runtime::Current()->GetHeap();
+ DCHECK_EQ(heap->IsBootImageAddress(method),
+ std::any_of(heap->GetBootImageSpaces().begin(),
+ heap->GetBootImageSpaces().end(),
+ [=](gc::space::ImageSpace* space) REQUIRES_SHARED(Locks::mutator_lock_) {
+ return space->GetImageHeader().GetMethodsSection().Contains(
+ reinterpret_cast<uint8_t*>(method) - space->Begin());
+ }));
+ return heap->IsBootImageAddress(method);
}
static bool BootImageAOTCanEmbedMethod(ArtMethod* method, const CompilerOptions& compiler_options) {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 07704fa80b..eab292c94d 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -167,6 +167,44 @@ static inline bool CareAboutPauseTimes() {
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 @@ Heap::Heap(size_t initial_size,
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 @@ Heap::Heap(size_t initial_size,
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 @@ void Heap::DisableGCForShutdown() {
}
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) {
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 20feaf76d2..15534c9e00 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -685,10 +685,19 @@ class Heap {
REQUIRES_SHARED(Locks::mutator_lock_);
// Get the start address of the boot images if any; otherwise returns 0.
- uint32_t GetBootImagesStartAddress() const;
+ uint32_t GetBootImagesStartAddress() const {
+ return boot_images_start_address_;
+ }
// Get the size of all boot images, including the heap and oat areas.
- uint32_t GetBootImagesSize() const;
+ uint32_t GetBootImagesSize() const {
+ return boot_images_size_;
+ }
+
+ // Check if a pointer points to a boot image.
+ bool IsBootImageAddress(const void* p) const {
+ return reinterpret_cast<uintptr_t>(p) - boot_images_start_address_ < boot_images_size_;
+ }
space::DlMallocSpace* GetDlMallocSpace() const {
return dlmalloc_space_;
@@ -1553,6 +1562,10 @@ class Heap {
// Boot image spaces.
std::vector<space::ImageSpace*> boot_image_spaces_;
+ // Boot image address range. Includes images and oat files.
+ uint32_t boot_images_start_address_;
+ uint32_t boot_images_size_;
+
// An installed allocation listener.
Atomic<AllocationListener*> alloc_listener_;
// An installed GC Pause listener.
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 05015e371b..92c8cb5451 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -2225,8 +2225,7 @@ void OatFile::InitializeRelocations() const {
reloc_begin,
DataBimgRelRoSize(),
PROT_READ | PROT_WRITE);
- uint32_t boot_image_begin = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(
- Runtime::Current()->GetHeap()->GetBootImageSpaces().front()->Begin()));
+ uint32_t boot_image_begin = Runtime::Current()->GetHeap()->GetBootImagesStartAddress();
for (const uint32_t& relocation : GetBootImageRelocations()) {
const_cast<uint32_t&>(relocation) += boot_image_begin;
}