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);
}
diff --git a/compiler/utils/dex_cache_arrays_layout.h b/compiler/utils/dex_cache_arrays_layout.h
index b461256..8f98ea1 100644
--- a/compiler/utils/dex_cache_arrays_layout.h
+++ b/compiler/utils/dex_cache_arrays_layout.h
@@ -29,6 +29,7 @@
// Construct an invalid layout.
DexCacheArraysLayout()
: /* types_offset_ is always 0u */
+ pointer_size_(0u),
methods_offset_(0u),
strings_offset_(0u),
fields_offset_(0u),
@@ -36,7 +37,7 @@
}
// Construct a layout for a particular dex file.
- explicit DexCacheArraysLayout(const DexFile* dex_file);
+ explicit DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file);
bool Valid() const {
return Size() != 0u;
@@ -52,36 +53,43 @@
size_t TypeOffset(uint32_t type_idx) const;
+ size_t TypesSize(size_t num_elements) const;
+
size_t MethodsOffset() const {
return methods_offset_;
}
size_t MethodOffset(uint32_t method_idx) const;
+ size_t MethodsSize(size_t num_elements) const;
+
size_t StringsOffset() const {
return strings_offset_;
}
size_t StringOffset(uint32_t string_idx) const;
+ size_t StringsSize(size_t num_elements) const;
+
size_t FieldsOffset() const {
return fields_offset_;
}
size_t FieldOffset(uint32_t field_idx) const;
+ size_t FieldsSize(size_t num_elements) const;
+
private:
static constexpr size_t types_offset_ = 0u;
+ const size_t pointer_size_; // Must be first for construction initialization order.
const size_t methods_offset_;
const size_t strings_offset_;
const size_t fields_offset_;
const size_t size_;
- template <typename MirrorType>
- static size_t ElementOffset(uint32_t idx);
+ static size_t ElementOffset(size_t element_size, uint32_t idx);
- template <typename MirrorType>
- static size_t ArraySize(uint32_t num_elements);
+ static size_t ArraySize(size_t element_size, uint32_t num_elements);
};
} // namespace art