Index: src/OFAutoreleasePool.m ================================================================== --- src/OFAutoreleasePool.m +++ src/OFAutoreleasePool.m @@ -30,28 +30,52 @@ # import "OFInitializationFailedException.h" #endif #import "autorelease.h" +#define MAX_CACHE_SIZE 0x20 + #ifdef OF_COMPILER_TLS static __thread void *first = NULL; +static __thread OFAutoreleasePool **cache = NULL; #else -static of_tlskey_t firstKey; +static of_tlskey_t firstKey, cacheKey; #endif @implementation OFAutoreleasePool #ifndef OF_COMPILER_TLS + (void)initialize { if (self != [OFAutoreleasePool class]) return; - if (!of_tlskey_new(&firstKey)) + if (!of_tlskey_new(&firstKey) || !of_tlskey_new(&cacheKey)) @throw [OFInitializationFailedException exceptionWithClass: self]; } #endif + ++ alloc +{ +#ifndef OF_COMPILER_TLS + OFAutoreleasePool **cache = of_tlskey_get(cacheKey); +#endif + + if (cache != NULL) { + unsigned i; + + for (i = 0; i < MAX_CACHE_SIZE; i++) { + if (cache[i] != NULL) { + OFAutoreleasePool *pool = cache[i]; + cache[i] = NULL; + return pool; + } + } + } + + return [super alloc]; +} + (id)addObject: (id)object { #ifndef OF_COMPILER_TLS void *first = of_tlskey_get(firstKey); @@ -121,10 +145,14 @@ [self dealloc]; } - (void)dealloc { +#ifndef OF_COMPILER_TLS + OFAutoreleasePool **cache = of_tlskey_get(cacheKey); +#endif + if (ignoreRelease) return; ignoreRelease = YES; @@ -135,10 +163,36 @@ if (of_tlskey_get(firstKey) == pool) OF_ENSURE(of_tlskey_set(firstKey, NULL)); #endif objc_autoreleasePoolPop(pool); + + if (cache == NULL) { + cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE); + +#ifndef OF_COMPILER_TLS + if (!of_tlskey_set(cacheKey, cache)) { + free(cache); + cache = NULL; + } +#endif + } + + if (cache != NULL) { + unsigned i; + + for (i = 0; i < MAX_CACHE_SIZE; i++) { + if (cache[i] == NULL) { + pool = NULL; + ignoreRelease = NO; + + cache[i] = self; + + return; + } + } + } [super dealloc]; } - retain