aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h')
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h54
1 files changed, 45 insertions, 9 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index 15fce04ea465..9431b4250240 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -22,6 +22,7 @@
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
class CommandObjectObjC_ClassTable_Dump;
@@ -242,11 +243,19 @@ public:
virtual bool HasReadObjCLibrary() = 0;
+ // These two methods actually use different caches. The only time we'll
+ // cache a sel_str is if we found a "selector specific stub" for the selector
+ // and conversely we only add to the SEL cache if we saw a regular dispatch.
lldb::addr_t LookupInMethodCache(lldb::addr_t class_addr, lldb::addr_t sel);
+ lldb::addr_t LookupInMethodCache(lldb::addr_t class_addr,
+ llvm::StringRef sel_str);
void AddToMethodCache(lldb::addr_t class_addr, lldb::addr_t sel,
lldb::addr_t impl_addr);
+ void AddToMethodCache(lldb::addr_t class_addr, llvm::StringRef sel_str,
+ lldb::addr_t impl_addr);
+
TypeAndOrName LookupInClassNameCache(lldb::addr_t class_addr);
void AddToClassNameCache(lldb::addr_t class_addr, const char *name,
@@ -343,20 +352,22 @@ protected:
}
private:
- // We keep a map of <Class,Selector>->Implementation so we don't have to call
- // the resolver function over and over.
+ // We keep two maps of <Class,Selector>->Implementation so we don't have
+ // to call the resolver function over and over.
+ // The first comes from regular obj_msgSend type dispatch, and maps the
+ // class + uniqued SEL value to an implementation.
+ // The second comes from the "selector-specific stubs", which are always
+ // of the form _objc_msgSend$SelectorName, so we don't know the uniqued
+ // selector, only the string name.
// FIXME: We need to watch for the loading of Protocols, and flush the cache
// for any
// class that we see so changed.
struct ClassAndSel {
- ClassAndSel() {
- sel_addr = LLDB_INVALID_ADDRESS;
- class_addr = LLDB_INVALID_ADDRESS;
- }
+ ClassAndSel() = default;
- ClassAndSel(lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr)
+ ClassAndSel(lldb::addr_t in_class_addr, lldb::addr_t in_sel_addr)
: class_addr(in_class_addr), sel_addr(in_sel_addr) {}
bool operator==(const ClassAndSel &rhs) {
@@ -379,11 +390,35 @@ private:
}
}
- lldb::addr_t class_addr;
- lldb::addr_t sel_addr;
+ lldb::addr_t class_addr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t sel_addr = LLDB_INVALID_ADDRESS;
+ };
+
+ struct ClassAndSelStr {
+ ClassAndSelStr() = default;
+
+ ClassAndSelStr(lldb::addr_t in_class_addr, llvm::StringRef in_sel_name)
+ : class_addr(in_class_addr), sel_name(in_sel_name) {}
+
+ bool operator==(const ClassAndSelStr &rhs) {
+ return class_addr == rhs.class_addr && sel_name == rhs.sel_name;
+ }
+
+ bool operator<(const ClassAndSelStr &rhs) const {
+ if (class_addr < rhs.class_addr)
+ return true;
+ else if (class_addr > rhs.class_addr)
+ return false;
+ else
+ return ConstString::Compare(sel_name, rhs.sel_name);
+ }
+
+ lldb::addr_t class_addr = LLDB_INVALID_ADDRESS;
+ ConstString sel_name;
};
typedef std::map<ClassAndSel, lldb::addr_t> MsgImplMap;
+ typedef std::map<ClassAndSelStr, lldb::addr_t> MsgImplStrMap;
typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
@@ -391,6 +426,7 @@ private:
typedef ThreadSafeDenseMap<void *, uint64_t> TypeSizeCache;
MsgImplMap m_impl_cache;
+ MsgImplStrMap m_impl_str_cache;
LazyBool m_has_new_literals_and_indexing;
ISAToDescriptorMap m_isa_to_descriptor;
HashToISAMap m_hash_to_isa_map;