diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-03-27 14:35:38 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-04-10 12:57:27 -0700 |
commit | c785344b87221f5e4e6473e5b762e4e61fe65dcf (patch) | |
tree | cd32ad2c2604596a18926f04d4c313dab255ecfd /runtime/gc | |
parent | a29d93b380c9aeb8270e281aefbdd0c77a430d43 (diff) | |
download | art-c785344b87221f5e4e6473e5b762e4e61fe65dcf.zip art-c785344b87221f5e4e6473e5b762e4e61fe65dcf.tar.gz art-c785344b87221f5e4e6473e5b762e4e61fe65dcf.tar.bz2 |
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
Diffstat (limited to 'runtime/gc')
-rw-r--r-- | runtime/gc/accounting/mod_union_table.cc | 1 | ||||
-rw-r--r-- | runtime/gc/accounting/remembered_set.cc | 1 | ||||
-rw-r--r-- | runtime/gc/accounting/space_bitmap.cc | 34 | ||||
-rw-r--r-- | runtime/gc/collector/concurrent_copying.cc | 2 | ||||
-rw-r--r-- | runtime/gc/collector/mark_compact.cc | 2 | ||||
-rw-r--r-- | runtime/gc/collector/mark_sweep-inl.h | 3 | ||||
-rw-r--r-- | runtime/gc/collector/mark_sweep.cc | 1 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 18 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 38 | ||||
-rw-r--r-- | runtime/gc/space/image_space.h | 2 |
10 files changed, 44 insertions, 58 deletions
diff --git a/runtime/gc/accounting/mod_union_table.cc b/runtime/gc/accounting/mod_union_table.cc index a3fac58..cd3f910 100644 --- a/runtime/gc/accounting/mod_union_table.cc +++ b/runtime/gc/accounting/mod_union_table.cc @@ -28,7 +28,6 @@ #include "gc/heap.h" #include "gc/space/space.h" #include "gc/space/image_space.h" -#include "mirror/art_field-inl.h" #include "mirror/object-inl.h" #include "mirror/class-inl.h" #include "mirror/object_array-inl.h" diff --git a/runtime/gc/accounting/remembered_set.cc b/runtime/gc/accounting/remembered_set.cc index b16a146..eeb385e 100644 --- a/runtime/gc/accounting/remembered_set.cc +++ b/runtime/gc/accounting/remembered_set.cc @@ -26,7 +26,6 @@ #include "gc/collector/semi_space.h" #include "gc/heap.h" #include "gc/space/space.h" -#include "mirror/art_field-inl.h" #include "mirror/object-inl.h" #include "mirror/class-inl.h" #include "mirror/object_array-inl.h" diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc index ad8d988..2da8325 100644 --- a/runtime/gc/accounting/space_bitmap.cc +++ b/runtime/gc/accounting/space_bitmap.cc @@ -16,12 +16,12 @@ #include "space_bitmap-inl.h" +#include "art_field-inl.h" #include "base/stringprintf.h" #include "dex_file-inl.h" #include "mem_map.h" #include "mirror/object-inl.h" #include "mirror/class.h" -#include "mirror/art_field.h" #include "mirror/object_array.h" namespace art { @@ -190,15 +190,13 @@ void SpaceBitmap<kAlignment>::WalkInstanceFields(SpaceBitmap<kAlignment>* visite WalkInstanceFields(visited, callback, obj, super, arg); } // Walk instance fields - mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields(); - if (fields != NULL) { - for (int32_t i = 0; i < fields->GetLength(); i++) { - mirror::ArtField* field = fields->Get(i); - if (!field->IsPrimitiveType()) { - mirror::Object* value = field->GetObj(obj); - if (value != NULL) { - WalkFieldsInOrder(visited, callback, value, arg); - } + auto* fields = klass->GetIFields(); + for (size_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) { + ArtField* field = &fields[i]; + if (!field->IsPrimitiveType()) { + mirror::Object* value = field->GetObj(obj); + if (value != nullptr) { + WalkFieldsInOrder(visited, callback, value, arg); } } } @@ -219,15 +217,13 @@ void SpaceBitmap<kAlignment>::WalkFieldsInOrder(SpaceBitmap<kAlignment>* visited WalkInstanceFields(visited, callback, obj, klass, arg); // Walk static fields of a Class if (obj->IsClass()) { - mirror::ObjectArray<mirror::ArtField>* fields = klass->GetSFields(); - if (fields != NULL) { - for (int32_t i = 0; i < fields->GetLength(); i++) { - mirror::ArtField* field = fields->Get(i); - if (!field->IsPrimitiveType()) { - mirror::Object* value = field->GetObj(NULL); - if (value != NULL) { - WalkFieldsInOrder(visited, callback, value, arg); - } + auto* sfields = klass->GetSFields(); + for (size_t i = 0, count = klass->NumStaticFields(); i < count; ++i) { + ArtField* field = &sfields[i]; + if (!field->IsPrimitiveType()) { + mirror::Object* value = field->GetObj(nullptr); + if (value != nullptr) { + WalkFieldsInOrder(visited, callback, value, arg); } } } diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc index 6a68880..eabb1c2 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -16,12 +16,12 @@ #include "concurrent_copying.h" +#include "art_field-inl.h" #include "gc/accounting/heap_bitmap-inl.h" #include "gc/accounting/space_bitmap-inl.h" #include "gc/space/image_space.h" #include "gc/space/space.h" #include "intern_table.h" -#include "mirror/art_field-inl.h" #include "mirror/object-inl.h" #include "scoped_thread_state_change.h" #include "thread-inl.h" diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc index 8902df8..3c247cd 100644 --- a/runtime/gc/collector/mark_compact.cc +++ b/runtime/gc/collector/mark_compact.cc @@ -35,8 +35,6 @@ #include "jni_internal.h" #include "mark_sweep-inl.h" #include "monitor.h" -#include "mirror/art_field.h" -#include "mirror/art_field-inl.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache.h" diff --git a/runtime/gc/collector/mark_sweep-inl.h b/runtime/gc/collector/mark_sweep-inl.h index 104ed36..4e3845e 100644 --- a/runtime/gc/collector/mark_sweep-inl.h +++ b/runtime/gc/collector/mark_sweep-inl.h @@ -17,10 +17,9 @@ #ifndef ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_ #define ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_ -#include "gc/collector/mark_sweep.h" +#include "mark_sweep.h" #include "gc/heap.h" -#include "mirror/art_field.h" #include "mirror/class-inl.h" #include "mirror/object_array-inl.h" #include "mirror/reference.h" diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index 79d1034..ed2e295 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -39,7 +39,6 @@ #include "gc/space/large_object_space.h" #include "gc/space/space-inl.h" #include "mark_sweep-inl.h" -#include "mirror/art_field-inl.h" #include "mirror/object-inl.h" #include "runtime.h" #include "scoped_thread_state_change.h" diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index b9153c1..83da5a8 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -23,6 +23,7 @@ #include <memory> #include <vector> +#include "art_field-inl.h" #include "base/allocator.h" #include "base/dumpable.h" #include "base/histogram-inl.h" @@ -58,7 +59,6 @@ #include "heap-inl.h" #include "image.h" #include "intern_table.h" -#include "mirror/art_field-inl.h" #include "mirror/class-inl.h" #include "mirror/object.h" #include "mirror/object-inl.h" @@ -233,7 +233,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max CHECK_GT(oat_file_end_addr, image_space->End()); requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize); } else { - LOG(WARNING) << "Could not create image space with image file '" << image_file_name << "'. " + LOG(ERROR) << "Could not create image space with image file '" << image_file_name << "'. " << "Attempting to fall back to imageless running. Error was: " << error_msg; } } @@ -482,7 +482,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max non_moving_space_->GetMemMap()); if (!no_gap) { MemMap::DumpMaps(LOG(ERROR)); - LOG(FATAL) << "There's a gap between the image space and the main space"; + LOG(FATAL) << "There's a gap between the image space and the non-moving space"; } } if (running_on_valgrind_) { @@ -2708,12 +2708,12 @@ class VerifyReferenceCardVisitor { // Print which field of the object is dead. if (!obj->IsObjectArray()) { mirror::Class* klass = is_static ? obj->AsClass() : obj->GetClass(); - CHECK(klass != NULL); - mirror::ObjectArray<mirror::ArtField>* fields = is_static ? klass->GetSFields() - : klass->GetIFields(); - CHECK(fields != NULL); - for (int32_t i = 0; i < fields->GetLength(); ++i) { - mirror::ArtField* cur = fields->Get(i); + CHECK(klass != nullptr); + auto* fields = is_static ? klass->GetSFields() : klass->GetIFields(); + auto num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields(); + CHECK_EQ(fields == nullptr, num_fields == 0u); + for (size_t i = 0; i < num_fields; ++i) { + ArtField* cur = &fields[i]; if (cur->GetOffset().Int32Value() == offset.Int32Value()) { LOG(ERROR) << (is_static ? "Static " : "") << "field in the live stack is " << PrettyField(cur); 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 @@ namespace space { 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 @@ ImageSpace* ImageSpace::Create(const char* image_location, 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 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat *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 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat 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 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat 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 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat 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_ diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h index d7f8057..9ae2af4 100644 --- a/runtime/gc/space/image_space.h +++ b/runtime/gc/space/image_space.h @@ -145,7 +145,7 @@ class ImageSpace : public MemMapSpace { std::unique_ptr<accounting::ContinuousSpaceBitmap> live_bitmap_; ImageSpace(const std::string& name, const char* image_location, - MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap); + MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap, uint8_t* end); // The OatFile associated with the image during early startup to // reserve space contiguous to the image. It is later released to |