Last active
August 29, 2015 14:05
-
-
Save rpplusplus/f7cbf551cbefc7f9b4dc to your computer and use it in GitHub Desktop.
CFRuntime.__CFDoExternRefOperation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// we disguise pointers so that programs like 'leaks' forget about these references | |
#define DISGUISE(O) (~(uintptr_t)(O)) | |
#if DEPLOYMENT_TARGET_MACOSX | |
#define NUM_EXTERN_TABLES 8 | |
#define EXTERN_TABLE_IDX(O) (((uintptr_t)(O) >> 8) & 0x7) | |
#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX | |
#define NUM_EXTERN_TABLES 1 | |
#define EXTERN_TABLE_IDX(O) 0 | |
#else | |
#error | |
#endif | |
static struct { | |
CFSpinLock_t lock; | |
CFBasicHashRef table; | |
uint8_t padding[64 - sizeof(CFBasicHashRef) - sizeof(CFSpinLock_t)]; | |
} __NSRetainCounters[NUM_EXTERN_TABLES]; | |
CF_EXPORT uintptr_t __CFDoExternRefOperation(uintptr_t op, id obj) { | |
if (nil == obj) HALT; | |
uintptr_t idx = EXTERN_TABLE_IDX(obj); | |
uintptr_t disguised = DISGUISE(obj); | |
CFSpinLock_t *lock = &__NSRetainCounters[idx].lock; | |
CFBasicHashRef table = __NSRetainCounters[idx].table; | |
uintptr_t count; | |
switch (op) { | |
case 300: // increment | |
case 350: // increment, no event | |
__CFSpinLock(lock); | |
CFBasicHashAddValue(table, disguised, disguised); | |
__CFSpinUnlock(lock); | |
if (__CFOASafe && op != 350) __CFRecordAllocationEvent(__kCFObjectRetainedEvent, obj, 0, 0, NULL); | |
return (uintptr_t)obj; | |
case 400: // decrement | |
if (__CFOASafe) __CFRecordAllocationEvent(__kCFObjectReleasedEvent, obj, 0, 0, NULL); | |
case 450: // decrement, no event | |
__CFSpinLock(lock); | |
count = (uintptr_t)CFBasicHashRemoveValue(table, disguised); | |
__CFSpinUnlock(lock); | |
return 0 == count; | |
case 500: | |
__CFSpinLock(lock); | |
count = (uintptr_t)CFBasicHashGetCountOfKey(table, disguised); | |
__CFSpinUnlock(lock); | |
return count; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment