diff --git a/ANNOUNCE b/ANNOUNCE index 20ead16..1ce8dab 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -21,6 +21,10 @@ Objective-C programs. Highlights of this release include: - Significant improvements in property introspection and an exhaustive test suite. +- Improved integration with libdispatch. The runtime will correctly register + work queues with the garbage collector or create autorelease pools around + block invocations. + - A new exception implementation providing better integration with foreign exceptions (e.g. C++ exceptions). The new ABI is supported by clang 3.3 when compiling with -fobjc-runtime=gnustep-1.7 (or higher). The old ABI is still diff --git a/gc_none.c b/gc_none.c index ff4331d..be90b73 100644 --- a/gc_none.c +++ b/gc_none.c @@ -21,6 +21,10 @@ static void *alloc(size_t size) return calloc(size, 1); } +void objc_registerThreadWithCollector(void) {} +void objc_unregisterThreadWithCollector(void) {} +void objc_assertRegisteredThreadWithCollector() {} + PRIVATE struct gc_ops gc_ops_none = { .allocate_class = allocate_class, diff --git a/loader.c b/loader.c index 6f4d88e..70ab229 100644 --- a/loader.c +++ b/loader.c @@ -1,6 +1,8 @@ #include #include #include "objc/runtime.h" +#include "objc/objc-auto.h" +#include "objc/objc-arc.h" #include "lock.h" #include "loader.h" #include "visibility.h" @@ -35,6 +37,12 @@ static void log_memory_stats(void) /* Number of threads that are alive. */ int __objc_runtime_threads_alive = 1; /* !T:MUTEX */ +// libdispatch hooks for registering threads +__attribute__((weak)) void (*dispatch_begin_thread_4GC)(void); +__attribute__((weak)) void (*dispatch_end_thread_4GC)(void); +__attribute__((weak)) void *(*_dispatch_begin_NSAutoReleasePool)(void); +__attribute__((weak)) void (*_dispatch_end_NSAutoReleasePool)(void *); + void __objc_exec_class(struct objc_module_abi_8 *module) { static BOOL first_run = YES; @@ -73,6 +81,18 @@ void __objc_exec_class(struct objc_module_abi_8 *module) { atexit(log_memory_stats); } + if (dispatch_begin_thread_4GC != 0) { + dispatch_begin_thread_4GC = objc_registerThreadWithCollector; + } + if (dispatch_end_thread_4GC != 0) { + dispatch_end_thread_4GC = objc_unregisterThreadWithCollector; + } + if (_dispatch_begin_NSAutoReleasePool != 0) { + _dispatch_begin_NSAutoReleasePool = objc_autoreleasePoolPush; + } + if (_dispatch_end_NSAutoReleasePool != 0) { + _dispatch_end_NSAutoReleasePool = objc_autoreleasePoolPop; + } } // The runtime mutex is held for the entire duration of a load. It does