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