Initial support for running finalizers in a separate thread.

main
theraven 15 years ago
parent 0c8faf1961
commit 6d78040180

@ -117,7 +117,10 @@ libobjc_CFLAGS += -Wno-unused-function
# Uncomment this when debugging - it makes everything slow, but means that the # Uncomment this when debugging - it makes everything slow, but means that the
# debugger actually works... # debugger actually works...
# libobjc_CFLAGS += -fno-inline ifeq ($(debug), yes)
libobjc_CFLAGS += -fno-inline
libobjc_CPPFLAGS += -DGC_DEBUG
endif
libobjc_OBJCFLAGS += $(libobjc_CFLAGS) $(libobjc_CFLAGS) libobjc_OBJCFLAGS += $(libobjc_CFLAGS) $(libobjc_CFLAGS)
ifneq ($(findstring gcc, $(CC)),) ifneq ($(findstring gcc, $(CC)),)

@ -1,5 +1,6 @@
#define GNUSTEP_LIBOBJC_NO_LEGACY #define GNUSTEP_LIBOBJC_NO_LEGACY
#include "objc/runtime.h" #include "objc/runtime.h"
#include "objc/toydispatch.h"
#include "class.h" #include "class.h"
#include "ivar.h" #include "ivar.h"
#include "lock.h" #include "lock.h"
@ -12,6 +13,17 @@
#include "gc_ops.h" #include "gc_ops.h"
#define I_HIDE_POINTERS #define I_HIDE_POINTERS
/**
* Dispatch queue used to invoke finalizers.
*/
static dispatch_queue_t finalizer_queue;
/**
* Should finalizers be invoked in their own thread?
*/
static BOOL finalizeThreaded;
/* /*
* Citing boehm-gc's README.linux: * Citing boehm-gc's README.linux:
* *
@ -305,10 +317,13 @@ static id allocate_class(Class cls, size_t extra)
} }
else else
{ {
GC_descr d = descriptor_for_class(cls); obj = GC_MALLOC_EXPLICITLY_TYPED(class_getInstanceSize(cls),
obj = GC_MALLOC_EXPLICITLY_TYPED(class_getInstanceSize(cls), d); descriptor_for_class(cls));
} }
//fprintf(stderr, "Allocating %p (%s + %d). Base is %p\n", obj, cls->name, extra, GC_base(obj)); //fprintf(stderr, "Allocating %p (%s + %d). Base is %p\n", obj, cls->name, extra, GC_base(obj));
// It would be nice not to register a finaliser if the object didn't
// implement finalize or .cxx_destruct methods. Unfortunately, this is not
// possible, because a class may add a finalize method as it runs.
GC_REGISTER_FINALIZER_NO_ORDER(obj, runFinalize, 0, 0, 0); GC_REGISTER_FINALIZER_NO_ORDER(obj, runFinalize, 0, 0, 0);
return obj; return obj;
} }
@ -477,6 +492,22 @@ static void collectAndDumpStats(int signalNo)
GC_dump(); GC_dump();
} }
static void deferredFinalizer(void)
{
GC_invoke_finalizers();
}
static void runFinalizers(void)
{
if (finalizeThreaded)
{
dispatch_async_f(finalizer_queue, deferredFinalizer, NULL);
}
else
{
GC_invoke_finalizers();
}
}
static void init(void) static void init(void)
{ {
@ -496,6 +527,7 @@ static void init(void)
GC_clear_roots(); GC_clear_roots();
finalize = sel_registerName("finalize"); finalize = sel_registerName("finalize");
cxx_destruct = sel_registerName(".cxx_destruct"); cxx_destruct = sel_registerName(".cxx_destruct");
GC_finalizer_notifier = runFinalizers;
} }
BOOL objc_collecting_enabled(void) BOOL objc_collecting_enabled(void)
@ -505,7 +537,9 @@ BOOL objc_collecting_enabled(void)
void objc_startCollectorThread(void) void objc_startCollectorThread(void)
{ {
enableGC(NO); if (YES == finalizeThreaded) { return; }
finalizer_queue = dispatch_queue_create("ObjC finalizeation thread", 0);
finalizeThreaded = YES;
} }
void objc_clear_stack(unsigned long options) void objc_clear_stack(unsigned long options)

Loading…
Cancel
Save