diff options
Diffstat (limited to 'runtime/mirror/class.cc')
| -rw-r--r-- | runtime/mirror/class.cc | 151 |
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()); |