Delete ClassHelper and fix compaction bug in GetDirectInterface
Cleanup helps to prevent compaction bugs. Fixed a fairly serious
compaction error caused by calling ClassHelper::GetDirectInterface
without handling the case where it causes thread suspension due to
ResolveType.
Bug: 8981901
Change-Id: I82b3bb6dd48d21eb6ece7aae0733c4a23c2bc408
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index b1e8c09..664ac89 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -66,171 +66,6 @@
DISALLOW_COPY_AND_ASSIGN(ObjectLock);
};
-class ClassHelper {
- public:
- explicit ClassHelper(mirror::Class* c )
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : interface_type_list_(nullptr), klass_(nullptr) {
- if (c != nullptr) {
- ChangeClass(c);
- }
- }
-
- void ChangeClass(mirror::Class* new_c)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(new_c != nullptr) << "klass_=" << klass_; // Log what we were changing from if any
- if (!new_c->IsClass()) {
- LOG(FATAL) << "new_c=" << new_c << " cc " << new_c->GetClass() << " ccc "
- << ((new_c->GetClass() != nullptr) ? new_c->GetClass()->GetClass() : nullptr);
- }
- klass_ = new_c;
- interface_type_list_ = nullptr;
- }
-
- // The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
- // If you need it longer, copy it into a std::string.
- const char* GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(klass_ != nullptr);
- if (UNLIKELY(klass_->IsArrayClass())) {
- return GetArrayDescriptor();
- } else if (UNLIKELY(klass_->IsPrimitive())) {
- return Primitive::Descriptor(klass_->GetPrimitiveType());
- } else if (UNLIKELY(klass_->IsProxyClass())) {
- descriptor_ = GetClassLinker()->GetDescriptorForProxy(klass_);
- return descriptor_.c_str();
- } else {
- const DexFile& dex_file = GetDexFile();
- const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
- return dex_file.GetTypeDescriptor(type_id);
- }
- }
-
- const char* GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string result("[");
- mirror::Class* saved_klass = klass_;
- CHECK(saved_klass != nullptr);
- ChangeClass(klass_->GetComponentType());
- result += GetDescriptor();
- ChangeClass(saved_klass);
- descriptor_ = result;
- return descriptor_.c_str();
- }
-
- const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- uint16_t class_def_idx = klass_->GetDexClassDefIndex();
- if (class_def_idx == DexFile::kDexNoIndex16) {
- return nullptr;
- }
- return &GetDexFile().GetClassDef(class_def_idx);
- }
-
- uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- if (klass_->IsPrimitive()) {
- return 0;
- } else if (klass_->IsArrayClass()) {
- return 2;
- } else if (klass_->IsProxyClass()) {
- mirror::SynthesizedProxyClass* proxyClass = reinterpret_cast<mirror::SynthesizedProxyClass*>(klass_);
- mirror::ObjectArray<mirror::Class>* interfaces = proxyClass->GetInterfaces();
- return interfaces != nullptr ? interfaces->GetLength() : 0;
- } else {
- const DexFile::TypeList* interfaces = GetInterfaceTypeList();
- if (interfaces == nullptr) {
- return 0;
- } else {
- return interfaces->Size();
- }
- }
- }
-
- uint16_t GetDirectInterfaceTypeIdx(uint32_t idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- DCHECK(!klass_->IsPrimitive());
- DCHECK(!klass_->IsArrayClass());
- return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
- }
-
- mirror::Class* GetDirectInterface(uint32_t idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- DCHECK(!klass_->IsPrimitive());
- if (klass_->IsArrayClass()) {
- if (idx == 0) {
- return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/lang/Cloneable;");
- } else {
- DCHECK_EQ(1U, idx);
- return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/io/Serializable;");
- }
- } else if (klass_->IsProxyClass()) {
- mirror::SynthesizedProxyClass* proxyClass = reinterpret_cast<mirror::SynthesizedProxyClass*>(klass_);
- mirror::ObjectArray<mirror::Class>* interfaces = proxyClass->GetInterfaces();
- DCHECK(interfaces != nullptr);
- return interfaces->Get(idx);
- } else {
- uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
- mirror::Class* interface = GetDexCache()->GetResolvedType(type_idx);
- if (interface == nullptr) {
- interface = GetClassLinker()->ResolveType(GetDexFile(), type_idx, klass_);
- CHECK(interface != nullptr || Thread::Current()->IsExceptionPending());
- }
- return interface;
- }
- }
-
- const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string descriptor(GetDescriptor());
- const DexFile& dex_file = GetDexFile();
- const DexFile::ClassDef* dex_class_def = GetClassDef();
- CHECK(dex_class_def != nullptr) << "No class def for class " << PrettyClass(klass_);
- return dex_file.GetSourceFile(*dex_class_def);
- }
-
- std::string GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::DexCache* dex_cache = GetDexCache();
- if (dex_cache != nullptr && !klass_->IsProxyClass()) {
- return dex_cache->GetLocation()->ToModifiedUtf8();
- } else {
- // Arrays and proxies are generated and have no corresponding dex file location.
- return "generated class";
- }
- }
-
- const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return *GetDexCache()->GetDexFile();
- }
-
- mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return klass_->GetDexCache();
- }
-
- private:
- const DexFile::TypeList* GetInterfaceTypeList()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::TypeList* result = interface_type_list_;
- if (result == nullptr) {
- const DexFile::ClassDef* class_def = GetClassDef();
- if (class_def != nullptr) {
- result = GetDexFile().GetInterfacesList(*class_def);
- interface_type_list_ = result;
- }
- }
- return result;
- }
-
- ClassLinker* GetClassLinker() ALWAYS_INLINE {
- return Runtime::Current()->GetClassLinker();
- }
-
- const DexFile::TypeList* interface_type_list_;
- mirror::Class* klass_;
- std::string descriptor_;
-
- DISALLOW_COPY_AND_ASSIGN(ClassHelper);
-};
-
class FieldHelper {
public:
FieldHelper() : field_(nullptr) {}
@@ -304,8 +139,7 @@
DCHECK(field_->IsStatic());
DCHECK_LT(field_index, 2U);
// 0 == Class[] interfaces; 1 == Class[][] throws;
- ClassHelper kh(field_->GetDeclaringClass());
- declaring_class_descriptor_ = kh.GetDescriptor();
+ declaring_class_descriptor_ = field_->GetDeclaringClass()->GetDescriptor();
return declaring_class_descriptor_.c_str();
}
const DexFile& dex_file = GetDexFile();
@@ -468,7 +302,7 @@
}
const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ClassHelper(method_->GetDeclaringClass()).GetSourceFile();
+ return method_->GetDeclaringClass()->GetSourceFile();
}
uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {