Move ArtField to native
Add linear alloc. Moved ArtField to be native object. Changed image
writer to put ArtFields after the mirror section.
Savings:
2MB on low ram devices
4MB on normal devices
Total PSS measurements before (normal N5, 95s after shell start):
Image size: 7729152 bytes
23112 kB: .NonMoving
23212 kB: .NonMoving
22868 kB: .NonMoving
23072 kB: .NonMoving
22836 kB: .NonMoving
19618 kB: .Zygote
19850 kB: .Zygote
19623 kB: .Zygote
19924 kB: .Zygote
19612 kB: .Zygote
Avg: 42745.4 kB
After:
Image size: 7462912 bytes
17440 kB: .NonMoving
16776 kB: .NonMoving
16804 kB: .NonMoving
17812 kB: .NonMoving
16820 kB: .NonMoving
18788 kB: .Zygote
18856 kB: .Zygote
19064 kB: .Zygote
18841 kB: .Zygote
18629 kB: .Zygote
3499 kB: .LinearAlloc
3408 kB: .LinearAlloc
3424 kB: .LinearAlloc
3600 kB: .LinearAlloc
3436 kB: .LinearAlloc
Avg: 39439.4 kB
No reflection performance changes.
Bug: 19264997
Bug: 17643507
Change-Id: I10c73a37913332080aeb978c7c94713bdfe4fe1c
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 1fb3252..e28e8d7 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -43,8 +43,9 @@
Atomic<uint32_t> ImageSpace::bitmap_index_(0);
ImageSpace::ImageSpace(const std::string& image_filename, const char* image_location,
- MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap)
- : MemMapSpace(image_filename, mem_map, mem_map->Begin(), mem_map->End(), mem_map->End(),
+ MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap,
+ uint8_t* end)
+ : MemMapSpace(image_filename, mem_map, mem_map->Begin(), end, end,
kGcRetentionPolicyNeverCollect),
image_location_(image_location) {
DCHECK(live_bitmap != nullptr);
@@ -642,10 +643,10 @@
void ImageSpace::VerifyImageAllocations() {
uint8_t* current = Begin() + RoundUp(sizeof(ImageHeader), kObjectAlignment);
while (current < End()) {
- DCHECK_ALIGNED(current, kObjectAlignment);
- mirror::Object* obj = reinterpret_cast<mirror::Object*>(current);
- CHECK(live_bitmap_->Test(obj));
+ CHECK_ALIGNED(current, kObjectAlignment);
+ auto* obj = reinterpret_cast<mirror::Object*>(current);
CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class";
+ CHECK(live_bitmap_->Test(obj)) << PrettyTypeOf(obj);
if (kUseBakerOrBrooksReadBarrier) {
obj->AssertReadBarrierPointer();
}
@@ -675,7 +676,6 @@
*error_msg = StringPrintf("Invalid image header in '%s'", image_filename);
return nullptr;
}
-
// Check that the file is large enough.
uint64_t image_file_size = static_cast<uint64_t>(file->GetLength());
if (image_header.GetImageSize() > image_file_size) {
@@ -683,23 +683,18 @@
image_file_size, image_header.GetImageSize());
return nullptr;
}
- if (image_header.GetBitmapOffset() + image_header.GetImageBitmapSize() != image_file_size) {
- *error_msg = StringPrintf("Image file too small for image bitmap: %" PRIu64 " vs. %zu.",
- image_file_size,
- image_header.GetBitmapOffset() + image_header.GetImageBitmapSize());
+ auto end_of_bitmap = image_header.GetImageBitmapOffset() + image_header.GetImageBitmapSize();
+ if (end_of_bitmap != image_file_size) {
+ *error_msg = StringPrintf(
+ "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.", image_file_size,
+ end_of_bitmap);
return nullptr;
}
// Note: The image header is part of the image due to mmap page alignment required of offset.
- std::unique_ptr<MemMap> map(MemMap::MapFileAtAddress(image_header.GetImageBegin(),
- image_header.GetImageSize(),
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE,
- file->Fd(),
- 0,
- false,
- image_filename,
- error_msg));
+ std::unique_ptr<MemMap> map(MemMap::MapFileAtAddress(
+ image_header.GetImageBegin(), image_header.GetImageSize() + image_header.GetArtFieldsSize(),
+ PROT_READ | PROT_WRITE, MAP_PRIVATE, file->Fd(), 0, false, image_filename, error_msg));
if (map.get() == NULL) {
DCHECK(!error_msg->empty());
return nullptr;
@@ -710,7 +705,7 @@
std::unique_ptr<MemMap> image_map(
MemMap::MapFileAtAddress(nullptr, image_header.GetImageBitmapSize(),
PROT_READ, MAP_PRIVATE,
- file->Fd(), image_header.GetBitmapOffset(),
+ file->Fd(), image_header.GetImageBitmapOffset(),
false,
image_filename,
error_msg));
@@ -730,8 +725,9 @@
return nullptr;
}
+ uint8_t* const image_end = map->Begin() + image_header.GetImageSize();
std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename, image_location,
- map.release(), bitmap.release()));
+ map.release(), bitmap.release(), image_end));
// VerifyImageAllocations() will be called later in Runtime::Init()
// as some class roots like ArtMethod::java_lang_reflect_ArtMethod_