Validate the C++ and managed fields are ordered consistently.

Change-Id: If0d0fcc2ffcc0172bd86fd1714111857af572d6a
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 57abab8..5aea3aa 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -4,7 +4,6 @@
 #include "class_linker.h"
 #include "dex_file.h"
 #include "heap.h"
-#include "stringprintf.h"
 #include "gtest/gtest.h"
 
 namespace art {
@@ -183,7 +182,6 @@
       AssertDexFileClass(dex, descriptor);
     }
   }
-
 };
 
 TEST_F(ClassLinkerTest, FindClassNonexistent) {
@@ -386,16 +384,23 @@
 }
 
 TEST_F(ClassLinkerTest, LibCore) {
-  // TODO add host support when we have DexFile::OpenJar
-  if (!is_host_) {
-    return;
-  }
-
-  // TODO switch to jar when we have DexFile::OpenJar
-  std::string libcore_dex_file_name = StringPrintf("%s/out/target/common/obj/JAVA_LIBRARIES/core_intermediates/noproguard.classes.dex",
-                                                   getenv("ANDROID_BUILD_TOP"));
-  scoped_ptr<DexFile> libcore_dex_file(DexFile::OpenFile(libcore_dex_file_name.c_str()));
+  scoped_ptr<DexFile> libcore_dex_file(GetLibCoreDex());
+  EXPECT_TRUE(libcore_dex_file.get() != NULL); // Passes on host only until we have DexFile::OpenJar
   AssertDexFile(libcore_dex_file.get());
 }
 
+// C++ fields must exactly match the fields in the Java class. 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());
+  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());
+}
+
 }  // namespace art
diff --git a/src/common_test.h b/src/common_test.h
index 1c4790b..a1b5f34 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -3,6 +3,7 @@
 #include "base64.h"
 #include "heap.h"
 #include "thread.h"
+#include "stringprintf.h"
 #include "class_linker.h"
 #include "dex_file.h"
 
@@ -185,6 +186,18 @@
     class_linker_ = runtime_->GetClassLinker();
   }
 
+  DexFile* GetLibCoreDex() {
+    // TODO add host support when we have DexFile::OpenJar
+    // TODO switch to jar when we have DexFile::OpenJar
+    if (!is_host_) {
+      return NULL;
+    }
+
+    std::string libcore_dex_file_name = StringPrintf("%s/out/target/common/obj/JAVA_LIBRARIES/core_intermediates/noproguard.classes.dex",
+                                                     getenv("ANDROID_BUILD_TOP"));
+    return DexFile::OpenFile(libcore_dex_file_name.c_str());
+  }
+
   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 0abf444..05071cc 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1043,6 +1043,7 @@
   }
 
  public: // TODO: private
+  // Field order required by test "ValidateFieldOrderOfJavaLangString".
   CharArray* array_;
 
   uint32_t hash_code_;