#if __OBJC2__
#include "objc-private.h"
-#include "objc-cache.h"
-
-#if SUPPORT_PREOPT
-static const objc_selopt_t *builtins = NULL;
-#endif
-
-
-static size_t SelrefCount = 0;
-
-static NXMapTable *namedSelectors;
+#include "DenseMapExtras.h"
+static objc::ExplicitInitDenseSet<const char *> namedSelectors;
static SEL search_builtins(const char *key);
**********************************************************************/
void sel_init(size_t selrefCount)
{
- // save this value for later
- SelrefCount = selrefCount;
-
#if SUPPORT_PREOPT
- builtins = preoptimizedSelectors();
-
- if (PrintPreopt && builtins) {
- uint32_t occupied = builtins->occupied;
- uint32_t capacity = builtins->capacity;
-
- _objc_inform("PREOPTIMIZATION: using selopt at %p", builtins);
- _objc_inform("PREOPTIMIZATION: %u selectors", occupied);
- _objc_inform("PREOPTIMIZATION: %u/%u (%u%%) hash table occupancy",
- occupied, capacity,
- (unsigned)(occupied/(double)capacity*100));
- }
+ if (PrintPreopt) {
+ _objc_inform("PREOPTIMIZATION: using dyld selector opt");
+ }
#endif
- // Register selectors used by libobjc
+ namedSelectors.init((unsigned)selrefCount);
-#define s(x) SEL_##x = sel_registerNameNoLock(#x, NO)
-#define t(x,y) SEL_##y = sel_registerNameNoLock(#x, NO)
+ // Register selectors used by libobjc
mutex_locker_t lock(selLock);
- s(load);
- s(initialize);
- t(resolveInstanceMethod:, resolveInstanceMethod);
- t(resolveClassMethod:, resolveClassMethod);
- t(.cxx_construct, cxx_construct);
- t(.cxx_destruct, cxx_destruct);
- s(retain);
- s(release);
- s(autorelease);
- s(retainCount);
- s(alloc);
- t(allocWithZone:, allocWithZone);
- s(dealloc);
- s(copy);
- s(new);
- t(forwardInvocation:, forwardInvocation);
- t(_tryRetain, tryRetain);
- t(_isDeallocating, isDeallocating);
- s(retainWeakReference);
- s(allowsWeakReference);
-
-#undef s
-#undef t
+ SEL_cxx_construct = sel_registerNameNoLock(".cxx_construct", NO);
+ SEL_cxx_destruct = sel_registerNameNoLock(".cxx_destruct", NO);
}
}
+unsigned long sel_hash(SEL sel)
+{
+ unsigned long selAddr = (unsigned long)sel;
+#if CONFIG_USE_PREOPT_CACHES
+ selAddr ^= (selAddr >> 7);
+#endif
+ return selAddr;
+}
+
+
BOOL sel_isMapped(SEL sel)
{
if (!sel) return NO;
if (sel == search_builtins(name)) return YES;
mutex_locker_t lock(selLock);
- if (namedSelectors) {
- return (sel == (SEL)NXMapGet(namedSelectors, name));
- }
- return false;
+ auto it = namedSelectors.get().find(name);
+ return it != namedSelectors.get().end() && (SEL)*it == sel;
}
static SEL search_builtins(const char *name)
{
#if SUPPORT_PREOPT
- if (builtins) return (SEL)builtins->get(name);
+ if (SEL result = (SEL)_dyld_get_objc_selector(name))
+ return result;
#endif
return nil;
}
if (result) return result;
conditional_mutex_locker_t lock(selLock, shouldLock);
- if (namedSelectors) {
- result = (SEL)NXMapGet(namedSelectors, name);
- }
- if (result) return result;
-
- // No match. Insert.
-
- if (!namedSelectors) {
- namedSelectors = NXCreateMapTable(NXStrValueMapPrototype,
- (unsigned)SelrefCount);
- }
- if (!result) {
- result = sel_alloc(name, copy);
- // fixme choose a better container (hash not map for starters)
- NXMapInsert(namedSelectors, sel_getName(result), result);
- }
-
- return result;
+ auto it = namedSelectors.get().insert(name);
+ if (it.second) {
+ // No match. Insert.
+ *it.first = (const char *)sel_alloc(name, copy);
+ }
+ return (SEL)*it.first;
}