#include "gc/space/space-inl.h"
#include "mirror/object.h"
+#include "oat_file.h"
namespace art {
namespace gc {
space::ImageSpace* image_space = space->AsImageSpace();
// Update the end to include the other non-heap sections.
space_end = RoundUp(reinterpret_cast<uintptr_t>(image_space->GetImageEnd()), kPageSize);
- uintptr_t oat_begin = reinterpret_cast<uintptr_t>(image_space->GetOatFileBegin());
- uintptr_t oat_end = reinterpret_cast<uintptr_t>(image_space->GetOatFileEnd());
- if (space_end == oat_begin) {
- DCHECK_GE(oat_end, oat_begin);
- space_end = oat_end;
+ // For the app image case, GetOatFileBegin is where the oat file was mapped during image
+ // creation, the actual oat file could be somewhere else.
+ const OatFile* const image_oat_file = image_space->GetOatFile();
+ if (image_oat_file != nullptr) {
+ uintptr_t oat_begin = reinterpret_cast<uintptr_t>(image_oat_file->Begin());
+ uintptr_t oat_end = reinterpret_cast<uintptr_t>(image_oat_file->End());
+ if (space_end == oat_begin) {
+ DCHECK_GE(oat_end, oat_begin);
+ space_end = oat_end;
+ }
}
}
if (cur_begin == 0u) {
}
largest_immune_region_.SetBegin(reinterpret_cast<mirror::Object*>(best_begin));
largest_immune_region_.SetEnd(reinterpret_cast<mirror::Object*>(best_end));
+ VLOG(gc) << "Immune region " << largest_immune_region_.Begin() << "-"
+ << largest_immune_region_.End();
}
void ImmuneSpaces::AddSpace(space::ContinuousSpace* space) {
EXPECT_EQ(reinterpret_cast<uint8_t*>(spaces.GetLargestImmuneRegion().End()), b.Limit());
}
+class DummyOatFile : public OatFile {
+ public:
+ DummyOatFile(uint8_t* begin, uint8_t* end) : OatFile("Location", /*is_executable*/ false) {
+ begin_ = begin;
+ end_ = end;
+ }
+};
+
class DummyImageSpace : public space::ImageSpace {
public:
- DummyImageSpace(MemMap* map, accounting::ContinuousSpaceBitmap* live_bitmap)
+ DummyImageSpace(MemMap* map,
+ accounting::ContinuousSpaceBitmap* live_bitmap,
+ std::unique_ptr<DummyOatFile>&& oat_file)
: ImageSpace("DummyImageSpace",
/*image_location*/"",
map,
live_bitmap,
- map->End()) {}
+ map->End()) {
+ oat_file_ = std::move(oat_file);
+ oat_file_non_owned_ = oat_file_.get();
+ }
- // OatSize is how large the oat file is after the image.
- static DummyImageSpace* Create(size_t size, size_t oat_size) {
+ // Size is the size of the image space, oat offset is where the oat file is located
+ // after the end of image space. oat_size is the size of the oat file.
+ static DummyImageSpace* Create(size_t size, size_t oat_offset, size_t oat_size) {
std::string error_str;
std::unique_ptr<MemMap> map(MemMap::MapAnonymous("DummyImageSpace",
nullptr,
if (live_bitmap == nullptr) {
return nullptr;
}
+ // The actual mapped oat file may not be directly after the image for the app image case.
+ std::unique_ptr<DummyOatFile> oat_file(new DummyOatFile(map->End() + oat_offset,
+ map->End() + oat_offset + oat_size));
// Create image header.
ImageSection sections[ImageHeader::kSectionCount];
new (map->Begin()) ImageHeader(
sections,
/*image_roots*/PointerToLowMemUInt32(map->Begin()) + 1,
/*oat_checksum*/0u,
+ // The oat file data in the header is always right after the image space.
/*oat_file_begin*/PointerToLowMemUInt32(map->End()),
/*oat_data_begin*/PointerToLowMemUInt32(map->End()),
/*oat_data_end*/PointerToLowMemUInt32(map->End() + oat_size),
/*is_pic*/false,
ImageHeader::kStorageModeUncompressed,
/*storage_size*/0u);
- return new DummyImageSpace(map.release(), live_bitmap.release());
+ return new DummyImageSpace(map.release(), live_bitmap.release(), std::move(oat_file));
}
};
ImmuneSpaces spaces;
constexpr size_t image_size = 123 * kPageSize;
constexpr size_t image_oat_size = 321 * kPageSize;
- std::unique_ptr<DummyImageSpace> image_space(DummyImageSpace::Create(image_size, image_oat_size));
+ std::unique_ptr<DummyImageSpace> image_space(DummyImageSpace::Create(image_size,
+ 0,
+ image_oat_size));
ASSERT_TRUE(image_space != nullptr);
const ImageHeader& image_header = image_space->GetImageHeader();
EXPECT_EQ(image_header.GetImageSize(), image_size);
EXPECT_EQ(reinterpret_cast<uint8_t*>(spaces.GetLargestImmuneRegion().Begin()),
image_space->Begin());
EXPECT_EQ(reinterpret_cast<uint8_t*>(spaces.GetLargestImmuneRegion().End()), space.Limit());
+ // Check that appending with a gap between the map does not include the oat file.
+ image_space.reset(DummyImageSpace::Create(image_size, kPageSize, image_oat_size));
+ spaces.Reset();
+ {
+ WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
+ spaces.AddSpace(image_space.get());
+ }
+ EXPECT_EQ(reinterpret_cast<uint8_t*>(spaces.GetLargestImmuneRegion().Begin()),
+ image_space->Begin());
+ // Size should be equal, we should not add the oat file since it is not adjacent to the image
+ // space.
+ EXPECT_EQ(spaces.GetLargestImmuneRegion().Size(), image_size);
}
} // namespace collector