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/compiler/utils/dex_cache_arrays_layout-inl.h b/compiler/utils/dex_cache_arrays_layout-inl.h
index 7d02ce3..2c50c96 100644
--- a/compiler/utils/dex_cache_arrays_layout-inl.h
+++ b/compiler/utils/dex_cache_arrays_layout-inl.h
@@ -26,7 +26,6 @@
#include "utils.h"
namespace mirror {
-class ArtField;
class ArtMethod;
class Class;
class String;
@@ -34,40 +33,55 @@
namespace art {
-inline DexCacheArraysLayout::DexCacheArraysLayout(const DexFile* dex_file)
+inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file)
: /* types_offset_ is always 0u */
- methods_offset_(types_offset_ + ArraySize<mirror::Class>(dex_file->NumTypeIds())),
- strings_offset_(methods_offset_ + ArraySize<mirror::ArtMethod>(dex_file->NumMethodIds())),
- fields_offset_(strings_offset_ + ArraySize<mirror::String>(dex_file->NumStringIds())),
- size_(fields_offset_ + ArraySize<mirror::ArtField>(dex_file->NumFieldIds())) {
+ pointer_size_(pointer_size),
+ methods_offset_(types_offset_ + TypesSize(dex_file->NumTypeIds())),
+ strings_offset_(methods_offset_ + MethodsSize(dex_file->NumMethodIds())),
+ fields_offset_(strings_offset_ + StringsSize(dex_file->NumStringIds())),
+ size_(fields_offset_ + FieldsSize(dex_file->NumFieldIds())) {
+ DCHECK(pointer_size == 4u || pointer_size == 8u);
}
inline size_t DexCacheArraysLayout::TypeOffset(uint32_t type_idx) const {
- return types_offset_ + ElementOffset<mirror::Class>(type_idx);
+ return types_offset_ + ElementOffset(sizeof(mirror::HeapReference<mirror::Class>), type_idx);
+}
+
+inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const {
+ return ArraySize(sizeof(mirror::HeapReference<mirror::Class>), num_elements);
}
inline size_t DexCacheArraysLayout::MethodOffset(uint32_t method_idx) const {
- return methods_offset_ + ElementOffset<mirror::ArtMethod>(method_idx);
+ return methods_offset_ + ElementOffset(
+ sizeof(mirror::HeapReference<mirror::ArtMethod>), method_idx);
+}
+
+inline size_t DexCacheArraysLayout::MethodsSize(size_t num_elements) const {
+ return ArraySize(sizeof(mirror::HeapReference<mirror::ArtMethod>), num_elements);
}
inline size_t DexCacheArraysLayout::StringOffset(uint32_t string_idx) const {
- return strings_offset_ + ElementOffset<mirror::String>(string_idx);
+ return strings_offset_ + ElementOffset(sizeof(mirror::HeapReference<mirror::String>), string_idx);
+}
+
+inline size_t DexCacheArraysLayout::StringsSize(size_t num_elements) const {
+ return ArraySize(sizeof(mirror::HeapReference<mirror::String>), num_elements);
}
inline size_t DexCacheArraysLayout::FieldOffset(uint32_t field_idx) const {
- return fields_offset_ + ElementOffset<mirror::ArtField>(field_idx);
+ return fields_offset_ + ElementOffset(pointer_size_, field_idx);
}
-template <typename MirrorType>
-inline size_t DexCacheArraysLayout::ElementOffset(uint32_t idx) {
- return mirror::Array::DataOffset(sizeof(mirror::HeapReference<MirrorType>)).Uint32Value() +
- sizeof(mirror::HeapReference<MirrorType>) * idx;
+inline size_t DexCacheArraysLayout::FieldsSize(size_t num_elements) const {
+ return ArraySize(pointer_size_, num_elements);
}
-template <typename MirrorType>
-inline size_t DexCacheArraysLayout::ArraySize(uint32_t num_elements) {
- size_t array_size = mirror::ComputeArraySize(
- num_elements, ComponentSizeShiftWidth<sizeof(mirror::HeapReference<MirrorType>)>());
+inline size_t DexCacheArraysLayout::ElementOffset(size_t element_size, uint32_t idx) {
+ return mirror::Array::DataOffset(element_size).Uint32Value() + element_size * idx;
+}
+
+inline size_t DexCacheArraysLayout::ArraySize(size_t element_size, uint32_t num_elements) {
+ size_t array_size = mirror::ComputeArraySize(num_elements, ComponentSizeShiftWidth(element_size));
DCHECK_NE(array_size, 0u); // No overflow expected for dex cache arrays.
return RoundUp(array_size, kObjectAlignment);
}