Fix recursive static field lookup.

Change-Id: I892696e6e98be9f31a7900d10130cae204f9127a
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 4133a86..5439489 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -386,11 +386,11 @@
 
   // Sanity check Class[] and Object[]'s interfaces
   ClassHelper kh(class_array_class.get(), this);
-  CHECK_EQ(java_lang_Cloneable, kh.GetInterface(0));
-  CHECK_EQ(java_io_Serializable, kh.GetInterface(1));
+  CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
+  CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
   kh.ChangeClass(object_array_class.get());
-  CHECK_EQ(java_lang_Cloneable, kh.GetInterface(0));
-  CHECK_EQ(java_io_Serializable, kh.GetInterface(1));
+  CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
+  CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
   // run Class, Constructor, Field, and Method through FindSystemClass.
   // this initializes their dex_cache_ fields and register them in classes_.
   Class* Class_class = FindSystemClass("Ljava/lang/Class;");
@@ -2889,10 +2889,10 @@
   }
   size_t ifcount = super_ifcount;
   ClassHelper kh(klass.get(), this);
-  uint32_t num_interfaces = interfaces == NULL ? kh.NumInterfaces() : interfaces->GetLength();
+  uint32_t num_interfaces = interfaces == NULL ? kh.NumDirectInterfaces() : interfaces->GetLength();
   ifcount += num_interfaces;
   for (size_t i = 0; i < num_interfaces; i++) {
-    Class* interface = interfaces == NULL ? kh.GetInterface(i) : interfaces->Get(i);
+    Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
     ifcount += interface->GetIfTableCount();
   }
   if (ifcount == 0) {
@@ -2912,7 +2912,7 @@
   // Flatten the interface inheritance hierarchy.
   size_t idx = super_ifcount;
   for (size_t i = 0; i < num_interfaces; i++) {
-    Class* interface = interfaces == NULL ? kh.GetInterface(i) : interfaces->Get(i);
+    Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
     DCHECK(interface != NULL);
     if (!interface->IsInterface()) {
       ClassHelper ih(interface);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 07a9816..f677cae 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -71,7 +71,7 @@
     EXPECT_EQ(0U, primitive->NumVirtualMethods());
     EXPECT_EQ(0U, primitive->NumInstanceFields());
     EXPECT_EQ(0U, primitive->NumStaticFields());
-    EXPECT_EQ(0U, primitive_ch.NumInterfaces());
+    EXPECT_EQ(0U, primitive_ch.NumDirectInterfaces());
     EXPECT_TRUE(primitive->GetVTable() == NULL);
     EXPECT_EQ(0, primitive->GetIfTableCount());
     EXPECT_TRUE(primitive->GetIfTable() == NULL);
@@ -118,15 +118,15 @@
     EXPECT_EQ(0U, array->NumInstanceFields());
     EXPECT_EQ(0U, array->NumStaticFields());
     kh.ChangeClass(array);
-    EXPECT_EQ(2U, kh.NumInterfaces());
+    EXPECT_EQ(2U, kh.NumDirectInterfaces());
     EXPECT_TRUE(array->GetVTable() != NULL);
     EXPECT_EQ(2, array->GetIfTableCount());
     ObjectArray<InterfaceEntry>* iftable = array->GetIfTable();
     ASSERT_TRUE(iftable != NULL);
-    kh.ChangeClass(kh.GetInterface(0));
+    kh.ChangeClass(kh.GetDirectInterface(0));
     EXPECT_STREQ(kh.GetDescriptor(), "Ljava/lang/Cloneable;");
     kh.ChangeClass(array);
-    kh.ChangeClass(kh.GetInterface(1));
+    kh.ChangeClass(kh.GetDirectInterface(1));
     EXPECT_STREQ(kh.GetDescriptor(), "Ljava/io/Serializable;");
   }
 
@@ -699,7 +699,7 @@
   EXPECT_STREQ(fh.GetName(), "shadow$_monitor_");
 
   EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
-  EXPECT_EQ(0U, kh.NumInterfaces());
+  EXPECT_EQ(0U, kh.NumDirectInterfaces());
 
   SirtRef<ClassLoader> class_loader(LoadDex("MyClass"));
   AssertNonExistentClass("LMyClass;");
@@ -731,7 +731,7 @@
   EXPECT_EQ(0U, MyClass->NumVirtualMethods());
   EXPECT_EQ(0U, MyClass->NumInstanceFields());
   EXPECT_EQ(0U, MyClass->NumStaticFields());
-  EXPECT_EQ(0U, kh.NumInterfaces());
+  EXPECT_EQ(0U, kh.NumDirectInterfaces());
 
   EXPECT_EQ(JavaLangObject->GetClass()->GetClass(), MyClass->GetClass()->GetClass());
 
@@ -956,6 +956,15 @@
   EXPECT_EQ(Ai, A->FindVirtualMethodForVirtualOrInterface(Ii));
   EXPECT_EQ(Aj1, A->FindVirtualMethodForVirtualOrInterface(Jj1));
   EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2));
+
+  Field* Afoo = A->FindStaticField("foo", "Ljava/lang/String;");
+  Field* Bfoo = B->FindStaticField("foo", "Ljava/lang/String;");
+  Field* Jfoo = J->FindStaticField("foo", "Ljava/lang/String;");
+  Field* Kfoo = K->FindStaticField("foo", "Ljava/lang/String;");
+  ASSERT_TRUE(Afoo != NULL);
+  EXPECT_EQ(Afoo, Bfoo);
+  EXPECT_EQ(Afoo, Jfoo);
+  EXPECT_EQ(Afoo, Kfoo);
 }
 
 TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
diff --git a/src/debugger.cc b/src/debugger.cc
index 2fa77ef..581645d 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -1080,10 +1080,10 @@
   }
 
   ClassHelper kh(c);
-  size_t interface_count = kh.NumInterfaces();
+  size_t interface_count = kh.NumDirectInterfaces();
   expandBufAdd4BE(pReply, interface_count);
   for (size_t i = 0; i < interface_count; ++i) {
-    expandBufAddRefTypeId(pReply, gRegistry->Add(kh.GetInterface(i)));
+    expandBufAddRefTypeId(pReply, gRegistry->Add(kh.GetDirectInterface(i)));
   }
   return JDWP::ERR_NONE;
 }
diff --git a/src/object.cc b/src/object.cc
index 6dda684..9724e42 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -753,10 +753,10 @@
   if (IsArrayClass()) {
     os << "  componentType=" << PrettyClass(GetComponentType()) << "\n";
   }
-  if (kh.NumInterfaces() > 0) {
-    os << "  interfaces (" << kh.NumInterfaces() << "):\n";
-    for (size_t i = 0; i < kh.NumInterfaces(); ++i) {
-      Class* interface = kh.GetInterface(i);
+  if (kh.NumDirectInterfaces() > 0) {
+    os << "  interfaces (" << kh.NumDirectInterfaces() << "):\n";
+    for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+      Class* interface = kh.GetDirectInterface(i);
       const ClassLoader* cl = interface->GetClassLoader();
       os << StringPrintf("    %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
     }
@@ -1174,9 +1174,9 @@
     }
     // Is this field in any of this class' interfaces?
     kh.ChangeClass(k);
-    for (uint32_t i = 0; i < kh.NumInterfaces(); ++i) {
-      Class* interface = kh.GetInterface(i);
-      f = interface->FindDeclaredStaticField(name, type);
+    for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+      Class* interface = kh.GetDirectInterface(i);
+      f = interface->FindStaticField(name, type);
       if (f != NULL) {
         return f;
       }
@@ -1195,9 +1195,9 @@
     }
     // Is this field in any of this class' interfaces?
     kh.ChangeClass(k);
-    for (uint32_t i = 0; i < kh.NumInterfaces(); ++i) {
-      Class* interface = kh.GetInterface(i);
-      f = interface->FindDeclaredStaticField(dex_cache, dex_field_idx);
+    for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+      Class* interface = kh.GetDirectInterface(i);
+      f = interface->FindStaticField(dex_cache, dex_field_idx);
       if (f != NULL) {
         return f;
       }
@@ -1221,9 +1221,9 @@
     }
     // Is this field in any of this class' interfaces?
     kh.ChangeClass(k);
-    for (uint32_t i = 0; i < kh.NumInterfaces(); ++i) {
-      Class* interface = kh.GetInterface(i);
-      f = interface->FindDeclaredStaticField(name, type);
+    for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+      Class* interface = kh.GetDirectInterface(i);
+      f = interface->FindStaticField(name, type);
       if (f != NULL) {
         return f;
       }
diff --git a/src/object_test.cc b/src/object_test.cc
index de32f69..c0049a3 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -108,9 +108,9 @@
 
   ASSERT_TRUE(oa->GetClass() != NULL);
   ClassHelper oa_ch(oa->GetClass());
-  ASSERT_EQ(2U, oa_ch.NumInterfaces());
-  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Cloneable;"), oa_ch.GetInterface(0));
-  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/io/Serializable;"), oa_ch.GetInterface(1));
+  ASSERT_EQ(2U, oa_ch.NumDirectInterfaces());
+  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Cloneable;"), oa_ch.GetDirectInterface(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/io/Serializable;"), oa_ch.GetDirectInterface(1));
 }
 
 TEST_F(ObjectTest, AllocArray) {
diff --git a/src/object_utils.h b/src/object_utils.h
index ceef186..c186a24 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -126,7 +126,7 @@
     return result;
   }
 
-  uint32_t NumInterfaces() {
+  uint32_t NumDirectInterfaces() {
     DCHECK(klass_ != NULL);
     if (klass_->IsPrimitive()) {
       return 0;
@@ -144,14 +144,14 @@
     }
   }
 
-  uint16_t GetInterfaceTypeIdx(uint32_t idx) {
+  uint16_t GetDirectInterfaceTypeIdx(uint32_t idx) {
     DCHECK(klass_ != NULL);
     DCHECK(!klass_->IsPrimitive());
     DCHECK(!klass_->IsArrayClass());
     return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
   }
 
-  Class* GetInterface(uint32_t idx) {
+  Class* GetDirectInterface(uint32_t idx) {
     DCHECK(klass_ != NULL);
     DCHECK(!klass_->IsPrimitive());
     if (klass_->IsArrayClass()) {
@@ -164,7 +164,7 @@
     } else if (klass_->IsProxyClass()) {
       return klass_->GetIfTable()->Get(idx)->GetInterface();
     } else {
-      uint16_t type_idx = GetInterfaceTypeIdx(idx);
+      uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
       Class* interface = GetDexCache()->GetResolvedType(type_idx);
       if (interface == NULL) {
         interface = GetClassLinker()->ResolveType(GetDexFile(), type_idx, klass_);