diff options
author | Greg Clayton <gclayton@apple.com> | 2013-02-13 22:56:14 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-02-13 22:56:14 +0000 |
commit | a66c4d96f02a07f2956a3f029e216a8967463f5d (patch) | |
tree | dfab354f735b493e2148d9f0b9e3d6990a174fea /lldb/source/Target/ObjCLanguageRuntime.cpp | |
parent | 3c8220405d2dfc93da1c0c69942d07b0bd12927a (diff) | |
download | bcm5719-llvm-a66c4d96f02a07f2956a3f029e216a8967463f5d.tar.gz bcm5719-llvm-a66c4d96f02a07f2956a3f029e216a8967463f5d.zip |
<rdar://problem/13210494>
Parse objective C information as efficiently as possible and without taking dangerous runtime locks.
Reworked the way objective C information is parsed by:
1 - don't read all class names up front, this is about 500K of data with names
2 - add a 32 bit hash map that maps a hash of a name to the Class pointer (isa)
3 - Improved name lookups by using the new hash map
4 - split up reading the objc runtime info into dynamic and shared cache since the shared cache only needs to be read once.
5 - When reading all isa values, also get the 32 bit hash instead of the name
6 - Read names lazily now that we don't need all names up front
7 - Allow the hash maps to not be there and still have this function correctly
There is dead code in here with all of the various methods I tried. I want to check this in first to not lose any of it in case we need to revert to any of the extra code. I will promptly cleanup and commit again.
llvm-svn: 175101
Diffstat (limited to 'lldb/source/Target/ObjCLanguageRuntime.cpp')
-rw-r--r-- | lldb/source/Target/ObjCLanguageRuntime.cpp | 74 |
1 files changed, 62 insertions, 12 deletions
diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp index 078fa5dd510..4877cba50a5 100644 --- a/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -9,6 +9,7 @@ #include "clang/AST/Type.h" #include "lldb/Core/Log.h" +#include "lldb/Core/MappedHash.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Timer.h" @@ -34,12 +35,25 @@ ObjCLanguageRuntime::~ObjCLanguageRuntime() ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) : LanguageRuntime (process), m_has_new_literals_and_indexing (eLazyBoolCalculate), - m_isa_to_descriptor_cache(), - m_isa_to_descriptor_cache_stop_id (UINT32_MAX) + m_isa_to_descriptor(), + m_isa_to_descriptor_stop_id (UINT32_MAX) { } +bool +ObjCLanguageRuntime::AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name) +{ + if (isa != 0) + { + m_isa_to_descriptor[isa] = descriptor_sp; + // class_name is assumed to be valid + m_hash_to_isa_map.insert(std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa)); + return true; + } + return false; +} + void ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr) { @@ -431,13 +445,50 @@ ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value, ObjCLanguageRuntime::ObjCISA ObjCLanguageRuntime::GetISA(const ConstString &name) { - UpdateISAToDescriptorMap(); - for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache) - if (val.second && val.second->GetClassName() == name) - return val.first; + ISAToDescriptorIterator pos = GetDescriptorIterator (name); + if (pos != m_isa_to_descriptor.end()) + return pos->first; return 0; } +ObjCLanguageRuntime::ISAToDescriptorIterator +ObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name) +{ + ISAToDescriptorIterator end = m_isa_to_descriptor.end(); + + if (name) + { + UpdateISAToDescriptorMap(); + if (m_hash_to_isa_map.empty()) + { + // No name hashes were provided, we need to just linearly power through the + // names and find a match + for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin(); pos != end; ++pos) + { + if (pos->second->GetClassName() == name) + return pos; + } + } + else + { + // Name hashes were provided, so use them to efficiently lookup name to isa/descriptor + const uint32_t name_hash = MappedHash::HashStringUsingDJB (name.GetCString()); + std::pair <HashToISAIterator, HashToISAIterator> range = m_hash_to_isa_map.equal_range(name_hash); + for (HashToISAIterator range_pos = range.first; range_pos != range.second; ++range_pos) + { + ISAToDescriptorIterator pos = m_isa_to_descriptor.find (range_pos->second); + if (pos != m_isa_to_descriptor.end()) + { + if (pos->second->GetClassName() == name) + return pos; + } + } + } + } + return end; +} + + ObjCLanguageRuntime::ObjCISA ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa) { @@ -463,10 +514,9 @@ ObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) ObjCLanguageRuntime::ClassDescriptorSP ObjCLanguageRuntime::GetClassDescriptor (const ConstString &class_name) { - UpdateISAToDescriptorMap(); - for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache) - if (val.second && val.second->GetClassName() == class_name) - return val.second; + ISAToDescriptorIterator pos = GetDescriptorIterator (class_name); + if (pos != m_isa_to_descriptor.end()) + return pos->second; return ClassDescriptorSP(); } @@ -521,8 +571,8 @@ ObjCLanguageRuntime::GetClassDescriptor (ObjCISA isa) if (isa) { UpdateISAToDescriptorMap(); - ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor_cache.find(isa); - if (pos != m_isa_to_descriptor_cache.end()) + ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa); + if (pos != m_isa_to_descriptor.end()) return pos->second; } return ClassDescriptorSP(); |