summaryrefslogtreecommitdiff
path: root/runtime/mirror/class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/class.cc')
-rw-r--r--runtime/mirror/class.cc151
1 files changed, 66 insertions, 85 deletions
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 6543435720..110a8c541b 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -378,6 +378,7 @@ ObjPtr<String> Class::ComputeName(Handle<Class> h_this) {
}
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 @@ void Class::DumpClass(std::ostream& os, int flags) {
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 @@ void Class::DumpClass(std::ostream& os, int flags) {
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 @@ void Class::DumpClass(std::ostream& os, int flags) {
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>";
@@ -1027,13 +1023,11 @@ ArtField* Class::FindDeclaredStaticField(ObjPtr<DexCache> dex_cache, uint32_t de
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) {
@@ -1041,9 +1035,9 @@ ArtField* Class::FindStaticField(Thread* self,
}
// 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;
}
@@ -1052,24 +1046,19 @@ ArtField* Class::FindStaticField(Thread* self,
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;
}
@@ -1080,22 +1069,20 @@ ArtField* Class::FindStaticField(Thread* self,
// 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;
@@ -1128,9 +1115,9 @@ ArtField* Class::FindField(Thread* self,
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;
}
@@ -1140,12 +1127,11 @@ ArtField* Class::FindField(Thread* self,
};
// 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;
@@ -1154,14 +1140,14 @@ ArtField* Class::FindField(Thread* self,
// 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) {
@@ -1284,35 +1270,30 @@ dex::TypeIndex Class::GetDirectInterfaceTypeIdx(uint32_t idx) {
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());