summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/ObjCLanguageRuntime.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2013-02-13 22:56:14 +0000
committerGreg Clayton <gclayton@apple.com>2013-02-13 22:56:14 +0000
commita66c4d96f02a07f2956a3f029e216a8967463f5d (patch)
treedfab354f735b493e2148d9f0b9e3d6990a174fea /lldb/source/Target/ObjCLanguageRuntime.cpp
parent3c8220405d2dfc93da1c0c69942d07b0bd12927a (diff)
downloadbcm5719-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.cpp74
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();
OpenPOWER on IntegriCloud