Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -71,11 +71,13 @@ enum of_thread_running { OF_THREAD_NOT_RUNNING, OF_THREAD_RUNNING, OF_THREAD_WAITING_FOR_JOIN } _running; +# ifndef OF_OBJFW_RUNTIME void *_pool; +# endif # ifdef OF_HAVE_BLOCKS of_thread_block_t _Nullable _threadBlock; # endif jmp_buf _exitEnv; id _returnValue; Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -105,11 +105,13 @@ if (!of_tlskey_set(threadSelfKey, thread)) @throw [OFInitializationFailedException exceptionWithClass: thread.class]; +#ifndef OF_OBJFW_RUNTIME thread->_pool = objc_autoreleasePoolPush(); +#endif name = thread.name; if (name != nil) of_thread_set_name( [name cStringWithEncoding: [OFLocale encoding]]); @@ -136,11 +138,15 @@ thread->_returnValue = [[thread main] retain]; } [thread handleTermination]; +#ifdef OF_OBJFW_RUNTIME + objc_autoreleasePoolPop((void *)(uintptr_t)-1); +#else objc_autoreleasePoolPop(thread->_pool); +#endif #if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS) if (thread.supportsSockets) of_socket_deinit(); #endif Index: src/runtime/autorelease.m ================================================================== --- src/runtime/autorelease.m +++ src/runtime/autorelease.m @@ -27,109 +27,107 @@ # import "tlskey.h" #endif #if defined(OF_HAVE_COMPILER_TLS) static thread_local id *objects = NULL; -static thread_local id *top = NULL; -static thread_local size_t size = 0; +static thread_local uintptr_t count = 0; +static thread_local uintptr_t size = 0; #elif defined(OF_HAVE_THREADS) -static of_tlskey_t objectsKey, topKey, sizeKey; +static of_tlskey_t objectsKey, countKey, sizeKey; #else static id *objects = NULL; -static id *top = NULL; -static size_t size = 0; +static uintptr_t count = 0; +static uintptr_t size = 0; #endif #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OF_CONSTRUCTOR() { OF_ENSURE(of_tlskey_new(&objectsKey)); - OF_ENSURE(of_tlskey_new(&topKey)); + OF_ENSURE(of_tlskey_new(&countKey)); OF_ENSURE(of_tlskey_new(&sizeKey)); } #endif void * objc_autoreleasePoolPush() { #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - id *top = of_tlskey_get(topKey); - id *objects = of_tlskey_get(objectsKey); + uintptr_t count = (uintptr_t)of_tlskey_get(countKey); #endif - ptrdiff_t offset = top - objects; - - return (void *)offset; + return (void *)count; } void -objc_autoreleasePoolPop(void *offset) -{ -#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - id *top = of_tlskey_get(topKey); - id *objects = of_tlskey_get(objectsKey); -#endif - id *pool = objects + (ptrdiff_t)offset; - id *iter; - - for (iter = pool; iter < top; iter++) - [*iter release]; - - top = pool; - - if (top == objects) { - free(objects); - - objects = NULL; - top = NULL; - } - -#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - OF_ENSURE(of_tlskey_set(topKey, top)); - OF_ENSURE(of_tlskey_set(objectsKey, objects)); +objc_autoreleasePoolPop(void *pool) +{ +#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + id *objects = of_tlskey_get(objectsKey); + uintptr_t count = (uintptr_t)of_tlskey_get(countKey); +#endif + uintptr_t idx = (uintptr_t)pool; + bool freeMem = false; + + if (idx == (uintptr_t)-1) { + idx++; + freeMem = true; + } + + for (uintptr_t i = idx; i < count; i++) { + [objects[i] release]; + +#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + objects = of_tlskey_get(objectsKey); + count = (uintptr_t)of_tlskey_get(countKey); +#endif + } + + count = idx; + + if (freeMem) { + free(objects); + objects = NULL; +#if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS) + size = 0; +#else + OF_ENSURE(of_tlskey_set(objectsKey, objects)); + OF_ENSURE(of_tlskey_set(sizeKey, (void *)0)); +#endif + } + +#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + OF_ENSURE(of_tlskey_set(countKey, (void *)count)); #endif } id _objc_rootAutorelease(id object) { #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - id *top = of_tlskey_get(topKey); - id *objects = of_tlskey_get(objectsKey); - size_t size = (size_t)(uintptr_t)of_tlskey_get(sizeKey); -#endif - - if (objects == NULL) { - size = 16 * sizeof(id); - - OF_ENSURE((objects = malloc(size)) != NULL); - - top = objects; - -#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - OF_ENSURE(of_tlskey_set(objectsKey, objects)); - OF_ENSURE(of_tlskey_set(sizeKey, (void *)(uintptr_t)size)); -#endif - } - - if ((uintptr_t)top >= (uintptr_t)objects + size) { - ptrdiff_t diff = top - objects; - - size *= 2; - OF_ENSURE((objects = realloc(objects, size)) != NULL); - -#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - OF_ENSURE(of_tlskey_set(objectsKey, objects)); - OF_ENSURE(of_tlskey_set(sizeKey, (void *)(uintptr_t)size)); -#endif - - top = objects + diff; - } - - *top = object; - top++; - -#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) - OF_ENSURE(of_tlskey_set(topKey, top)); + id *objects = of_tlskey_get(objectsKey); + uintptr_t count = (uintptr_t)of_tlskey_get(countKey); + uintptr_t size = (uintptr_t)of_tlskey_get(sizeKey); +#endif + + if (count >= size) { + if (size == 0) + size = 16; + else + size *= 2; + + OF_ENSURE((objects = + realloc(objects, size * sizeof(id))) != NULL); + +#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + OF_ENSURE(of_tlskey_set(objectsKey, objects)); + OF_ENSURE(of_tlskey_set(sizeKey, (void *)size)); +#endif + } + + objects[count++] = object; + +#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + OF_ENSURE(of_tlskey_set(countKey, (void *)count)); #endif return object; }