More field order validation.

This is to set me up to remove the redundant fields like declaring
class and name from field and method.

Change-Id: Ie834c615b33caed89c443fa23c25b7757d4b7ef3
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 7c33930..cdcf8fb 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -398,18 +398,44 @@
   AssertDexFile(libcore_dex_file.get());
 }
 
-// C++ fields must exactly match the fields in the Java class. If this fails,
+// C++ fields must exactly match the fields in the Java classes. If this fails,
 // reorder the fields in the C++ class. Managed class fields are ordered by
 // ClassLinker::LinkInstanceFields.
-TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaLangString) {
-  scoped_ptr<DexFile> libcore_dex_file(GetLibCoreDex());
-  EXPECT_TRUE(libcore_dex_file.get() != NULL); // Passes on host only until we have DexFile::OpenJar
-  class_linker_->RegisterDexFile(libcore_dex_file.get());
-  Class* string = class_linker_->FindClass( "Ljava/lang/String;", NULL, libcore_dex_file.get());
+TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
+  UseLibCoreDex();
+  Class* string = class_linker_->FindClass( "Ljava/lang/String;", NULL, java_lang_dex_file_.get());
+  ASSERT_EQ(4U, string->NumInstanceFields());
   EXPECT_EQ("value",    string->GetInstanceField(0)->GetName());
   EXPECT_EQ("hashCode", string->GetInstanceField(1)->GetName());
   EXPECT_EQ("offset",   string->GetInstanceField(2)->GetName());
   EXPECT_EQ("count",    string->GetInstanceField(3)->GetName());
+
+  Class* accessible_object = class_linker_->FindClass("Ljava/lang/reflect/AccessibleObject;", NULL, java_lang_dex_file_.get());
+  ASSERT_EQ(1U, accessible_object->NumInstanceFields());
+  EXPECT_EQ("flag", accessible_object->GetInstanceField(0)->GetName());
+
+  Class* field = class_linker_->FindClass("Ljava/lang/reflect/Field;", NULL, java_lang_dex_file_.get());
+  ASSERT_EQ(6U, field->NumInstanceFields());
+  EXPECT_EQ("declaringClass",             field->GetInstanceField(0)->GetName());
+  EXPECT_EQ("genericType",                field->GetInstanceField(1)->GetName());
+  EXPECT_EQ("type",                       field->GetInstanceField(2)->GetName());
+  EXPECT_EQ("name",                       field->GetInstanceField(3)->GetName());
+  EXPECT_EQ("slot",                       field->GetInstanceField(4)->GetName());
+  EXPECT_EQ("genericTypesAreInitialized", field->GetInstanceField(5)->GetName());
+
+  Class* method = class_linker_->FindClass("Ljava/lang/reflect/Method;", NULL, java_lang_dex_file_.get());
+  ASSERT_EQ(11U, method->NumInstanceFields());
+  EXPECT_EQ("declaringClass",             method->GetInstanceField( 0)->GetName());
+  EXPECT_EQ("exceptionTypes",             method->GetInstanceField( 1)->GetName());
+  EXPECT_EQ("formalTypeParameters",       method->GetInstanceField( 2)->GetName());
+  EXPECT_EQ("genericExceptionTypes",      method->GetInstanceField( 3)->GetName());
+  EXPECT_EQ("genericParameterTypes",      method->GetInstanceField( 4)->GetName());
+  EXPECT_EQ("genericReturnType",          method->GetInstanceField( 5)->GetName());
+  EXPECT_EQ("returnType",                 method->GetInstanceField( 6)->GetName());
+  EXPECT_EQ("name",                       method->GetInstanceField( 7)->GetName());
+  EXPECT_EQ("parameterTypes",             method->GetInstanceField( 8)->GetName());
+  EXPECT_EQ("genericTypesAreInitialized", method->GetInstanceField( 9)->GetName());
+  EXPECT_EQ("slot",                       method->GetInstanceField(10)->GetName());
 }
 
 }  // namespace art
diff --git a/src/common_test.h b/src/common_test.h
index c4a3d1f..cfc0a5f 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -211,6 +211,18 @@
     return DexFile::OpenFile(libcore_dex_file_name.c_str());
   }
 
+  void UseLibCoreDex() {
+    delete runtime_.release();
+    java_lang_dex_file_.reset(GetLibCoreDex());
+
+    std::vector<DexFile*> boot_class_path;
+    boot_class_path.push_back(java_lang_dex_file_.get());
+
+    runtime_.reset(Runtime::Create(boot_class_path));
+    ASSERT_TRUE(runtime_ != NULL);
+    class_linker_ = runtime_->GetClassLinker();
+  }
+
   bool is_host_;
   scoped_ptr<DexFile> java_lang_dex_file_;
   scoped_ptr<Runtime> runtime_;
diff --git a/src/object.h b/src/object.h
index fbeac8f..4d68d30 100644
--- a/src/object.h
+++ b/src/object.h
@@ -23,6 +23,7 @@
 class Monitor;
 class Method;
 class Object;
+class String;
 template<class T> class ObjectArray;
 class StaticField;
 
@@ -244,7 +245,13 @@
   DISALLOW_COPY_AND_ASSIGN(ObjectLock);
 };
 
-class Field : public Object {
+class AccessibleObject : public Object {
+ private:
+  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+  uint32_t java_flag_;
+};
+
+class Field : public AccessibleObject {
  public:
   Class* GetDeclaringClass() const {
     return declaring_class_;
@@ -263,16 +270,13 @@
   }
 
  public:  // TODO: private
-#define FIELD_FIELD_SLOTS 1+6
-  // AccessibleObject #0 flag
-  // Field #0 declaringClass
-  // Field #1 genericType
-  // Field #2 genericTypesAreInitialized
-  // Field #3 name
-  // Field #4 slot
-  // Field #5 type
-  uint32_t instance_data_[FIELD_FIELD_SLOTS];
-#undef FIELD_FIELD_SLOTS
+  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+  Class* java_declaring_class_;
+  Object* java_generic_type_;
+  uint32_t java_generic_types_are_initialized_;
+  String* java_name_;
+  uint32_t java_slot_;
+  Class* java_type_;
 
   // The class in which this field is declared.
   Class* declaring_class_;
@@ -371,7 +375,7 @@
   StaticField();
 };
 
-class Method : public Object {
+class Method : public AccessibleObject {
  public:
   // Returns the method name, e.g. "<init>" or "eatLunch"
   const StringPiece& GetName() const {
@@ -435,21 +439,18 @@
   uint32_t NumArgRegisters();
 
  public:  // TODO: private
-#define METHOD_FIELD_SLOTS 1+11
-  // AccessibleObject #0 flag
-  // Method #0  declaringClass
-  // Method #1  exceptionTypes
-  // Method #2  formalTypeParameters
-  // Method #3  genericExceptionTypes
-  // Method #4  genericParameterTypes
-  // Method #5  genericReturnType
-  // Method #6  genericTypesAreInitialized
-  // Method #7  name
-  // Method #8  parameterTypes
-  // Method #9  returnType
-  // Method #10 slot
-  uint32_t instance_data_[METHOD_FIELD_SLOTS];
-#undef METHOD_FIELD_SLOTS
+  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+  Class* java_declaring_class_;
+  ObjectArray<Class>* java_exception_types_;
+  Object* java_formal_type_parameters_;
+  Object* java_generic_exception_types_;
+  Object* java_generic_parameter_types_;
+  Object* java_generic_return_type_;
+  Class* java_return_type_;
+  String* java_name_;
+  ObjectArray<Class>* java_parameter_types_;
+  uint32_t java_generic_types_are_initialized_;
+  uint32_t java_slot_;
 
   bool IsReturnAReference() const {
     return (shorty_[0] == 'L') || (shorty_[0] == '[');
@@ -1053,7 +1054,7 @@
   }
 
  public: // TODO: private
-  // Field order required by test "ValidateFieldOrderOfJavaLangString".
+  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
   CharArray* array_;
 
   uint32_t hash_code_;