Initialize classes in GetFieldID/GetMethodID.

Change-Id: I2ccf5d021067e4d18803bd505d5bdc1fcbbb3433
diff --git a/src/class_linker.cc b/src/class_linker.cc
index a7d10f4..448a542 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -884,7 +884,6 @@
 
   Method* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
   if (clinit != NULL) {
-  } else {
     // JValue unused;
     // TODO: dvmCallMethod(self, method, NULL, &unused);
     // UNIMPLEMENTED(FATAL);
@@ -913,7 +912,7 @@
       klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
     const Class* super = klass->GetSuperClass();
     for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
-      const Method* method = klass->GetVirtualMethod(i);
+      const Method* method = super->GetVirtualMethod(i);
       if (method != super->GetVirtualMethod(i) &&
           !HasSameMethodDescriptorClasses(method, super, klass)) {
         LG << "Classes resolve differently in superclass";
@@ -995,7 +994,6 @@
 
 bool ClassLinker::InitializeSuperClass(Class* klass) {
   CHECK(klass != NULL);
-  MutexLock mu(classes_lock_);
   if (!klass->IsInterface() && klass->HasSuperClass()) {
     Class* super_class = klass->GetSuperClass();
     if (super_class->GetStatus() != Class::kStatusInitialized) {
@@ -1014,6 +1012,18 @@
   return true;
 }
 
+bool ClassLinker::EnsureInitialized(Class* c) {
+  CHECK(c != NULL);
+  if (c->IsInitialized()) {
+    return true;
+  }
+
+  c->MonitorExit();
+  InitializeClass(c);
+  c->MonitorEnter();
+  return !Thread::Current()->IsExceptionPending();
+}
+
 void ClassLinker::InitializeStaticFields(Class* klass) {
   size_t num_static_fields = klass->NumStaticFields();
   if (num_static_fields == 0) {
@@ -1028,6 +1038,10 @@
   const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
   CHECK(dex_class_def != NULL);
   const byte* addr = dex_file.GetEncodedArray(*dex_class_def);
+  if (addr == NULL) {
+    // All this class' static fields have default values.
+    return;
+  }
   size_t array_size = DecodeUnsignedLeb128(&addr);
   for (size_t i = 0; i < array_size; ++i) {
     Field* field = klass->GetStaticField(i);