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_