summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/ObjCLanguageRuntime.cpp
diff options
context:
space:
mode:
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