Remove pad word from arrays

This change removes the 4 byte pad from all arrays except longs and
doubles. It saves 76kb from the boot image, and will also reduce the
size of arrays in the heap (and thereby reduce garbage collection).

Change-Id: I3ff277d5bf14c57c0f7552215818e588ec6cc275
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 1f7f24d..8c97cf1 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -748,23 +748,48 @@
   AssertDexFile(java_lang_dex_file_, NULL);
 }
 
-// The first reference array element must be a multiple of 8 bytes from the
+// The first reference array element must be a multiple of 4 bytes from the
 // start of the object
 TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
   Class* array_class = class_linker_->FindSystemClass("[Ljava/lang/String;");
   ObjectArray<String>* array = ObjectArray<String>::Alloc(array_class, 0);
   uint32_t array_offset = reinterpret_cast<uint32_t>(array);
   uint32_t data_offset =
-      array_offset + ObjectArray<String>::DataOffset().Uint32Value();
-  EXPECT_EQ(16U, data_offset - array_offset);
+      array_offset + ObjectArray<String>::DataOffset(sizeof(String*)).Uint32Value();
+  if (sizeof(String*) == sizeof(int32_t)) {
+    EXPECT_TRUE(IsAligned<4>(data_offset));  // Check 4 byte alignment.
+  } else {
+    EXPECT_TRUE(IsAligned<8>(data_offset));  // Check 8 byte alignment.
+  }
 }
 
 TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
-  SirtRef<LongArray> array(LongArray::Alloc(0));
-  EXPECT_EQ(class_linker_->FindSystemClass("[J"), array->GetClass());
-  uint32_t array_offset = reinterpret_cast<uint32_t>(array.get());
-  uint32_t data_offset = reinterpret_cast<uint32_t>(array->GetData());
-  EXPECT_EQ(16U, data_offset - array_offset);
+  SirtRef<LongArray> long_array(LongArray::Alloc(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("[J"), long_array->GetClass());
+  uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData());
+  EXPECT_TRUE(IsAligned<8>(data_offset));  // Longs require 8 byte alignment
+
+  SirtRef<DoubleArray> double_array(DoubleArray::Alloc(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("[D"), double_array->GetClass());
+  data_offset = reinterpret_cast<uintptr_t>(double_array->GetData());
+  EXPECT_TRUE(IsAligned<8>(data_offset));  // Doubles require 8 byte alignment
+
+  SirtRef<IntArray> int_array(IntArray::Alloc(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("[I"), int_array->GetClass());
+  data_offset = reinterpret_cast<uintptr_t>(int_array->GetData());
+  EXPECT_TRUE(IsAligned<4>(data_offset));  // Ints require 4 byte alignment
+
+  SirtRef<CharArray> char_array(CharArray::Alloc(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("[C"), char_array->GetClass());
+  data_offset = reinterpret_cast<uintptr_t>(char_array->GetData());
+  EXPECT_TRUE(IsAligned<2>(data_offset));  // Chars require 2 byte alignment
+
+  SirtRef<ShortArray> short_array(ShortArray::Alloc(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("[S"), short_array->GetClass());
+  data_offset = reinterpret_cast<uintptr_t>(short_array->GetData());
+  EXPECT_TRUE(IsAligned<2>(data_offset));  // Shorts require 2 byte alignment
+
+  // Take it as given that bytes and booleans have byte alignment
 }
 
 TEST_F(ClassLinkerTest, ValidateBoxedTypes) {