diff options
-rw-r--r-- | compiler/optimizing/sharpening.cc | 18 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 118 | ||||
-rw-r--r-- | runtime/gc/heap.h | 17 | ||||
-rw-r--r-- | runtime/oat_file.cc | 3 |
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; } |