Clean up Class::GetDirectInterface().
Fetch array interfaces from the `IfTable`. This removes the
only use of the `Thread* self` argument, so we can remove
that argument. We also make the function non-static to avoid
the explicit `klass` argument. Similarly clean up arguments
of `Class::FindClass()` and `Class::FindStaticClass()`.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 181943478
Change-Id: Id639b675b4eb331a777cf318eb61bd19e05de4f0
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 50b5357..0eeda74 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -897,15 +897,11 @@
object_array_class->GetIfTable()->SetInterface(0, java_lang_Cloneable.Get());
object_array_class->GetIfTable()->SetInterface(1, java_io_Serializable.Get());
- // Check Class[] and Object[]'s interfaces. GetDirectInterface may cause thread suspension.
- CHECK_EQ(java_lang_Cloneable.Get(),
- mirror::Class::GetDirectInterface(self, class_array_class.Get(), 0));
- CHECK_EQ(java_io_Serializable.Get(),
- mirror::Class::GetDirectInterface(self, class_array_class.Get(), 1));
- CHECK_EQ(java_lang_Cloneable.Get(),
- mirror::Class::GetDirectInterface(self, object_array_class.Get(), 0));
- CHECK_EQ(java_io_Serializable.Get(),
- mirror::Class::GetDirectInterface(self, object_array_class.Get(), 1));
+ // Check Class[] and Object[]'s interfaces.
+ CHECK_EQ(java_lang_Cloneable.Get(), class_array_class->GetDirectInterface(0));
+ CHECK_EQ(java_io_Serializable.Get(), class_array_class->GetDirectInterface(1));
+ CHECK_EQ(java_lang_Cloneable.Get(), object_array_class->GetDirectInterface(0));
+ CHECK_EQ(java_io_Serializable.Get(), object_array_class->GetDirectInterface(1));
CHECK_EQ(object_array_string.Get(),
FindSystemClass(self, GetClassRootDescriptor(ClassRoot::kJavaLangStringArrayClass)));
@@ -1859,10 +1855,9 @@
return true;
};
class_table->Visit(verify_direct_interfaces_in_table);
- Thread* self = Thread::Current();
for (ObjPtr<mirror::Class> klass : classes) {
for (uint32_t i = 0, num = klass->NumDirectInterfaces(); i != num; ++i) {
- CHECK(klass->GetDirectInterface(self, klass, i) != nullptr)
+ CHECK(klass->GetDirectInterface(i) != nullptr)
<< klass->PrettyDescriptor() << " iface #" << i;
}
}
@@ -5401,7 +5396,7 @@
StackHandleScope<1> hs_iface(self);
MutableHandle<mirror::Class> handle_scope_iface(hs_iface.NewHandle<mirror::Class>(nullptr));
for (size_t i = 0; i < num_direct_interfaces; i++) {
- handle_scope_iface.Assign(mirror::Class::GetDirectInterface(self, klass.Get(), i));
+ handle_scope_iface.Assign(klass->GetDirectInterface(i));
CHECK(handle_scope_iface != nullptr) << klass->PrettyDescriptor() << " iface #" << i;
CHECK(handle_scope_iface->IsInterface());
if (handle_scope_iface->HasBeenRecursivelyInitialized()) {
@@ -5554,7 +5549,7 @@
MutableHandle<mirror::Class> handle_super_iface(hs.NewHandle<mirror::Class>(nullptr));
// First we initialize all of iface's super-interfaces recursively.
for (size_t i = 0; i < num_direct_ifaces; i++) {
- ObjPtr<mirror::Class> super_iface = mirror::Class::GetDirectInterface(self, iface.Get(), i);
+ ObjPtr<mirror::Class> super_iface = iface->GetDirectInterface(i);
CHECK(super_iface != nullptr) << iface->PrettyDescriptor() << " iface #" << i;
if (!super_iface->HasBeenRecursivelyInitialized()) {
// Recursive step
@@ -7185,8 +7180,7 @@
// super_ifcount entries filled in with the transitive closure of the interfaces of the superclass.
// The other entries are uninitialized. We will fill in the remaining entries in this function. The
// iftable must be large enough to hold all interfaces without changing its size.
-static size_t FillIfTable(Thread* self,
- ObjPtr<mirror::Class> klass,
+static size_t FillIfTable(ObjPtr<mirror::Class> klass,
ObjPtr<mirror::ObjectArray<mirror::Class>> interfaces,
ObjPtr<mirror::IfTable> iftable,
size_t super_ifcount,
@@ -7207,9 +7201,8 @@
size_t filled_ifcount = super_ifcount;
const bool have_interfaces = interfaces != nullptr;
for (size_t i = 0; i != num_interfaces; ++i) {
- ObjPtr<mirror::Class> interface = have_interfaces
- ? interfaces->Get(i)
- : mirror::Class::GetDirectInterface(self, klass, i);
+ ObjPtr<mirror::Class> interface =
+ have_interfaces ? interfaces->Get(i) : klass->GetDirectInterface(i);
// Let us call the first filled_ifcount elements of iftable the current-iface-list.
// At this point in the loop current-iface-list has the invariant that:
@@ -7301,9 +7294,8 @@
size_t ifcount = super_ifcount + num_interfaces;
// Check that every class being implemented is an interface.
for (size_t i = 0; i < num_interfaces; i++) {
- ObjPtr<mirror::Class> interface = have_interfaces
- ? interfaces->GetWithoutChecks(i)
- : mirror::Class::GetDirectInterface(self, klass.Get(), i);
+ ObjPtr<mirror::Class> interface =
+ have_interfaces ? interfaces->GetWithoutChecks(i) : klass->GetDirectInterface(i);
DCHECK(interface != nullptr);
if (UNLIKELY(!interface->IsInterface())) {
std::string temp;
@@ -7335,8 +7327,8 @@
// doesn't really do anything.
self->AllowThreadSuspension();
- const size_t new_ifcount = FillIfTable(
- self, klass.Get(), interfaces.Get(), iftable.Get(), super_ifcount, num_interfaces);
+ const size_t new_ifcount =
+ FillIfTable(klass.Get(), interfaces.Get(), iftable.Get(), super_ifcount, num_interfaces);
self->AllowThreadSuspension();
@@ -9313,18 +9305,15 @@
ObjPtr<mirror::ClassLoader> class_loader,
uint32_t field_idx,
bool is_static) {
- ArtField* resolved = nullptr;
- Thread* self = is_static ? Thread::Current() : nullptr;
- const DexFile& dex_file = *dex_cache->GetDexFile();
-
- resolved = is_static ? mirror::Class::FindStaticField(self, klass, dex_cache, field_idx)
- : klass->FindInstanceField(dex_cache, field_idx);
+ ArtField* resolved = is_static ? klass->FindStaticField(dex_cache, field_idx)
+ : klass->FindInstanceField(dex_cache, field_idx);
if (resolved == nullptr) {
+ const DexFile& dex_file = *dex_cache->GetDexFile();
const dex::FieldId& field_id = dex_file.GetFieldId(field_idx);
const char* name = dex_file.GetFieldName(field_id);
const char* type = dex_file.GetFieldTypeDescriptor(field_id);
- resolved = is_static ? mirror::Class::FindStaticField(self, klass, name, type)
+ resolved = is_static ? klass->FindStaticField(name, type)
: klass->FindInstanceField(name, type);
}
@@ -9346,8 +9335,7 @@
ObjPtr<mirror::DexCache> dex_cache,
ObjPtr<mirror::ClassLoader> class_loader,
uint32_t field_idx) {
- Thread* self = Thread::Current();
- ArtField* resolved = mirror::Class::FindField(self, klass, dex_cache, field_idx);
+ ArtField* resolved = klass->FindField(dex_cache, field_idx);
if (resolved != nullptr &&
hiddenapi::ShouldDenyAccessToMember(resolved,
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index c561c4d..5dc194f 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -231,12 +231,10 @@
EXPECT_TRUE(array->ShouldHaveEmbeddedVTable());
EXPECT_EQ(2, array->GetIfTableCount());
ASSERT_TRUE(array->GetIfTable() != nullptr);
- ObjPtr<mirror::Class> direct_interface0 =
- mirror::Class::GetDirectInterface(self, array.Get(), 0);
+ ObjPtr<mirror::Class> direct_interface0 = array->GetDirectInterface(0);
EXPECT_TRUE(direct_interface0 != nullptr);
EXPECT_STREQ(direct_interface0->GetDescriptor(&temp), "Ljava/lang/Cloneable;");
- ObjPtr<mirror::Class> direct_interface1 =
- mirror::Class::GetDirectInterface(self, array.Get(), 1);
+ ObjPtr<mirror::Class> direct_interface1 = array->GetDirectInterface(1);
EXPECT_STREQ(direct_interface1->GetDescriptor(&temp), "Ljava/io/Serializable;");
EXPECT_OBJ_PTR_EQ(class_linker_->FindArrayClass(self, array->GetComponentType()), array.Get());
@@ -1182,48 +1180,47 @@
EXPECT_EQ(9U, statics->NumStaticFields());
- ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s0", "Z");
+ ArtField* s0 = statics->FindStaticField("s0", "Z");
EXPECT_EQ(s0->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
EXPECT_EQ(true, s0->GetBoolean(statics.Get()));
s0->SetBoolean<false>(statics.Get(), false);
- ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s1", "B");
+ ArtField* s1 = statics->FindStaticField("s1", "B");
EXPECT_EQ(s1->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
EXPECT_EQ(5, s1->GetByte(statics.Get()));
s1->SetByte<false>(statics.Get(), 6);
- ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s2", "C");
+ ArtField* s2 = statics->FindStaticField("s2", "C");
EXPECT_EQ(s2->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
EXPECT_EQ('a', s2->GetChar(statics.Get()));
s2->SetChar<false>(statics.Get(), 'b');
- ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s3", "S");
+ ArtField* s3 = statics->FindStaticField("s3", "S");
EXPECT_EQ(s3->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
EXPECT_EQ(-536, s3->GetShort(statics.Get()));
s3->SetShort<false>(statics.Get(), -535);
- ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s4", "I");
+ ArtField* s4 = statics->FindStaticField("s4", "I");
EXPECT_EQ(s4->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(2000000000, s4->GetInt(statics.Get()));
s4->SetInt<false>(statics.Get(), 2000000001);
- ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s5", "J");
+ ArtField* s5 = statics->FindStaticField("s5", "J");
EXPECT_EQ(s5->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get()));
s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12));
- ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s6", "F");
+ ArtField* s6 = statics->FindStaticField("s6", "F");
EXPECT_EQ(s6->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
EXPECT_DOUBLE_EQ(0.5, s6->GetFloat(statics.Get()));
s6->SetFloat<false>(statics.Get(), 0.75);
- ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s7", "D");
+ ArtField* s7 = statics->FindStaticField("s7", "D");
EXPECT_EQ(s7->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
EXPECT_DOUBLE_EQ(16777217.0, s7->GetDouble(statics.Get()));
s7->SetDouble<false>(statics.Get(), 16777219);
- ArtField* s8 = mirror::Class::FindStaticField(
- soa.Self(), statics.Get(), "s8", "Ljava/lang/String;");
+ ArtField* s8 = statics->FindStaticField("s8", "Ljava/lang/String;");
EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
ObjPtr<mirror::String> str_value = mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot");
@@ -1300,14 +1297,10 @@
EXPECT_EQ(Aj1, A->FindVirtualMethodForVirtualOrInterface(Jj1, kRuntimePointerSize));
EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2, kRuntimePointerSize));
- ArtField* Afoo =
- mirror::Class::FindStaticField(soa.Self(), A.Get(), "foo", "Ljava/lang/String;");
- ArtField* Bfoo =
- mirror::Class::FindStaticField(soa.Self(), B.Get(), "foo", "Ljava/lang/String;");
- ArtField* Jfoo =
- mirror::Class::FindStaticField(soa.Self(), J.Get(), "foo", "Ljava/lang/String;");
- ArtField* Kfoo =
- mirror::Class::FindStaticField(soa.Self(), K.Get(), "foo", "Ljava/lang/String;");
+ ArtField* Afoo = A->FindStaticField("foo", "Ljava/lang/String;");
+ ArtField* Bfoo = B->FindStaticField("foo", "Ljava/lang/String;");
+ ArtField* Jfoo = J->FindStaticField("foo", "Ljava/lang/String;");
+ ArtField* Kfoo = K->FindStaticField("foo", "Ljava/lang/String;");
ASSERT_TRUE(Afoo != nullptr);
EXPECT_EQ(Afoo, Bfoo);
EXPECT_EQ(Afoo, Jfoo);
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index f483ad3..45fbf00 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -476,8 +476,7 @@
}
std::string temp;
if (is_static) {
- field = mirror::Class::FindStaticField(
- soa.Self(), c.Get(), name, field_type->GetDescriptor(&temp));
+ field = c->FindStaticField(name, field_type->GetDescriptor(&temp));
} else {
field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
}
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index e6397cb..8bec7e4 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -378,6 +378,7 @@
}
void Class::DumpClass(std::ostream& os, int flags) {
+ ScopedAssertNoThreadSuspension ants(__FUNCTION__);
if ((flags & kDumpClassFullDetail) == 0) {
os << PrettyClass();
if ((flags & kDumpClassClassLoader) != 0) {
@@ -390,22 +391,19 @@
return;
}
- Thread* const self = Thread::Current();
- StackHandleScope<2> hs(self);
- Handle<Class> h_this(hs.NewHandle(this));
- Handle<Class> h_super(hs.NewHandle(GetSuperClass()));
+ ObjPtr<Class> super = GetSuperClass();
auto image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
std::string temp;
os << "----- " << (IsInterface() ? "interface" : "class") << " "
- << "'" << GetDescriptor(&temp) << "' cl=" << GetClassLoader() << " -----\n",
- os << " objectSize=" << SizeOf() << " "
- << "(" << (h_super != nullptr ? h_super->SizeOf() : -1) << " from super)\n",
- os << StringPrintf(" access=0x%04x.%04x\n",
- GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
- if (h_super != nullptr) {
- os << " super='" << h_super->PrettyClass() << "' (cl=" << h_super->GetClassLoader()
- << ")\n";
+ << "'" << GetDescriptor(&temp) << "' cl=" << GetClassLoader() << " -----\n"
+ << " objectSize=" << SizeOf() << " "
+ << "(" << (super != nullptr ? super->SizeOf() : -1) << " from super)\n"
+ << StringPrintf(" access=0x%04x.%04x\n",
+ GetAccessFlags() >> 16,
+ GetAccessFlags() & kAccJavaFlagsMask);
+ if (super != nullptr) {
+ os << " super='" << super->PrettyClass() << "' (cl=" << super->GetClassLoader() << ")\n";
}
if (IsArrayClass()) {
os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
@@ -414,7 +412,7 @@
if (num_direct_interfaces > 0) {
os << " interfaces (" << num_direct_interfaces << "):\n";
for (size_t i = 0; i < num_direct_interfaces; ++i) {
- ObjPtr<Class> interface = GetDirectInterface(self, h_this.Get(), i);
+ ObjPtr<Class> interface = GetDirectInterface(i);
if (interface == nullptr) {
os << StringPrintf(" %2zd: nullptr!\n", i);
} else {
@@ -426,35 +424,33 @@
if (!IsLoaded()) {
os << " class not yet loaded";
} else {
- // After this point, this may have moved due to GetDirectInterface.
- os << " vtable (" << h_this->NumVirtualMethods() << " entries, "
- << (h_super != nullptr ? h_super->NumVirtualMethods() : 0) << " in super):\n";
+ os << " vtable (" << NumVirtualMethods() << " entries, "
+ << (super != nullptr ? super->NumVirtualMethods() : 0) << " in super):\n";
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
os << StringPrintf(" %2zd: %s\n", i, ArtMethod::PrettyMethod(
- h_this->GetVirtualMethodDuringLinking(i, image_pointer_size)).c_str());
+ GetVirtualMethodDuringLinking(i, image_pointer_size)).c_str());
}
- os << " direct methods (" << h_this->NumDirectMethods() << " entries):\n";
- for (size_t i = 0; i < h_this->NumDirectMethods(); ++i) {
+ os << " direct methods (" << NumDirectMethods() << " entries):\n";
+ for (size_t i = 0; i < NumDirectMethods(); ++i) {
os << StringPrintf(" %2zd: %s\n", i, ArtMethod::PrettyMethod(
- h_this->GetDirectMethod(i, image_pointer_size)).c_str());
+ GetDirectMethod(i, image_pointer_size)).c_str());
}
- if (h_this->NumStaticFields() > 0) {
- os << " static fields (" << h_this->NumStaticFields() << " entries):\n";
- if (h_this->IsResolved()) {
- for (size_t i = 0; i < h_this->NumStaticFields(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i,
- ArtField::PrettyField(h_this->GetStaticField(i)).c_str());
+ if (NumStaticFields() > 0) {
+ os << " static fields (" << NumStaticFields() << " entries):\n";
+ if (IsResolved()) {
+ for (size_t i = 0; i < NumStaticFields(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, ArtField::PrettyField(GetStaticField(i)).c_str());
}
} else {
os << " <not yet available>";
}
}
- if (h_this->NumInstanceFields() > 0) {
- os << " instance fields (" << h_this->NumInstanceFields() << " entries):\n";
- if (h_this->IsResolved()) {
- for (size_t i = 0; i < h_this->NumInstanceFields(); ++i) {
+ if (NumInstanceFields() > 0) {
+ os << " instance fields (" << NumInstanceFields() << " entries):\n";
+ if (IsResolved()) {
+ for (size_t i = 0; i < NumInstanceFields(); ++i) {
os << StringPrintf(" %2zd: %s\n", i,
- ArtField::PrettyField(h_this->GetInstanceField(i)).c_str());
+ ArtField::PrettyField(GetInstanceField(i)).c_str());
}
} else {
os << " <not yet available>";
@@ -1035,13 +1031,11 @@
return nullptr;
}
-ArtField* Class::FindStaticField(Thread* self,
- ObjPtr<Class> klass,
- std::string_view name,
- std::string_view type) {
+ArtField* Class::FindStaticField(std::string_view name, std::string_view type) {
+ ScopedAssertNoThreadSuspension ants(__FUNCTION__);
// Is the field in this class (or its interfaces), or any of its
// superclasses (or their interfaces)?
- for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
+ for (ObjPtr<Class> k = this; k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredStaticField(name, type);
if (f != nullptr) {
@@ -1049,9 +1043,9 @@
}
// Is this field in any of this class' interfaces?
for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
- ObjPtr<Class> interface = GetDirectInterface(self, k, i);
+ ObjPtr<Class> interface = k->GetDirectInterface(i);
DCHECK(interface != nullptr);
- f = FindStaticField(self, interface, name, type);
+ f = interface->FindStaticField(name, type);
if (f != nullptr) {
return f;
}
@@ -1060,24 +1054,19 @@
return nullptr;
}
-ArtField* Class::FindStaticField(Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<DexCache> dex_cache,
- uint32_t dex_field_idx) {
- for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
+ArtField* Class::FindStaticField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
+ ScopedAssertNoThreadSuspension ants(__FUNCTION__);
+ for (ObjPtr<Class> k = this; k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
if (f != nullptr) {
return f;
}
- // Though GetDirectInterface() should not cause thread suspension when called
- // from here, it takes a Handle as an argument, so we need to wrap `k`.
- ScopedAssertNoThreadSuspension ants(__FUNCTION__);
// Is this field in any of this class' interfaces?
for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
- ObjPtr<Class> interface = GetDirectInterface(self, k, i);
+ ObjPtr<Class> interface = k->GetDirectInterface(i);
DCHECK(interface != nullptr);
- f = FindStaticField(self, interface, dex_cache, dex_field_idx);
+ f = interface->FindStaticField(dex_cache, dex_field_idx);
if (f != nullptr) {
return f;
}
@@ -1088,22 +1077,20 @@
// Find a field using the JLS field resolution order
FLATTEN
-ArtField* Class::FindField(Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<mirror::DexCache> dex_cache,
- uint32_t field_idx) {
+ArtField* Class::FindField(ObjPtr<mirror::DexCache> dex_cache, uint32_t field_idx) {
// FIXME: Hijacking a proxy class by a custom class loader can break this assumption.
- DCHECK(!klass->IsProxyClass());
+ DCHECK(!IsProxyClass());
+
+ ScopedAssertNoThreadSuspension ants(__FUNCTION__);
// First try to find a declared field by `field_idx` if we have a `dex_cache` match.
- ObjPtr<DexCache> klass_dex_cache = klass->GetDexCache();
- if (klass_dex_cache == dex_cache) {
+ ObjPtr<DexCache> this_dex_cache = GetDexCache();
+ if (this_dex_cache == dex_cache) {
// Lookup is always performed in the class referenced by the FieldId.
- DCHECK_EQ(klass->dex_type_idx_,
- klass_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_.index_);
- ArtField* f = klass->FindDeclaredInstanceField(klass_dex_cache, field_idx);
+ DCHECK_EQ(dex_type_idx_, this_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_.index_);
+ ArtField* f = FindDeclaredInstanceField(this_dex_cache, field_idx);
if (f == nullptr) {
- f = klass->FindDeclaredStaticField(klass_dex_cache, field_idx);
+ f = FindDeclaredStaticField(this_dex_cache, field_idx);
}
if (f != nullptr) {
return f;
@@ -1136,9 +1123,9 @@
if (num_interfaces != 0u) {
ensure_name_and_type_initialized();
for (uint32_t i = 0; i != num_interfaces; ++i) {
- ObjPtr<Class> interface = GetDirectInterface(self, k, i);
+ ObjPtr<Class> interface = k->GetDirectInterface(i);
DCHECK(interface != nullptr);
- ArtField* f = FindStaticField(self, interface, name, type);
+ ArtField* f = interface->FindStaticField(name, type);
if (f != nullptr) {
return f;
}
@@ -1148,12 +1135,11 @@
};
// If we had a dex cache mismatch, search declared fields by name and type.
- if (klass_dex_cache != dex_cache &&
- (klass->GetIFieldsPtr() != nullptr || klass->GetSFieldsPtr() != nullptr)) {
+ if (this_dex_cache != dex_cache && (GetIFieldsPtr() != nullptr || GetSFieldsPtr() != nullptr)) {
ensure_name_and_type_initialized();
- ArtField* f = klass->FindDeclaredInstanceField(name, type);
+ ArtField* f = FindDeclaredInstanceField(name, type);
if (f == nullptr) {
- f = klass->FindDeclaredStaticField(name, type);
+ f = FindDeclaredStaticField(name, type);
}
if (f != nullptr) {
return f;
@@ -1162,14 +1148,14 @@
// Search direct interfaces.
{
- ArtField* f = search_direct_interfaces(klass);
+ ArtField* f = search_direct_interfaces(this);
if (f != nullptr) {
return f;
}
}
// Continue searching in superclasses.
- for (ObjPtr<Class> k = klass->GetSuperClass(); k != nullptr; k = k->GetSuperClass()) {
+ for (ObjPtr<Class> k = GetSuperClass(); k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ObjPtr<DexCache> k_dex_cache = k->GetDexCache();
if (k_dex_cache == dex_cache) {
@@ -1292,35 +1278,30 @@
return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
}
-ObjPtr<Class> Class::GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint32_t idx) {
- DCHECK(klass != nullptr);
- DCHECK(!klass->IsPrimitive());
- if (klass->IsArrayClass()) {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- // Use ClassLinker::LookupClass(); avoid poisoning ObjPtr<>s by ClassLinker::FindSystemClass().
- ObjPtr<Class> interface;
- if (idx == 0) {
- interface = class_linker->LookupClass(self, "Ljava/lang/Cloneable;", nullptr);
- } else {
- DCHECK_EQ(1U, idx);
- interface = class_linker->LookupClass(self, "Ljava/io/Serializable;", nullptr);
- }
+ObjPtr<Class> Class::GetDirectInterface(uint32_t idx) {
+ DCHECK(!IsPrimitive());
+ if (IsArrayClass()) {
+ ObjPtr<IfTable> iftable = GetIfTable();
+ DCHECK(iftable != nullptr);
+ DCHECK_EQ(iftable->Count(), 2u);
+ DCHECK_LT(idx, 2u);
+ ObjPtr<Class> interface = iftable->GetInterface(idx);
DCHECK(interface != nullptr);
return interface;
- } else if (klass->IsProxyClass()) {
- ObjPtr<ObjectArray<Class>> interfaces = klass->GetProxyInterfaces();
+ } else if (IsProxyClass()) {
+ ObjPtr<ObjectArray<Class>> interfaces = GetProxyInterfaces();
DCHECK(interfaces != nullptr);
return interfaces->Get(idx);
} else {
- dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx);
+ dex::TypeIndex type_idx = GetDirectInterfaceTypeIdx(idx);
ObjPtr<Class> interface = Runtime::Current()->GetClassLinker()->LookupResolvedType(
- type_idx, klass->GetDexCache(), klass->GetClassLoader());
+ type_idx, GetDexCache(), GetClassLoader());
return interface;
}
}
ObjPtr<Class> Class::ResolveDirectInterface(Thread* self, Handle<Class> klass, uint32_t idx) {
- ObjPtr<Class> interface = GetDirectInterface(self, klass.Get(), idx);
+ ObjPtr<Class> interface = klass->GetDirectInterface(idx);
if (interface == nullptr) {
DCHECK(!klass->IsArrayClass());
DCHECK(!klass->IsProxyClass());
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index aff98ca..35ef358 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1092,10 +1092,7 @@
ArtField* GetStaticField(uint32_t i) REQUIRES_SHARED(Locks::mutator_lock_);
// Find a static or instance field using the JLS resolution order
- static ArtField* FindField(Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<mirror::DexCache> dex_cache,
- uint32_t field_idx)
+ ArtField* FindField(ObjPtr<mirror::DexCache> dex_cache, uint32_t field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
// Finds the given instance field in this class or a superclass.
@@ -1114,18 +1111,12 @@
REQUIRES_SHARED(Locks::mutator_lock_);
// Finds the given static field in this class or a superclass.
- static ArtField* FindStaticField(Thread* self,
- ObjPtr<Class> klass,
- std::string_view name,
- std::string_view type)
+ ArtField* FindStaticField(std::string_view name, std::string_view type)
REQUIRES_SHARED(Locks::mutator_lock_);
// Finds the given static field in this class or superclass, only searches classes that
// have the same dex cache.
- static ArtField* FindStaticField(Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<DexCache> dex_cache,
- uint32_t dex_field_idx)
+ ArtField* FindStaticField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
ArtField* FindDeclaredStaticField(std::string_view name, std::string_view type)
@@ -1219,11 +1210,10 @@
dex::TypeIndex GetDirectInterfaceTypeIdx(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_);
- // Get the direct interface of the `klass` at index `idx` if resolved, otherwise return null.
+ // Get the direct interface at index `idx` if resolved, otherwise return null.
// If the caller expects the interface to be resolved, for example for a resolved `klass`,
// that assumption should be checked by `DCHECK(result != nullptr)`.
- static ObjPtr<Class> GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint32_t idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<Class> GetDirectInterface(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_);
// Resolve and get the direct interface of the `klass` at index `idx`.
// Returns null with a pending exception if the resolution fails.
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 80ed832..e26cf42 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -147,9 +147,9 @@
Handle<mirror::Class> klass(hs.NewHandle(oa->GetClass()));
ASSERT_EQ(2U, klass->NumDirectInterfaces());
EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;"),
- mirror::Class::GetDirectInterface(soa.Self(), klass.Get(), 0));
+ klass->GetDirectInterface(0));
EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"),
- mirror::Class::GetDirectInterface(soa.Self(), klass.Get(), 1));
+ klass->GetDirectInterface(1));
}
TEST_F(ObjectTest, AllocArray) {
@@ -758,20 +758,16 @@
// Wrong type.
EXPECT_TRUE(c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "I") == nullptr);
- EXPECT_TRUE(mirror::Class::FindStaticField(
- soa.Self(), c.Get(), "CASE_INSENSITIVE_ORDER", "I") == nullptr);
+ EXPECT_TRUE(c->FindStaticField("CASE_INSENSITIVE_ORDER", "I") == nullptr);
// Wrong name.
EXPECT_TRUE(c->FindDeclaredStaticField(
"cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr);
- EXPECT_TRUE(
- mirror::Class::FindStaticField(
- soa.Self(), c.Get(), "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr);
+ EXPECT_TRUE(c->FindStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr);
// Right name and type.
ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
- ArtField* f2 = mirror::Class::FindStaticField(
- soa.Self(), c.Get(), "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+ ArtField* f2 = c->FindStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
EXPECT_TRUE(f1 != nullptr);
EXPECT_TRUE(f2 != nullptr);
EXPECT_EQ(f1, f2);
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 3760885..9acb0b7 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1419,8 +1419,7 @@
linker->EnsureInitialized(soa.Self(), dexfile, true, true);
for (std::pair<OatFileAssistant::DexOptNeeded, const char*> field : mapping) {
- ArtField* art_field = mirror::Class::FindStaticField(
- soa.Self(), dexfile.Get(), field.second, "I");
+ ArtField* art_field = dexfile->FindStaticField(field.second, "I");
ASSERT_FALSE(art_field == nullptr);
EXPECT_EQ(art_field->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(field.first, art_field->GetInt(dexfile.Get()));
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index d8e170b..d055186 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -68,8 +68,8 @@
ASSERT_TRUE(proxy_class->IsInitialized());
EXPECT_EQ(2U, proxy_class->NumDirectInterfaces()); // Interfaces$I and Interfaces$J.
- EXPECT_OBJ_PTR_EQ(I.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class.Get(), 0));
- EXPECT_OBJ_PTR_EQ(J.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class.Get(), 1));
+ EXPECT_OBJ_PTR_EQ(I.Get(), proxy_class->GetDirectInterface(0));
+ EXPECT_OBJ_PTR_EQ(J.Get(), proxy_class->GetDirectInterface(1));
std::string temp;
const char* proxy_class_descriptor = proxy_class->GetDescriptor(&temp);
EXPECT_STREQ("L$Proxy1234;", proxy_class_descriptor);