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_);
diff --git a/test/Interfaces/Interfaces.java b/test/Interfaces/Interfaces.java
index 4a13e56..db60253 100644
--- a/test/Interfaces/Interfaces.java
+++ b/test/Interfaces/Interfaces.java
@@ -19,6 +19,7 @@
public void i();
}
interface J {
+ public String foo = "foo";
public void j1();
public void j2();
}