Make LinkFields ordering more stable for easier maintenance

This is prepatory for moving remaining malloc heap storage to the managed heap.

Added offset tests for static fields of class instances known to C++ for boot strapping.
Found bug in MethodClass.

Change-Id: I267bbbf9192d648668e8958e9eddc3eac54bb52e
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 01e283e..6d5c643 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2,6 +2,7 @@
 
 #include "class_linker.h"
 
+#include <deque>
 #include <string>
 #include <utility>
 #include <vector>
@@ -1834,14 +1835,35 @@
   return success;
 }
 
+struct LinkFieldsComparator {
+  bool operator()(const Field* field1, const Field* field2){
+
+    // First come reference fields, then 64-bit, and finally 32-bit
+    const Class* type1 = field1->GetTypeDuringLinking();
+    const Class* type2 = field2->GetTypeDuringLinking();
+    bool isPrimitive1 = type1 != NULL && type1->IsPrimitive();
+    bool isPrimitive2 = type2 != NULL && type2->IsPrimitive();
+    bool is64bit1 = isPrimitive1 && (type1->IsPrimitiveLong() || type1->IsPrimitiveDouble());
+    bool is64bit2 = isPrimitive2 && (type2->IsPrimitiveLong() || type2->IsPrimitiveDouble());
+    int order1 = (!isPrimitive1 ? 0 : (is64bit1 ? 1 : 2));
+    int order2 = (!isPrimitive2 ? 0 : (is64bit2 ? 1 : 2));
+    if (order1 != order2) {
+      return order1 < order2;
+    }
+
+    // same basic group? then sort by string.
+    std::string name1 = field1->GetName()->ToModifiedUtf8();
+    std::string name2 = field2->GetName()->ToModifiedUtf8();
+    return name1 < name2;
+  }
+};
+
 bool ClassLinker::LinkFields(Class* klass, bool instance) {
   size_t num_fields =
       instance ? klass->NumInstanceFields() : klass->NumStaticFields();
 
   ObjectArray<Field>* fields =
       instance ? klass->GetIFields() : klass->GetSFields();
-  // Fields updated at end of LinkFields
-  size_t num_reference_fields;
 
   // Initialize size and field_offset
   size_t size;
@@ -1858,34 +1880,32 @@
     field_offset = Class::FieldsOffset();
   }
 
-  CHECK((num_fields == 0) == (fields == NULL));
+  CHECK_EQ(num_fields == 0, fields == NULL);
 
-  // Move references to the front.
-  size_t i = 0;
-  num_reference_fields = 0;
-  for (; i < num_fields; i++) {
-    Field* field = fields->Get(i);
-    const Class* field_type = field->GetTypeDuringLinking();
+  // we want a relatively stable order so that adding new fields
+  // minimizes distruption of C++ version such as Class and Method.
+  std::deque<Field*> grouped_and_sorted_fields;
+  for (size_t i = 0; i < num_fields; i++) {
+    grouped_and_sorted_fields.push_back(fields->Get(i));
+  }
+  std::sort(grouped_and_sorted_fields.begin(),
+            grouped_and_sorted_fields.end(),
+            LinkFieldsComparator());
+
+  // References should be at the front.
+  size_t current_field = 0;
+  size_t num_reference_fields = 0;
+  for (; current_field < num_fields; current_field++) {
+    Field* field = grouped_and_sorted_fields.front();
+    const Class* type = field->GetTypeDuringLinking();
     // if a field's type at this point is NULL it isn't primitive
-    if (field_type != NULL && field_type->IsPrimitive()) {
-      for (size_t j = num_fields - 1; j > i; j--) {
-        Field* ref_field = fields->Get(j);
-        const Class* ref_field_type = ref_field->GetTypeDuringLinking();
-        if (ref_field_type == NULL || !ref_field_type->IsPrimitive()) {
-          fields->Set(i, ref_field);
-          fields->Set(j, field);
-          field = ref_field;
-          field_type = ref_field_type;
-          num_reference_fields++;
-          break;
-        }
-      }
-    } else {
-      num_reference_fields++;
+    bool isPrimitive = type != NULL && type->IsPrimitive();
+    if (isPrimitive) {
+      break; // past last reference, move on to the next phase
     }
-    if (field_type != NULL && field_type->IsPrimitive()) {
-      break;
-    }
+    grouped_and_sorted_fields.pop_front();
+    num_reference_fields++;
+    fields->Set(current_field, field);
     field->SetOffset(field_offset);
     field_offset = MemberOffset(field_offset.Uint32Value() + sizeof(uint32_t));
   }
@@ -1893,86 +1913,57 @@
   // Now we want to pack all of the double-wide fields together.  If
   // we're not aligned, though, we want to shuffle one 32-bit field
   // into place.  If we can't find one, we'll have to pad it.
-  if (i != num_fields && !IsAligned(field_offset.Uint32Value(), 8)) {
-    Field* field = fields->Get(i);
-    const Class* c = field->GetTypeDuringLinking();
-    CHECK(c != NULL);  // should only be working on primitive types
-    if (!c->IsPrimitiveLong() && !c->IsPrimitiveDouble()) {
-      // The field that comes next is 32-bit, so just advance past it.
-      DCHECK(c->IsPrimitive());
+  if (current_field != num_fields && !IsAligned(field_offset.Uint32Value(), 8)) {
+    for (size_t i = 0; i < grouped_and_sorted_fields.size(); i++) {
+      Field* field = grouped_and_sorted_fields[i];
+      const Class* type = field->GetTypeDuringLinking();
+      CHECK(type != NULL);  // should only be working on primitive types
+      DCHECK(type->IsPrimitive());
+      if (type->IsPrimitiveLong() || type->IsPrimitiveDouble()) {
+        continue;
+      }
+      fields->Set(current_field++, field);
       field->SetOffset(field_offset);
-      field_offset = MemberOffset(field_offset.Uint32Value() +
-                                  sizeof(uint32_t));
-      i++;
-    } else {
-      // Next field is 64-bit, so search for a 32-bit field we can
-      // swap into it.
-      bool found = false;
-      for (size_t j = num_fields - 1; j > i; j--) {
-        Field* single_field = fields->Get(j);
-        const Class* rc = single_field->GetTypeDuringLinking();
-        CHECK(rc != NULL);  // should only be working on primitive types
-        if (!rc->IsPrimitiveLong() && !rc->IsPrimitiveDouble()) {
-          fields->Set(i, single_field);
-          fields->Set(j, field);
-          field = single_field;
-          field->SetOffset(field_offset);
-          field_offset = MemberOffset(field_offset.Uint32Value() +
-                                      sizeof(uint32_t));
-          found = true;
-          i++;
-          break;
-        }
-      }
-      if (!found) {
-        field_offset = MemberOffset(field_offset.Uint32Value() +
-                                    sizeof(uint32_t));
-      }
+      // drop the consumed field
+      grouped_and_sorted_fields.erase(grouped_and_sorted_fields.begin() + i);
+      break;
     }
+    // whether we found a 32-bit field for padding or not, we advance
+    field_offset = MemberOffset(field_offset.Uint32Value() + sizeof(uint32_t));
   }
 
   // Alignment is good, shuffle any double-wide fields forward, and
   // finish assigning field offsets to all fields.
-  DCHECK(i == num_fields || IsAligned(field_offset.Uint32Value(), 4));
-  for ( ; i < num_fields; i++) {
-    Field* field = fields->Get(i);
-    const Class* c = field->GetTypeDuringLinking();
-    CHECK(c != NULL);  // should only be working on primitive types
-    if (!c->IsPrimitiveDouble() && !c->IsPrimitiveLong()) {
-      for (size_t j = num_fields - 1; j > i; j--) {
-        Field* double_field = fields->Get(j);
-        const Class* rc = double_field->GetTypeDuringLinking();
-        CHECK(rc != NULL);  // should only be working on primitive types
-        if (rc->IsPrimitiveDouble() || rc->IsPrimitiveLong()) {
-          fields->Set(i, double_field);
-          fields->Set(j, field);
-          field = double_field;
-          c = rc;
-          break;
-        }
-      }
-    } else {
-      // This is a double-wide field, leave it be.
-    }
-
+  DCHECK(current_field == num_fields || IsAligned(field_offset.Uint32Value(), 8));
+  while (!grouped_and_sorted_fields.empty()) {
+    Field* field = grouped_and_sorted_fields.front();
+    grouped_and_sorted_fields.pop_front();
+    const Class* type = field->GetTypeDuringLinking();
+    CHECK(type != NULL);  // should only be working on primitive types
+    DCHECK(type->IsPrimitive());
+    fields->Set(current_field, field);
     field->SetOffset(field_offset);
-    if (c->IsPrimitiveLong() || c->IsPrimitiveDouble()) {
-      field_offset = MemberOffset(field_offset.Uint32Value() +
-                                  sizeof(uint64_t));
-    } else {
-      field_offset = MemberOffset(field_offset.Uint32Value() +
-                                  sizeof(uint32_t));
-    }
+    field_offset = MemberOffset(field_offset.Uint32Value() +
+                                ((type->IsPrimitiveLong() || type->IsPrimitiveDouble())
+                                 ? sizeof(uint64_t)
+                                 : sizeof(uint32_t)));
+    current_field++;
   }
 
 #ifndef NDEBUG
   // Make sure that all reference fields appear before
   // non-reference fields, and all double-wide fields are aligned.
   bool seen_non_ref = false;
-  for (i = 0; i < num_fields; i++) {
+  for (size_t i = 0; i < num_fields; i++) {
     Field* field = fields->Get(i);
-    const Class* c = field->GetTypeDuringLinking();
-    if (c != NULL && c->IsPrimitive()) {
+    if (false) {  // enable to debug field layout
+      LOG(INFO) << "LinkFields:"
+                << " class=" << klass->GetDescriptor()->ToModifiedUtf8()
+                << " field=" << field->GetName()->ToModifiedUtf8()
+                << " offset=" << field->GetField32(MemberOffset(Field::OffsetOffset()), false);
+    }
+    const Class* type = field->GetTypeDuringLinking();
+    if (type != NULL && type->IsPrimitive()) {
       if (!seen_non_ref) {
         seen_non_ref = true;
         DCHECK_EQ(num_reference_fields, i);
@@ -1987,9 +1978,9 @@
 #endif
   size = field_offset.Uint32Value();
   // Update klass
-  if(instance) {
+  if (instance) {
     klass->SetNumReferenceInstanceFields(num_reference_fields);
-    if(!klass->IsVariableSize()) {
+    if (!klass->IsVariableSize()) {
       klass->SetObjectSize(size);
     }
   } else {
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 3362fdc..cb1cd8d 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -379,61 +379,62 @@
 };
 
 struct CheckOffsets {
-  size_t s;
-  std::string c;
-  std::vector<CheckOffset> o;
+  bool instance;
+  size_t size;
+  std::string class_descriptor;
+  std::vector<CheckOffset> offsets;
 
   bool Check() {
-    Class* klass = Runtime::Current()->GetClassLinker()->FindSystemClass(c);
-    CHECK(klass != NULL) << c;
+    Class* klass = Runtime::Current()->GetClassLinker()->FindSystemClass(class_descriptor);
+    CHECK(klass != NULL) << class_descriptor;
 
     bool error = false;
 
-    if (!klass->IsClassClass())
-      if (s != klass->GetObjectSize()) {
+    if (!klass->IsClassClass() && instance)
+      if (size != (instance ? klass->GetObjectSize() : klass->GetClassSize())) {
         LG << "Class size mismatch:"
-           << " class=" << c
+           << " class=" << class_descriptor
            << " Java=" << klass->GetObjectSize()
-           << " C++=" << s;
+           << " C++=" << (instance ? klass->GetObjectSize() : klass->GetClassSize());
       error = true;
     }
 
-    CHECK_EQ(o.size(), klass->NumInstanceFields());
-    for (size_t i = 0; i < o.size(); i++) {
-      Field* field = klass->GetInstanceField(i);
-      if (!field->GetName()->Equals(o[i].java_name)) {
+    CHECK_EQ(offsets.size(), instance ? klass->NumInstanceFields() : klass->NumStaticFields());
+    for (size_t i = 0; i < offsets.size(); i++) {
+      Field* field = instance ? klass->GetInstanceField(i) : klass->GetStaticField(i);
+      if (!field->GetName()->Equals(offsets[i].java_name)) {
         error = true;
       }
     }
     if (error) {
-      for (size_t i = 0; i < o.size(); i++) {
-        CheckOffset& offset = o[i];
-        Field* field = klass->GetInstanceField(i);
-        if (!field->GetName()->Equals(o[i].java_name)) {
+      for (size_t i = 0; i < offsets.size(); i++) {
+        CheckOffset& offset = offsets[i];
+        Field* field = instance ? klass->GetInstanceField(i) : klass->GetStaticField(i);
+        if (!field->GetName()->Equals(offsets[i].java_name)) {
           LG << "JAVA FIELD ORDER MISMATCH NEXT LINE:";
         }
         LG << "Java field order:"
-           << " i=" << i << " class=" << c
+           << " i=" << i << " class=" << class_descriptor
            << " Java=" << field->GetName()->ToModifiedUtf8()
            << " CheckOffsets=" << offset.java_name;
       }
     }
 
-    for (size_t i = 0; i < o.size(); i++) {
-      CheckOffset& offset = o[i];
-      Field* field = klass->GetInstanceField(i);
+    for (size_t i = 0; i < offsets.size(); i++) {
+      CheckOffset& offset = offsets[i];
+      Field* field = instance ? klass->GetInstanceField(i) : klass->GetStaticField(i);
       if (field->GetOffset().Uint32Value() != offset.cpp_offset) {
         error = true;
       }
     }
     if (error) {
-      for (size_t i = 0; i < o.size(); i++) {
-        CheckOffset& offset = o[i];
-        Field* field = klass->GetInstanceField(i);
+      for (size_t i = 0; i < offsets.size(); i++) {
+        CheckOffset& offset = offsets[i];
+        Field* field = instance ? klass->GetInstanceField(i) : klass->GetStaticField(i);
         if (field->GetOffset().Uint32Value() != offset.cpp_offset) {
           LG << "OFFSET MISMATCH NEXT LINE:";
         }
-        LG << "Offset: class=" << c << " field=" << offset.java_name
+        LG << "Offset: class=" << class_descriptor << " field=" << offset.java_name
            << " Java=" << field->GetOffset().Uint32Value() << " C++=" << offset.cpp_offset;
       }
     }
@@ -444,175 +445,279 @@
 
 struct ObjectOffsets : public CheckOffsets {
   ObjectOffsets() {
-    s = sizeof(Object);
-    c = "Ljava/lang/Object;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Object, klass_),   "shadow$_klass_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Object, monitor_), "shadow$_monitor_"));
+    instance = true;
+    size = sizeof(Object);
+    class_descriptor = "Ljava/lang/Object;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Object, klass_),   "shadow$_klass_"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Object, monitor_), "shadow$_monitor_"));
   };
 };
 
 struct AccessibleObjectOffsets : public CheckOffsets {
   AccessibleObjectOffsets() {
-    s = sizeof(AccessibleObject);
-    c = "Ljava/lang/reflect/AccessibleObject;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(AccessibleObject, java_flag_), "flag"));
+    instance = true;
+    size = sizeof(AccessibleObject);
+    class_descriptor = "Ljava/lang/reflect/AccessibleObject;";
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AccessibleObject, java_flag_), "flag"));
   };
 };
 
 struct FieldOffsets : public CheckOffsets {
   FieldOffsets() {
-    s = sizeof(Field);
-    c = "Ljava/lang/reflect/Field;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, declaring_class_),               "declaringClass"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, generic_type_),                  "genericType"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, type_),                          "type"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, name_),                          "name"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, access_flags_),                  "shadow$_access_flags_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, offset_),                        "shadow$_offset_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, type_idx_),                      "shadow$_type_idx_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, slot_),                          "slot"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Field, generic_types_are_initialized_), "genericTypesAreInitialized"));
+    instance = true;
+    size = sizeof(Field);
+    class_descriptor = "Ljava/lang/reflect/Field;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, declaring_class_),               "declaringClass"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, generic_type_),                  "genericType"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, name_),                          "name"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, type_),                          "type"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, generic_types_are_initialized_), "genericTypesAreInitialized"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, access_flags_),                  "shadow$_access_flags_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, offset_),                        "shadow$_offset_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, type_idx_),                      "shadow$_type_idx_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Field, slot_),                          "slot"));
   };
 };
 
 struct MethodOffsets : public CheckOffsets {
   MethodOffsets() {
-    s = sizeof(Method);
-    c = "Ljava/lang/reflect/Method;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, declaring_class_),                      "declaringClass"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_exception_types_),                 "exceptionTypes"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_formal_type_parameters_),          "formalTypeParameters"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_exception_types_),         "genericExceptionTypes"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_parameter_types_),         "genericParameterTypes"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_return_type_),             "genericReturnType"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, signature_),                            "shadow$_signature_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, name_),                                 "name"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_parameter_types_),                 "parameterTypes"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_return_type_),                     "returnType"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, mapping_table_),                        "shadow$_mapping_table_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_array_),                    "shadow$_invoke_stub_array_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_array_),                           "shadow$_code_array_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_strings_),                    "shadow$_dex_cache_strings_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_types_),             "shadow$_dex_cache_resolved_types_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_code_and_direct_methods_),    "shadow$_dex_cache_code_and_direct_methods_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_initialized_static_storage_), "shadow$_dex_cache_initialized_static_storage_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_fields_),            "shadow$_dex_cache_resolved_fields_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_methods_),           "shadow$_dex_cache_resolved_methods_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, core_spill_mask_),                      "shadow$_core_spill_mask_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_item_offset_),                     "shadow$_code_item_offset_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, fp_spill_mask_),                        "shadow$_fp_spill_mask_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, frame_size_in_bytes_),                  "shadow$_frame_size_in_bytes_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_),                          "shadow$_invoke_stub_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_),                                 "shadow$_code_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_return_type_idx_),                 "shadow$_java_return_type_idx_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, access_flags_),                         "shadow$_access_flags_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, method_index_),                         "shadow$_method_index_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, native_method_),                        "shadow$_native_method_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_ins_),                              "shadow$_num_ins_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_outs_),                             "shadow$_num_outs_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_registers_),                        "shadow$_num_registers_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, proto_idx_),                            "shadow$_proto_idx_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, return_pc_offset_in_bytes_),            "shadow$_return_pc_offset_in_bytes_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, shorty_),                               "shadow$_shorty_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_types_are_initialized_),   "genericTypesAreInitialized"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_slot_),                            "slot"));
+    instance = true;
+    size = sizeof(Method);
+    class_descriptor = "Ljava/lang/reflect/Method;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, declaring_class_),                      "declaringClass"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_exception_types_),                 "exceptionTypes"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_formal_type_parameters_),          "formalTypeParameters"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_exception_types_),         "genericExceptionTypes"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_parameter_types_),         "genericParameterTypes"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_return_type_),             "genericReturnType"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, name_),                                 "name"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_parameter_types_),                 "parameterTypes"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_return_type_),                     "returnType"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_array_),                           "shadow$_code_array_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_code_and_direct_methods_),    "shadow$_dex_cache_code_and_direct_methods_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_initialized_static_storage_), "shadow$_dex_cache_initialized_static_storage_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_fields_),            "shadow$_dex_cache_resolved_fields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_methods_),           "shadow$_dex_cache_resolved_methods_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_types_),             "shadow$_dex_cache_resolved_types_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_strings_),                    "shadow$_dex_cache_strings_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_array_),                    "shadow$_invoke_stub_array_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, mapping_table_),                        "shadow$_mapping_table_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, signature_),                            "shadow$_signature_"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_types_are_initialized_),   "genericTypesAreInitialized"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, access_flags_),                         "shadow$_access_flags_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_),                                 "shadow$_code_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_item_offset_),                     "shadow$_code_item_offset_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, core_spill_mask_),                      "shadow$_core_spill_mask_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, fp_spill_mask_),                        "shadow$_fp_spill_mask_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, frame_size_in_bytes_),                  "shadow$_frame_size_in_bytes_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_),                          "shadow$_invoke_stub_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_return_type_idx_),                 "shadow$_java_return_type_idx_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, method_index_),                         "shadow$_method_index_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, native_method_),                        "shadow$_native_method_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_ins_),                              "shadow$_num_ins_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_outs_),                             "shadow$_num_outs_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_registers_),                        "shadow$_num_registers_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, proto_idx_),                            "shadow$_proto_idx_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, return_pc_offset_in_bytes_),            "shadow$_return_pc_offset_in_bytes_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, shorty_),                               "shadow$_shorty_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_slot_),                            "slot"));
   };
 };
 
 struct ClassOffsets : public CheckOffsets {
   ClassOffsets() {
-    s = sizeof(Class);
-    c = "Ljava/lang/Class;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, name_),                          "name"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, vtable_),                        "shadow$_vtable_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, virtual_methods_),               "shadow$_virtual_methods_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, class_loader_),                  "shadow$_class_loader_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, verify_error_class_),            "shadow$_verify_error_class_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_),                   "shadow$_super_class_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, component_type_),                "shadow$_component_type_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, descriptor_),                    "shadow$_descriptor_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, dex_cache_),                     "shadow$_dex_cache_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, direct_methods_),                "shadow$_direct_methods_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifields_),                       "shadow$_ifields_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, sfields_),                       "shadow$_sfields_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_type_idx_),           "shadow$_interfaces_type_idx_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_),                    "shadow$_interfaces_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_count_),               "shadow$_ifvi_pool_count_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_),                     "shadow$_ifvi_pool_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_count_),                 "shadow$_iftable_count_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_instance_fields_), "shadow$_num_reference_instance_fields_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_static_fields_),   "shadow$_num_reference_static_fields_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, object_size_),                   "shadow$_object_size_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, primitive_type_),                "shadow$_primitive_type_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_instance_offsets_),    "shadow$_reference_instance_offsets_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_static_offsets_),      "shadow$_reference_static_offsets_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_),                       "shadow$_iftable_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, source_file_),                   "shadow$_source_file_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, status_),                        "shadow$_status_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, clinit_thread_id_),              "shadow$_clinit_thread_id_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_type_idx_),          "shadow$_super_class_type_idx_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, class_size_),                    "shadow$_class_size_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, array_rank_),                    "shadow$_array_rank_"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Class, access_flags_),                  "shadow$_access_flags_"));
+    instance = true;
+    size = sizeof(Class);
+    class_descriptor = "Ljava/lang/Class;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, name_),                          "name"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, class_loader_),                  "shadow$_class_loader_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, component_type_),                "shadow$_component_type_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, descriptor_),                    "shadow$_descriptor_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, dex_cache_),                     "shadow$_dex_cache_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, direct_methods_),                "shadow$_direct_methods_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifields_),                       "shadow$_ifields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_),                    "shadow$_interfaces_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_type_idx_),           "shadow$_interfaces_type_idx_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, sfields_),                       "shadow$_sfields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_),                   "shadow$_super_class_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, verify_error_class_),            "shadow$_verify_error_class_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, virtual_methods_),               "shadow$_virtual_methods_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, vtable_),                        "shadow$_vtable_"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, access_flags_),                  "shadow$_access_flags_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, array_rank_),                    "shadow$_array_rank_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, class_size_),                    "shadow$_class_size_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, clinit_thread_id_),              "shadow$_clinit_thread_id_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_),                       "shadow$_iftable_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_count_),                 "shadow$_iftable_count_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_),                     "shadow$_ifvi_pool_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_count_),               "shadow$_ifvi_pool_count_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_instance_fields_), "shadow$_num_reference_instance_fields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_static_fields_),   "shadow$_num_reference_static_fields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, object_size_),                   "shadow$_object_size_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, primitive_type_),                "shadow$_primitive_type_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_instance_offsets_),    "shadow$_reference_instance_offsets_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_static_offsets_),      "shadow$_reference_static_offsets_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, source_file_),                   "shadow$_source_file_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, status_),                        "shadow$_status_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_type_idx_),          "shadow$_super_class_type_idx_"));
   };
 };
 
 struct StringOffsets : public CheckOffsets {
   StringOffsets() {
-    s = sizeof(String);
-    c = "Ljava/lang/String;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(String, array_),     "value"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(String, hash_code_), "hashCode"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(String, offset_),    "offset"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(String, count_),     "count"));
+    instance = true;
+    size = sizeof(String);
+    class_descriptor = "Ljava/lang/String;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(String, array_),     "value"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(String, count_),     "count"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(String, hash_code_), "hashCode"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(String, offset_),    "offset"));
   };
 };
 
 struct ThrowableOffsets : public CheckOffsets {
   ThrowableOffsets() {
-    s = sizeof(Throwable);
-    c = "Ljava/lang/Throwable;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, cause_),                 "cause"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, detail_message_),        "detailMessage"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, stack_state_),           "stackState"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, stack_trace_),           "stackTrace"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, suppressed_exceptions_), "suppressedExceptions"));
+    instance = true;
+    size = sizeof(Throwable);
+    class_descriptor = "Ljava/lang/Throwable;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, cause_),                 "cause"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, detail_message_),        "detailMessage"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, stack_state_),           "stackState"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, stack_trace_),           "stackTrace"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Throwable, suppressed_exceptions_), "suppressedExceptions"));
   };
 };
 
 struct StackTraceElementOffsets : public CheckOffsets {
   StackTraceElementOffsets() {
-    s = sizeof(StackTraceElement);
-    c = "Ljava/lang/StackTraceElement;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, declaring_class_), "declaringClass"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, file_name_),       "fileName"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, method_name_),     "methodName"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, line_number_),     "lineNumber"));
+    instance = true;
+    size = sizeof(StackTraceElement);
+    class_descriptor = "Ljava/lang/StackTraceElement;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, declaring_class_), "declaringClass"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, file_name_),       "fileName"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, method_name_),     "methodName"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StackTraceElement, line_number_),     "lineNumber"));
   };
 };
 
 struct ClassLoaderOffsets : public CheckOffsets {
   ClassLoaderOffsets() {
-    s = sizeof(ClassLoader);
-    c = "Ljava/lang/ClassLoader;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(ClassLoader, packages_), "packages"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(ClassLoader, parent_),   "parent"));
+    instance = true;
+    size = sizeof(ClassLoader);
+    class_descriptor = "Ljava/lang/ClassLoader;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(ClassLoader, packages_), "packages"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(ClassLoader, parent_),   "parent"));
   };
 };
 
 struct BaseDexClassLoaderOffsets : public CheckOffsets {
   BaseDexClassLoaderOffsets() {
-    s = sizeof(BaseDexClassLoader);
-    c = "Ldalvik/system/BaseDexClassLoader;";
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, original_path_), "originalPath"));
-    o.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, path_list_),   "pathList"));
+    instance = true;
+    size = sizeof(BaseDexClassLoader);
+    class_descriptor = "Ldalvik/system/BaseDexClassLoader;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, original_path_), "originalPath"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, path_list_),     "pathList"));
   };
 };
 
 struct PathClassLoaderOffsets : public CheckOffsets {
   PathClassLoaderOffsets() {
-    s = sizeof(PathClassLoader);
-    c = "Ldalvik/system/PathClassLoader;";
+    instance = true;
+    size = sizeof(PathClassLoader);
+    class_descriptor = "Ldalvik/system/PathClassLoader;";
+  };
+};
+
+struct ClassClassOffsets : public CheckOffsets {
+  ClassClassOffsets() {
+    instance = false;
+    size = sizeof(ClassClass);
+    class_descriptor = "Ljava/lang/Class;";
+
+    // padding 32-bit
+    // this space intentionally left blank
+
+    // alphabetical 64-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(ClassClass, serialVersionUID_), "serialVersionUID"));
+  };
+};
+
+struct StringClassOffsets : public CheckOffsets {
+  StringClassOffsets() {
+    instance = false;
+    size = sizeof(StringClass);
+    class_descriptor = "Ljava/lang/String;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, ASCII_),                  "ASCII"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, CASE_INSENSITIVE_ORDER_), "CASE_INSENSITIVE_ORDER"));
+
+    // padding 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, REPLACEMENT_CHAR_),       "REPLACEMENT_CHAR"));
+
+    // alphabetical 64-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, serialVersionUID_),       "serialVersionUID"));
+  };
+};
+
+struct FieldClassOffsets : public CheckOffsets {
+  FieldClassOffsets() {
+    instance = false;
+    size = sizeof(FieldClass);
+    class_descriptor = "Ljava/lang/reflect/Field;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, ORDER_BY_NAME_AND_DECLARING_CLASS_), "ORDER_BY_NAME_AND_DECLARING_CLASS"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_BOOLEAN_), "TYPE_BOOLEAN"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_BYTE_),    "TYPE_BYTE"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_CHAR_),    "TYPE_CHAR"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_DOUBLE_),  "TYPE_DOUBLE"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_FLOAT_),   "TYPE_FLOAT"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_INTEGER_), "TYPE_INTEGER"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_LONG_),    "TYPE_LONG"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(FieldClass, TYPE_SHORT_),   "TYPE_SHORT"));
+  };
+};
+
+struct MethodClassOffsets : public CheckOffsets {
+  MethodClassOffsets() {
+    instance = false;
+    size = sizeof(MethodClass);
+    class_descriptor = "Ljava/lang/reflect/Method;";
+
+    // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(MethodClass, NO_ANNOTATIONS_),     "NO_ANNOTATIONS"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(MethodClass, ORDER_BY_SIGNATURE_), "ORDER_BY_SIGNATURE"));
   };
 };
 
@@ -631,6 +736,11 @@
   EXPECT_TRUE(ClassLoaderOffsets().Check());
   EXPECT_TRUE(BaseDexClassLoaderOffsets().Check());
   EXPECT_TRUE(PathClassLoaderOffsets().Check());
+
+  EXPECT_TRUE(ClassClassOffsets().Check());
+  EXPECT_TRUE(StringClassOffsets().Check());
+  EXPECT_TRUE(FieldClassOffsets().Check());
+  EXPECT_TRUE(MethodClassOffsets().Check());
 }
 
 // The first reference array element must be a multiple of 8 bytes from the
diff --git a/src/heap.cc b/src/heap.cc
index d80f437..7f6b106 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -186,7 +186,7 @@
       LOG(FATAL) << "Object is dead: " << obj;
     }
     // Ignore early dawn of the universe verifications
-    if(num_objects_allocated_ > 10) {
+    if (num_objects_allocated_ > 10) {
       const byte* raw_addr = reinterpret_cast<const byte*>(obj) +
           Object::ClassOffset().Int32Value();
       const Class* c = *reinterpret_cast<Class* const *>(raw_addr);
diff --git a/src/object.h b/src/object.h
index 72a03ba..bc9ec7e 100644
--- a/src/object.h
+++ b/src/object.h
@@ -597,10 +597,12 @@
 
   Object* generic_type_;
 
+  const String* name_;
+
   // Type of the field
   Class* type_;
 
-  const String* name_;
+  uint32_t generic_types_are_initialized_;
 
   uint32_t access_flags_;
 
@@ -612,8 +614,6 @@
 
   int32_t slot_;
 
-  uint32_t generic_types_are_initialized_;
-
   static Class* java_lang_reflect_Field_;
 
   friend struct FieldOffsets;  // for verifying offset information
@@ -1006,40 +1006,16 @@
   Object* java_generic_parameter_types_;
   Object* java_generic_return_type_;
 
-  // The method descriptor.  This represents the parameters a method
-  // takes and value it returns.  This string is a list of the type
-  // descriptors for the parameters enclosed in parenthesis followed
-  // by the return type descriptor.  For example, for the method
-  //
-  //   Object mymethod(int i, double d, Thread t)
-  //
-  // the method descriptor would be
-  //
-  //   (IDLjava/lang/Thread;)Ljava/lang/Object;
-  String* signature_;
-
   String* name_;
 
   ObjectArray<Class>* java_parameter_types_;
 
   Class* java_return_type_;  // Unused by ART
 
-  // Storage for mapping_table_
-  const ByteArray* mapping_table_;
-
-  // Storage for invoke_stub_
-  const ByteArray* invoke_stub_array_;
-
   // Storage for code_
   const ByteArray* code_array_;
 
   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
-  ObjectArray<String>* dex_cache_strings_;
-
-  // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
-  ObjectArray<Class>* dex_cache_resolved_types_;
-
-  // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
   CodeAndDirectMethods* dex_cache_code_and_direct_methods_;
 
   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
@@ -1051,13 +1027,46 @@
   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
   ObjectArray<Method>* dex_cache_resolved_methods_;
 
-  // Architecture-dependent register spill mask
-  uint32_t core_spill_mask_;
+  // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
+  ObjectArray<Class>* dex_cache_resolved_types_;
+
+  // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
+  ObjectArray<String>* dex_cache_strings_;
+
+  // Storage for invoke_stub_
+  const ByteArray* invoke_stub_array_;
+
+  // Storage for mapping_table_
+  const ByteArray* mapping_table_;
+
+  // The method descriptor.  This represents the parameters a method
+  // takes and value it returns.  This string is a list of the type
+  // descriptors for the parameters enclosed in parenthesis followed
+  // by the return type descriptor.  For example, for the method
+  //
+  //   Object mymethod(int i, double d, Thread t)
+  //
+  // the method descriptor would be
+  //
+  //   (IDLjava/lang/Thread;)Ljava/lang/Object;
+  String* signature_;
+
+  uint32_t java_generic_types_are_initialized_;
+
+  // access flags; low 16 bits are defined by spec (could be uint16_t?)
+  uint32_t access_flags_;
+
+  // Compiled code associated with this method for callers from managed code.
+  // May be compiled managed code or a bridge for invoking a native method.
+  const void* code_;
 
   // Offset to the CodeItem.
   uint32_t code_item_offset_;
 
   // Architecture-dependent register spill mask
+  uint32_t core_spill_mask_;
+
+  // Architecture-dependent register spill mask
   uint32_t fp_spill_mask_;
 
   // Total size in bytes of the frame
@@ -1066,16 +1075,9 @@
   // Native invocation stub entry point for calling from native to managed code.
   const InvokeStub* invoke_stub_;
 
-  // Compiled code associated with this method for callers from managed code.
-  // May be compiled managed code or a bridge for invoking a native method.
-  const void* code_;
-
   // Index of the return type
   uint32_t java_return_type_idx_;
 
-  // access flags; low 16 bits are defined by spec (could be uint16_t?)
-  uint32_t access_flags_;
-
   // For concrete virtual methods, this is the offset of the method
   // in Class::vtable_.
   //
@@ -1103,8 +1105,6 @@
   // The short-form method descriptor string. TODO: make String*
   const char* shorty_;
 
-  uint32_t java_generic_types_are_initialized_;
-
   uint32_t java_slot_;
 
   static Class* java_lang_reflect_Method_;
@@ -1549,7 +1549,7 @@
     if (this == klass) {
       // Can always assign to things of the same type
       return true;
-    } else if(IsObjectClass()) {
+    } else if (IsObjectClass()) {
       // Can assign any reference to java.lang.Object
       return !klass->IsPrimitive();
     } else if (IsInterface()) {
@@ -1988,25 +1988,8 @@
   // descriptor for the class such as "java.lang.Class" or "[C"
   String* name_;  // TODO initialize
 
-  // Virtual method table (vtable), for use by "invoke-virtual".  The
-  // vtable from the superclass is copied in, and virtual methods from
-  // our class either replace those from the super or are appended.
-  ObjectArray<Method>* vtable_;
-
-  // virtual methods defined in this class; invoked through vtable
-  ObjectArray<Method>* virtual_methods_;
-
   // defining class loader, or NULL for the "bootstrap" system loader
-  const ClassLoader* class_loader_;  // TODO: make an instance field
-
-  // If class verify fails, we must return same error on subsequent tries.
-  // Update with SetVerifyErrorClass to ensure a write barrier is used.
-  const Class* verify_error_class_;
-
-  // The superclass, or NULL if this is java.lang.Object or a
-  // primitive type.
-  // see also super_class_type_idx_;
-  Class* super_class_;
+  const ClassLoader* class_loader_;
 
   // For array classes, the class object for base element, for
   // instanceof/checkcast (for String[][][], this will be String).
@@ -2035,50 +2018,46 @@
   // specifies the number of reference fields.
   ObjectArray<Field>* ifields_;
 
-  // Static fields
-  ObjectArray<Field>* sfields_;
+  // array of interfaces this class implements directly
+  // see also interfaces_type_idx_
+  ObjectArray<Class>* interfaces_;
 
   // array of type_idx's for interfaces this class implements directly
   // see also interfaces_
   IntArray* interfaces_type_idx_;
 
-  // array of interfaces this class implements directly
-  // see also interfaces_type_idx_
-  ObjectArray<Class>* interfaces_;
+  // Static fields
+  ObjectArray<Field>* sfields_;
 
-  // size of ifvi_pool_
-  size_t ifvi_pool_count_;
+  // The superclass, or NULL if this is java.lang.Object or a
+  // primitive type.
+  // see also super_class_type_idx_;
+  Class* super_class_;
 
-  // The interface vtable indices for iftable get stored here.  By
-  // placing them all in a single pool for each class that implements
-  // interfaces, we decrease the number of allocations.
-  //
-  // see also ifvi_pool_count_
-  //
-  // TODO convert to IntArray
-  uint32_t* ifvi_pool_;
+  // If class verify fails, we must return same error on subsequent tries.
+  // Update with SetVerifyErrorClass to ensure a write barrier is used.
+  const Class* verify_error_class_;
 
-  // size of iftable_
-  size_t iftable_count_;
+  // virtual methods defined in this class; invoked through vtable
+  ObjectArray<Method>* virtual_methods_;
 
-  // number of instance fields that are object refs
-  size_t num_reference_instance_fields_;
+  // Virtual method table (vtable), for use by "invoke-virtual".  The
+  // vtable from the superclass is copied in, and virtual methods from
+  // our class either replace those from the super or are appended.
+  ObjectArray<Method>* vtable_;
 
-  // number of static fields that are object refs
-  size_t num_reference_static_fields_;
+  // access flags; low 16 bits are defined by VM spec
+  uint32_t access_flags_;
 
-  // Total object size; used when allocating storage on gc heap.
-  // (For interfaces and abstract classes this will be zero.)
-  size_t object_size_;
+  // For array classes, the number of array dimensions, e.g. int[][]
+  // is 2.  Otherwise 0.
+  int32_t array_rank_;
 
-  // primitive type index, or kPrimNot (0); set for generated prim classes
-  PrimitiveType primitive_type_;
+  // Total class size; used when allocating storage on gc heap.
+  size_t class_size_;
 
-  // Bitmap of offsets of ifields.
-  uint32_t reference_instance_offsets_;
-
-  // Bitmap of offsets of sfields.
-  uint32_t reference_static_offsets_;
+  // threadId, used to check for recursive <clinit> invocation
+  pid_t clinit_thread_id_;
 
   // Interface table (iftable_), one entry per interface supported by
   // this class.  That means one entry for each interface we support
@@ -2099,29 +2078,50 @@
   //
   InterfaceEntry* iftable_;
 
+  // size of iftable_
+  size_t iftable_count_;
+
+  // The interface vtable indices for iftable get stored here.  By
+  // placing them all in a single pool for each class that implements
+  // interfaces, we decrease the number of allocations.
+  //
+  // see also ifvi_pool_count_
+  //
+  // TODO convert to IntArray
+  uint32_t* ifvi_pool_;
+
+  // size of ifvi_pool_
+  size_t ifvi_pool_count_;
+
+  // number of instance fields that are object refs
+  size_t num_reference_instance_fields_;
+
+  // number of static fields that are object refs
+  size_t num_reference_static_fields_;
+
+  // Total object size; used when allocating storage on gc heap.
+  // (For interfaces and abstract classes this will be zero.)
+  size_t object_size_;
+
+  // primitive type index, or kPrimNot (0); set for generated prim classes
+  PrimitiveType primitive_type_;
+
+  // Bitmap of offsets of ifields.
+  uint32_t reference_instance_offsets_;
+
+  // Bitmap of offsets of sfields.
+  uint32_t reference_static_offsets_;
+
   // source file name, if known.  Otherwise, NULL.
   const char* source_file_;
 
   // state of class initialization
   Status status_;
 
-  // threadId, used to check for recursive <clinit> invocation
-  uint32_t clinit_thread_id_;
-
   // Set in LoadClass, used to LinkClass
   // see also super_class_
   uint32_t super_class_type_idx_;
 
-  // Total class size; used when allocating storage on gc heap.
-  size_t class_size_;
-
-  // For array classes, the number of array dimensions, e.g. int[][]
-  // is 2.  Otherwise 0.
-  int32_t array_rank_;
-
-  // access flags; low 16 bits are defined by VM spec
-  uint32_t access_flags_;
-
   // TODO: ?
   // initiating class loader list
   // NOTE: for classes with low serialNumber, these are unused, and the
@@ -2344,6 +2344,7 @@
   // Padding to ensure the 64-bit serialVersionUID_ begins on a 8-byte boundary
   int32_t padding_;
   int64_t serialVersionUID_;
+  friend struct ClassClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
 };
 
@@ -2352,7 +2353,8 @@
   CharArray* ASCII_;
   Object* CASE_INSENSITIVE_ORDER_;
   uint32_t REPLACEMENT_CHAR_;
-  int64_t serialVersionUID;
+  int64_t serialVersionUID_;
+  friend struct StringClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
 };
 
@@ -2367,13 +2369,15 @@
   uint32_t TYPE_INTEGER_;
   uint32_t TYPE_LONG_;
   uint32_t TYPE_SHORT_;
+  friend struct FieldClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(FieldClass);
 };
 
 class MethodClass : public Class {
  private:
-  int32_t DECLARED_;
-  int32_t PUBLIC_;
+  ObjectArray<Object>* NO_ANNOTATIONS_;
+  Object* ORDER_BY_SIGNATURE_;
+  friend struct MethodClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(MethodClass);
 };
 
@@ -2528,12 +2532,12 @@
   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
   CharArray* array_;
 
+  int32_t count_;
+
   uint32_t hash_code_;
 
   int32_t offset_;
 
-  int32_t count_;
-
   static Class* java_lang_String_;
 
   friend struct StringOffsets;  // for verifying offset information