From: Greg Clayton Date: Tue, 23 Oct 2012 22:41:19 +0000 (+0000) Subject: Objective C cleanup. Removed an cache that was no longer needed and changes the code... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d64dd12fcf550f4921b29fdc7deb6538cb6cb616;p=platform%2Fupstream%2Fllvm.git Objective C cleanup. Removed an cache that was no longer needed and changes the code that gets the dynamic type and class name to use our new Objective C cache. llvm-svn: 166512 --- diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index 82cf079..d071f9f 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -349,10 +349,10 @@ public: } void - SetName (ConstString &type_name_const_str); + SetName (const ConstString &type_name); void - SetName (const char *type_name_str); + SetName (const char *type_name_cstr); void SetTypeSP (lldb::TypeSP type_sp); diff --git a/lldb/include/lldb/Target/ObjCLanguageRuntime.h b/lldb/include/lldb/Target/ObjCLanguageRuntime.h index 7be517b..3721d82 100644 --- a/lldb/include/lldb/Target/ObjCLanguageRuntime.h +++ b/lldb/include/lldb/Target/ObjCLanguageRuntime.h @@ -45,14 +45,16 @@ public: public: ClassDescriptor() : - m_is_kvo(eLazyBoolCalculate), - m_is_cf(eLazyBoolCalculate) - {} - - ClassDescriptor (ObjCISA isa, lldb::ProcessSP process) : - m_is_kvo(eLazyBoolCalculate), - m_is_cf(eLazyBoolCalculate) - {} + m_is_kvo (eLazyBoolCalculate), + m_is_cf (eLazyBoolCalculate), + m_type_wp () + { + } + + virtual + ~ClassDescriptor () + { + } virtual ConstString GetClassName () = 0; @@ -118,9 +120,17 @@ public: return false; } - virtual - ~ClassDescriptor () - {} + lldb::TypeSP + GetType () + { + return m_type_wp.lock(); + } + + void + SetType (const lldb::TypeSP &type_sp) + { + m_type_wp = type_sp; + } protected: bool @@ -133,6 +143,7 @@ public: private: LazyBool m_is_kvo; LazyBool m_is_cf; + lldb::TypeWP m_type_wp; }; // a convenience subclass of ClassDescriptor meant to represent invalid objects @@ -141,6 +152,10 @@ public: public: ClassDescriptor_Invalid() {} + virtual + ~ClassDescriptor_Invalid () + {} + virtual ConstString GetClassName () { return ConstString(""); } @@ -164,11 +179,6 @@ public: { return false; } - - virtual - ~ClassDescriptor_Invalid () - {} - }; virtual ClassDescriptorSP @@ -443,10 +453,6 @@ protected: ISAToDescriptorMap m_isa_to_descriptor_cache; bool m_isa_to_descriptor_cache_is_up_to_date; - typedef std::map ClassNameMap; - typedef ClassNameMap::iterator ClassNameIterator; - ClassNameMap m_class_name_cache; - typedef std::map CompleteClassMap; CompleteClassMap m_complete_class_cache; diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 7867281..af2c20b 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -259,152 +259,31 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, if (CouldHaveDynamicValue (in_value)) { // First job, pull out the address at 0 offset from the object That will be the ISA pointer. - Error error; - const addr_t object_ptr = in_value.GetPointerValue(); - const addr_t isa_addr = m_process->ReadPointerFromMemory (object_ptr, error); - - if (error.Fail()) - return false; - - address.SetRawAddress(object_ptr); - - // First check the cache... - SymbolContext sc; - class_type_or_name = LookupInClassNameCache (isa_addr); - - if (!class_type_or_name.IsEmpty()) - { - if (class_type_or_name.GetTypeSP()) - return true; - else - return false; - } - - // We don't have the object cached, so make sure the class - // address is readable, otherwise this is not a good object: - m_process->ReadPointerFromMemory (isa_addr, error); - - if (error.Fail()) - return false; - - const char *class_name = NULL; - Address isa_address; - Target &target = m_process->GetTarget(); - target.GetSectionLoadList().ResolveLoadAddress (isa_addr, isa_address); - - if (isa_address.IsValid()) + ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor (in_value)); + if (objc_class_sp) { - // If the ISA pointer points to one of the sections in the binary, then see if we can - // get the class name from the symbols. - - SectionSP section_sp (isa_address.GetSection()); + const addr_t object_ptr = in_value.GetPointerValue(); + address.SetRawAddress(object_ptr); - if (section_sp) - { - // If this points to a section that we know about, then this is - // some static class or nothing. See if it is in the right section - // and if its name is the right form. - ConstString section_name = section_sp->GetName(); - static ConstString g_objc_class_section_name ("__objc_data"); - if (section_name == g_objc_class_section_name) - { - isa_address.CalculateSymbolContext(&sc, eSymbolContextModule | eSymbolContextSymbol); - if (sc.symbol) - { - if (sc.symbol->GetType() == eSymbolTypeObjCClass) - class_name = sc.symbol->GetName().GetCString(); - else if (sc.symbol->GetType() == eSymbolTypeObjCMetaClass) - { - // FIXME: Meta-classes can't have dynamic types... - return false; - } - } - } - } - } - - char class_buffer[1024]; - if (class_name == NULL && use_dynamic == eDynamicCanRunTarget) - { - // If the class address didn't point into the binary, or - // it points into the right section but there wasn't a symbol - // there, try to look it up by calling the class method in the target. - - ExecutionContext exe_ctx (in_value.GetExecutionContextRef()); - - Thread *thread_to_use = exe_ctx.GetThreadPtr(); - - if (thread_to_use == NULL) - thread_to_use = m_process->GetThreadList().GetSelectedThread().get(); - - if (thread_to_use == NULL) - return false; - - if (!RunFunctionToFindClassName (object_ptr, thread_to_use, class_buffer, 1024)) - return false; - - class_name = class_buffer; - - } - - if (class_name && class_name[0]) - { - class_type_or_name.SetName (class_name); - - TypeList class_types; - const bool exact_match = true; - uint32_t num_matches = target.GetImages().FindTypes (sc, - class_type_or_name.GetName(), - exact_match, - UINT32_MAX, - class_types); - if (num_matches == 1) - { - class_type_or_name.SetTypeSP (class_types.GetTypeAtIndex(0)); - return true; - } + ConstString class_name (objc_class_sp->GetClassName()); + class_type_or_name.SetName(class_name); + TypeSP type_sp (objc_class_sp->GetType()); + if (type_sp) + class_type_or_name.SetTypeSP (type_sp); else { - for (size_t i = 0; i < num_matches; i++) + type_sp = LookupInCompleteClassCache (class_name); + if (type_sp) { - TypeSP this_type(class_types.GetTypeAtIndex(i)); - if (this_type) - { - // Only consider "real" ObjC classes. For now this means avoiding - // the Type objects that are made up from the OBJC_CLASS_$_ symbols. - // we don't want to use them since they are empty and useless. - if (this_type->IsRealObjCClass()) - { - // There can only be one type with a given name, - // so we've just found duplicate definitions, and this - // one will do as well as any other. - // We don't consider something to have a dynamic type if - // it is the same as the static type. So compare against - // the value we were handed: - - clang::ASTContext *in_ast_ctx = in_value.GetClangAST (); - clang::ASTContext *this_ast_ctx = this_type->GetClangAST (); - if (in_ast_ctx != this_ast_ctx - || !ClangASTContext::AreTypesSame (in_ast_ctx, - in_value.GetClangType(), - this_type->GetClangFullType())) - { - class_type_or_name.SetTypeSP (this_type); - } - break; - } - } + objc_class_sp->SetType (type_sp); + class_type_or_name.SetTypeSP (type_sp); } } - AddToClassNameCache (isa_addr, class_type_or_name); - if (class_type_or_name.GetTypeSP()) + if (type_sp) return true; - else - return false; } - } - + } return false; } @@ -1699,7 +1578,17 @@ AppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj) Error error; ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); if (isa != LLDB_INVALID_ADDRESS) + { objc_class_sp = ObjCLanguageRuntime::GetClassDescriptor (isa); + if (isa && !objc_class_sp) + { + lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + if (log) + log->Printf("0x%llx: AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%llx", + isa_pointer, + isa); + } + } } } } diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index bcdfeaf..b494b56 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -838,15 +838,15 @@ TypeAndOrName::GetName () const } void -TypeAndOrName::SetName (ConstString &type_name_const_str) +TypeAndOrName::SetName (const ConstString &type_name) { - m_type_name = type_name_const_str; + m_type_name = type_name; } void -TypeAndOrName::SetName (const char *type_name_str) +TypeAndOrName::SetName (const char *type_name_cstr) { - m_type_name.SetCString (type_name_str); + m_type_name.SetCString (type_name_cstr); } void diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp index 4fb41c8..46a0655 100644 --- a/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -58,47 +58,6 @@ ObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t return LLDB_INVALID_ADDRESS; } -void -ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp) -{ - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - if (log) - { - log->Printf ("Caching: class 0x%llx name: %s.", class_addr, name); - } - - TypeAndOrName class_type_or_name; - - if (type_sp) - class_type_or_name.SetTypeSP (type_sp); - else if (name && *name != '\0') - class_type_or_name.SetName (name); - else - return; - m_class_name_cache.insert (std::pair (class_addr, class_type_or_name)); -} - -void -ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_type_or_name) -{ - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - if (log) - { - log->Printf ("Caching: class 0x%llx name: %s.", class_addr, class_type_or_name.GetName().AsCString()); - } - - m_class_name_cache.insert (std::pair (class_addr, class_type_or_name)); -} - -TypeAndOrName -ObjCLanguageRuntime::LookupInClassNameCache (lldb::addr_t class_addr) -{ - ClassNameMap::iterator pos, end = m_class_name_cache.end(); - pos = m_class_name_cache.find (class_addr); - if (pos != end) - return (*pos).second; - return TypeAndOrName (); -} lldb::TypeSP ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) @@ -107,72 +66,77 @@ ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) if (complete_class_iter != m_complete_class_cache.end()) { - TypeSP ret(complete_class_iter->second); + // Check the weak pointer to make sure the type hasn't been unloaded + TypeSP complete_type_sp (complete_class_iter->second.lock()); - if (!ret) - m_complete_class_cache.erase(name); + if (complete_type_sp) + return complete_type_sp; else - return TypeSP(complete_class_iter->second); + m_complete_class_cache.erase(name); } ModuleList &modules = m_process->GetTarget().GetImages(); - + SymbolContextList sc_list; + const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name, + eSymbolTypeObjCClass, + sc_list); - modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list); - - if (sc_list.GetSize() == 0) - return TypeSP(); - - SymbolContext sc; - - sc_list.GetContextAtIndex(0, sc); - - ModuleSP module_sp(sc.module_sp); - - if (!module_sp) - return TypeSP(); - - const SymbolContext null_sc; - const bool exact_match = true; - const uint32_t max_matches = UINT32_MAX; - TypeList types; - - module_sp->FindTypes (null_sc, - name, - exact_match, - max_matches, - types); - - if (types.GetSize() == 1) + if (matching_symbols) { - TypeSP candidate_type = types.GetTypeAtIndex(0); + SymbolContext sc; - if (ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType())) - { - m_complete_class_cache[name] = TypeWP(candidate_type); - return candidate_type; - } - else - { + sc_list.GetContextAtIndex(0, sc); + + ModuleSP module_sp(sc.module_sp); + + if (!module_sp) return TypeSP(); - } - } - - for (uint32_t ti = 0, te = types.GetSize(); - ti < te; - ++ti) - { - TypeSP candidate_type = types.GetTypeAtIndex(ti); - if (candidate_type->IsCompleteObjCClass() && - ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType())) + const SymbolContext null_sc; + const bool exact_match = true; + const uint32_t max_matches = UINT32_MAX; + TypeList types; + + const uint32_t num_types = module_sp->FindTypes (null_sc, + name, + exact_match, + max_matches, + types); + + if (num_types) { - m_complete_class_cache[name] = TypeWP(candidate_type); - return candidate_type; + TypeSP incomplete_type_sp; + + uint32_t i; + for (i = 0; i < num_types; ++i) + { + TypeSP type_sp (types.GetTypeAtIndex(i)); + + if (ClangASTContext::IsObjCClassType(type_sp->GetClangForwardType())) + { + if (type_sp->IsCompleteObjCClass()) + { + m_complete_class_cache[name] = type_sp; + return type_sp; + } + else if (!incomplete_type_sp) + incomplete_type_sp = type_sp; + } + } + + // We didn't find any "real" definitions, so just use any??? Why was + // this being done? Prior to this, if there was 1 match only, then it + // would always use any objc definition, else we would only accept a + // definition if it was the real thing???? Doesn't make sense. + + if (incomplete_type_sp) + { + m_complete_class_cache[name] = incomplete_type_sp; + return incomplete_type_sp; + } } } - return TypeSP(); }