ART: Compress LengthPrefixedArray on 32-bit targets.

Previously, the LengthPrefixedArray<ArtMethod> on 32-bit
targets contained a 64-bit length field followed by the
ArtMethod elements with size only a multiple of 4, not 8.
Consequently, an odd-length array broke the alignment for
the following array which would have the 64-bit length
placed at an unaligned address.

To fix that, we make the length field 32-bit and explicitly
pass the alignment information to the LengthPrefixedArray.
This also makes the 32-bit boot image a bit smaller.
On Nexus 5, AOSP, ToT, the field section is 11528B smaller
and the method section is 21036B smaller. 64-bit targets
should see the same savings for the field section but no
difference for the methods section.

Change-Id: I3e03e7b94129025c8a1c117c27645a34dec516d2
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 5e29ca7..c8ecea0 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1618,9 +1618,7 @@
           const size_t pointer_size =
               InstructionSetPointerSize(oat_dumper_->GetOatInstructionSet());
           DumpArtMethodVisitor visitor(this);
-          methods_section.VisitPackedArtMethods(&visitor,
-                                                image_space->Begin(),
-                                                ArtMethod::ObjectSize(pointer_size));
+          methods_section.VisitPackedArtMethods(&visitor, image_space->Begin(), pointer_size);
         }
       }
       // Dump the large objects separately.
@@ -1642,13 +1640,19 @@
     const auto& intern_section = image_header_.GetImageSection(
         ImageHeader::kSectionInternedStrings);
     stats_.header_bytes = header_bytes;
-    size_t alignment_bytes = RoundUp(header_bytes, kObjectAlignment) - header_bytes;
-    stats_.alignment_bytes += alignment_bytes;
+    stats_.alignment_bytes += RoundUp(header_bytes, kObjectAlignment) - header_bytes;
+    // Add padding between the field and method section.
+    // (Field section is 4-byte aligned, method section is 8-byte aligned on 64-bit targets.)
+    stats_.alignment_bytes +=
+        method_section.Offset() - (field_section.Offset() + field_section.Size());
+    // Add padding between the method section and the intern table.
+    // (Method section is 4-byte aligned on 32-bit targets, intern table is 8-byte aligned.)
+    stats_.alignment_bytes +=
+        intern_section.Offset() - (method_section.Offset() + method_section.Size());
     stats_.alignment_bytes += bitmap_section.Offset() - image_header_.GetImageSize();
     stats_.bitmap_bytes += bitmap_section.Size();
     stats_.art_field_bytes += field_section.Size();
-    // RoundUp to 8 bytes to match the intern table alignment expectation.
-    stats_.art_method_bytes += RoundUp(method_section.Size(), sizeof(uint64_t));
+    stats_.art_method_bytes += method_section.Size();
     stats_.interned_strings_bytes += intern_section.Size();
     stats_.Dump(os, indent_os);
     os << "\n";