More garbage collection updates/fixes.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27590 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-01-13 15:57:38 +00:00
parent 67c379bc7a
commit 940de12cab
10 changed files with 249 additions and 201 deletions

View file

@ -1,3 +1,12 @@
2009-01-13 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSGarbageCollector.m: Mark the two unimplemented methods.
* Source/NSNotificationCenter.m: Automatically remove observers if
they are collected by the GC system.
* Source/NSThread.m: Make the GC system aware of each thread if poss.
* Source/GSArray.m: Don't use inline array class with GC.
* configure.ac: Add check for GC_register_my_thread
2009-01-12 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GNUmakefile:

View file

@ -12,159 +12,6 @@
/* Define if constructors are automatically loaded */
#undef CON_AUTOLOAD
/* Built in default value for GNUstep config file */
#undef GNUSTEP_TARGET_CONFIG_FILE
/* Built in default value for GNUstep local apps */
#undef GNUSTEP_TARGET_LOCAL_ADMIN_APPS
/* Built in default value for GNUstep local tools */
#undef GNUSTEP_TARGET_LOCAL_ADMIN_TOOLS
/* Built in default value for GNUstep local apps */
#undef GNUSTEP_TARGET_LOCAL_APPS
/* Built in default value for GNUstep local documentation */
#undef GNUSTEP_TARGET_LOCAL_DOC
/* Built in default value for GNUstep local info documentation */
#undef GNUSTEP_TARGET_LOCAL_DOC_INFO
/* Built in default value for GNUstep local manpages documentation */
#undef GNUSTEP_TARGET_LOCAL_DOC_MAN
/* Built in default value for GNUstep local headers */
#undef GNUSTEP_TARGET_LOCAL_HEADERS
/* Built in default value for GNUstep local libraries */
#undef GNUSTEP_TARGET_LOCAL_LIBRARIES
/* Built in default value for GNUstep local library */
#undef GNUSTEP_TARGET_LOCAL_LIBRARY
/* Built in default value for GNUstep local tools */
#undef GNUSTEP_TARGET_LOCAL_TOOLS
/* Built in default value for GNUstep Local Users directory */
#undef GNUSTEP_TARGET_LOCAL_USERS_DIR
/* Built in default value for GNUstep local web apps */
#undef GNUSTEP_TARGET_LOCAL_WEB_APPS
/* Built in default value for GNUstep Makefiles */
#undef GNUSTEP_TARGET_MAKEFILES
/* Built in default value for GNUstep network apps */
#undef GNUSTEP_TARGET_NETWORK_ADMIN_APPS
/* Built in default value for GNUstep system tools */
#undef GNUSTEP_TARGET_NETWORK_ADMIN_TOOLS
/* Built in default value for GNUstep network apps */
#undef GNUSTEP_TARGET_NETWORK_APPS
/* Built in default value for GNUstep network documentation */
#undef GNUSTEP_TARGET_NETWORK_DOC
/* Built in default value for GNUstep network info documentation */
#undef GNUSTEP_TARGET_NETWORK_DOC_INFO
/* Built in default value for GNUstep network manpages documentation */
#undef GNUSTEP_TARGET_NETWORK_DOC_MAN
/* Built in default value for GNUstep network headers */
#undef GNUSTEP_TARGET_NETWORK_HEADERS
/* Built in default value for GNUstep network libraries */
#undef GNUSTEP_TARGET_NETWORK_LIBRARIES
/* Built in default value for GNUstep network library */
#undef GNUSTEP_TARGET_NETWORK_LIBRARY
/* Built in default value for GNUstep network tools */
#undef GNUSTEP_TARGET_NETWORK_TOOLS
/* Built in default value for GNUstep Network Users directory */
#undef GNUSTEP_TARGET_NETWORK_USERS_DIR
/* Built in default value for GNUstep network web apps */
#undef GNUSTEP_TARGET_NETWORK_WEB_APPS
/* Built in default value for GNUstep system apps */
#undef GNUSTEP_TARGET_SYSTEM_ADMIN_APPS
/* Built in default value for GNUstep system tools */
#undef GNUSTEP_TARGET_SYSTEM_ADMIN_TOOLS
/* Built in default value for GNUstep system apps */
#undef GNUSTEP_TARGET_SYSTEM_APPS
/* Built in default value for GNUstep system documentation */
#undef GNUSTEP_TARGET_SYSTEM_DOC
/* Built in default value for GNUstep system info documentation */
#undef GNUSTEP_TARGET_SYSTEM_DOC_INFO
/* Built in default value for GNUstep system manpages documentation */
#undef GNUSTEP_TARGET_SYSTEM_DOC_MAN
/* Built in default value for GNUstep system headers */
#undef GNUSTEP_TARGET_SYSTEM_HEADERS
/* Built in default value for GNUstep system libraries */
#undef GNUSTEP_TARGET_SYSTEM_LIBRARIES
/* Built in default value for GNUstep system library */
#undef GNUSTEP_TARGET_SYSTEM_LIBRARY
/* Built in default value for GNUstep system tools */
#undef GNUSTEP_TARGET_SYSTEM_TOOLS
/* Built in default value for GNUstep System Users directory */
#undef GNUSTEP_TARGET_SYSTEM_USERS_DIR
/* Built in default value for GNUstep web apps */
#undef GNUSTEP_TARGET_SYSTEM_WEB_APPS
/* Built in default value for GNUstep user config file */
#undef GNUSTEP_TARGET_USER_CONFIG_FILE
/* Built in default value for GNUstep user defaults directory */
#undef GNUSTEP_TARGET_USER_DEFAULTS_DIR
/* Built in default value for GNUstep user_dir admin apps */
#undef GNUSTEP_TARGET_USER_DIR_ADMIN_APPS
/* Built in default value for GNUstep user_dir tools */
#undef GNUSTEP_TARGET_USER_DIR_ADMIN_TOOLS
/* Built in default value for GNUstep user_dir apps */
#undef GNUSTEP_TARGET_USER_DIR_APPS
/* Built in default value for GNUstep user_dir documentation */
#undef GNUSTEP_TARGET_USER_DIR_DOC
/* Built in default value for GNUstep user_dir info documentation */
#undef GNUSTEP_TARGET_USER_DIR_DOC_INFO
/* Built in default value for GNUstep user_dir manpages documentation */
#undef GNUSTEP_TARGET_USER_DIR_DOC_MAN
/* Built in default value for GNUstep user_dir headers */
#undef GNUSTEP_TARGET_USER_DIR_HEADERS
/* Built in default value for GNUstep user_dir libraries */
#undef GNUSTEP_TARGET_USER_DIR_LIBRARIES
/* Built in default value for GNUstep user_dir library */
#undef GNUSTEP_TARGET_USER_DIR_LIBRARY
/* Built in default value for GNUstep user_dir tools */
#undef GNUSTEP_TARGET_USER_DIR_TOOLS
/* Built in default value for GNUstep user_dir web apps */
#undef GNUSTEP_TARGET_USER_DIR_WEB_APPS
/* Define if this constant is defined */
#undef HANDLE_LLONG_MAX
@ -199,6 +46,12 @@
/* Define if libobjc has the __objc_msg_forward2 function */
#undef HAVE_FORWARD2
/* Define to 1 if you have the <gc.h> header file. */
#undef HAVE_GC_H
/* Define if GC_register_my_thread function is available */
#undef HAVE_GC_REGISTER_MY_THREAD
/* Define to 1 if you have the `getcwd' function. */
#undef HAVE_GETCWD
@ -600,9 +453,6 @@
/* Define if your system needs to have short/int word aligned */
#undef NEED_WORD_ALIGNMENT
/* Disable GNUSTEP_CONFIG_FILE environment variable */
#undef OPTION_NO_ENVIRONMENT
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

View file

@ -43,7 +43,11 @@
static SEL eqSel;
static SEL oaiSel;
#if GS_WITH_GC
static Class GSArrayClass;
#else
static Class GSInlineArrayClass;
#endif
@class GSArray;
@ -75,7 +79,8 @@ static Class GSInlineArrayClass;
[NSNumber numberWithUnsignedInt: _count], @"Count",
self, @"Array", nil, nil];
reason = [NSString stringWithFormat: @"Index %d is out of range %d (in '%@')",
reason = [NSString stringWithFormat:
@"Index %d is out of range %d (in '%@')",
index, _count, NSStringFromSelector(sel)];
exception = [NSException exceptionWithName: NSRangeException
@ -91,7 +96,11 @@ static Class GSInlineArrayClass;
[self setVersion: 1];
eqSel = @selector(isEqual:);
oaiSel = @selector(objectAtIndex:);
#if GS_WITH_GC
GSArrayClass = [GSArray class];
#else
GSInlineArrayClass = [GSInlineArray class];
#endif
}
}
@ -349,19 +358,29 @@ static Class GSInlineArrayClass;
}
@end
#if !GS_WITH_GC
/* This class stores objects inline in data beyond the end of the instance.
* However, when GC is enabled the object data is typed, and all data after
* the end of the class is ignored by the garbage collector (which would
* mean that objects in the array could be collected).
* We therefore do not provide the class ewhan GC is being used.
*/
@interface GSInlineArray : GSArray
{
}
@end
@implementation GSInlineArray
- (void) dealloc
{
if (_contents_array)
{
#if !GS_WITH_GC
unsigned i;
for (i = 0; i < _count; i++)
{
[_contents_array[i] release];
}
#endif
}
NSDeallocateObject(self);
GSNOSUPERDEALLOC;
@ -392,6 +411,7 @@ static Class GSInlineArrayClass;
return self;
}
@end
#endif
@implementation GSMutableArray
@ -437,7 +457,11 @@ static Class GSInlineArrayClass;
{
NSArray *copy;
#if GS_WITH_GC
copy = (id)NSAllocateObject(GSArrayClass, 0, zone);
#else
copy = (id)NSAllocateObject(GSInlineArrayClass, sizeof(id)*_count, zone);
#endif
return [copy initWithObjects: _contents_array count: _count];
}
@ -1002,7 +1026,11 @@ static Class GSInlineArrayClass;
+ (void) initialize
{
#if GS_WITH_GC
GSArrayClass = [GSArray class];
#else
GSInlineArrayClass = [GSInlineArray class];
#endif
}
- (id) autorelease
@ -1039,13 +1067,21 @@ static Class GSInlineArrayClass;
}
else
{
GSInlineArray *a;
unsigned c;
#if GS_WITH_GC
GSArray *a;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &c];
a = (id)NSAllocateObject(GSArrayClass, 0, GSObjCZone(self));
a->_contents_array = NSZoneMalloc(GSObjCZone(self), sizeof(id)*c);
#else
GSInlineArray *a;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &c];
a = (id)NSAllocateObject(GSInlineArrayClass,
sizeof(id)*c, GSObjCZone(self));
a->_contents_array = (id*)&a[1];
#endif
if (c > 0)
{
[aCoder decodeArrayOfObjCType: @encode(id)
@ -1059,8 +1095,12 @@ static Class GSInlineArrayClass;
- (id) initWithObjects: (id*)objects count: (unsigned)count
{
#if GS_WITH_GC
self = (id)NSAllocateObject(GSArrayClass, 0, GSObjCZone(self));
#else
self = (id)NSAllocateObject(GSInlineArrayClass, sizeof(id)*count,
GSObjCZone(self));
#endif
return [self initWithObjects: objects count: count];
}

View file

@ -73,11 +73,6 @@
}
@end
@interface GSInlineArray : GSArray
{
}
@end
@interface GSPlaceholderArray : NSArray
{
}

View file

@ -84,7 +84,6 @@ extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
static Class NSArrayClass;
static Class GSArrayClass;
static Class GSInlineArrayClass;
static Class NSMutableArrayClass;
static Class GSMutableArrayClass;
static Class GSPlaceholderArrayClass;
@ -125,7 +124,6 @@ static SEL rlSel;
NSArrayClass = [NSArray class];
NSMutableArrayClass = [NSMutableArray class];
GSArrayClass = [GSArray class];
GSInlineArrayClass = [GSInlineArray class];
GSMutableArrayClass = [GSMutableArray class];
GSPlaceholderArrayClass = [GSPlaceholderArray class];

View file

@ -82,6 +82,7 @@ static unsigned disabled = 0;
- (void) disableCollectorForPointer: (void *)ptr
{
// FIXME
[self notImplemented: _cmd];
return;
}
@ -102,6 +103,7 @@ static unsigned disabled = 0;
- (void) enableCollectorForPointer: (void *)ptr
{
// FIXME
[self notImplemented: _cmd];
return;
}

View file

@ -30,13 +30,22 @@
*/
#include "config.h"
#include "Foundation/NSNotification.h"
#include "Foundation/NSException.h"
#include "Foundation/NSLock.h"
#include "Foundation/NSThread.h"
#include "Foundation/NSDebug.h"
#include "GNUstepBase/GSLock.h"
#import "Foundation/NSNotification.h"
#import "Foundation/NSException.h"
#import "Foundation/NSLock.h"
#import "Foundation/NSThread.h"
#import "Foundation/NSDebug.h"
#import "GNUstepBase/GSLock.h"
/* purgeCollected() returns a list of observations with any observations for
* a collected observer removed.
*/
#if GS_WITH_GC
#include <gc.h>
#define purgeCollected(X) (X = listPurge(X, nil))
#else
#define purgeCollected(X) (X)
#endif
/**
* Concrete class implementing NSNotification.
@ -425,6 +434,9 @@ static void obsFree(Observation *o)
{
NCTable *t = o->link;
#if GS_WITH_GC
GC_unregister_disappearing_link((GC_PTR*)&o->observer);
#endif
o->link = (NCTable*)t->freeList;
t->freeList = o;
}
@ -533,7 +545,7 @@ purgeMapNode(GSIMapTable map, GSIMapNode node, id observer)
* I know of.
*
* We also use this trick to differentiate between map table keys that
* should be treated as objects (notification names) and thise that
* should be treated as objects (notification names) and those that
* should be treated as pointers (notification objects)
*/
#define CHEATGC(X) (id)(((uintptr_t)X) | 1)
@ -641,7 +653,10 @@ static NSNotificationCenter *default_center = nil;
*
* <p>The notification center does not retain observer or object. Therefore,
* you should always send removeObserver: or removeObserver:name:object: to
* the notification center before releasing these objects.</p>
* the notification center before releasing these objects.<br />
* As a convenience, when built with garbage collection, you do not need to
* remove any garbage collected observer as the system will do it implicitly.
* </p>
*
* <p>NB. For MacOS-X compatibility, adding an observer multiple times will
* register it to receive multiple copies of any matching notification, however
@ -687,8 +702,23 @@ static NSNotificationCenter *default_center = nil;
o->retained = 0;
o->next = 0;
#if GS_WITH_GC
/* Ensure that if the observer is garbage collected, we clear the
* oservation so that we don't end up sending notifications to the
* deallocated object.
* The observer must be a real GC-allocated object or this mechanism
* can't be used.
*/
if (GC_base(observer) != 0)
{
GC_general_register_disappearing_link((GC_PTR*)&o->observer, observer);
}
#endif
if (object != nil)
object = CHEATGC(object);
{
object = CHEATGC(object);
}
/*
* Record the Observation in one of the linked lists.
@ -943,6 +973,7 @@ static NSNotificationCenter *default_center = nil;
*/
- (void) _postAndRelease: (NSNotification*)notification
{
IF_NO_GC(GSGarbageCollector *collector = [NSGarbageCollector defaultCollector])
Observation *o;
unsigned count;
NSString *name = [notification name];
@ -952,6 +983,9 @@ static NSNotificationCenter *default_center = nil;
GSIArrayItem i[64];
GSIArray_t b;
GSIArray a = &b;
#if GS_WITH_GG
GSGarbageCollector *collector = [NSGarbageCollector defaultCollector];
#endif
if (name == nil)
{
@ -971,14 +1005,21 @@ static NSNotificationCenter *default_center = nil;
GSIArrayInitWithZoneAndStaticCapacity(a, NSDefaultMallocZone(), 64, i);
/*
* Lock the table of observers while we traverse it.
* Lock the table of observations while we traverse it.
*
* The table of observations contains weak pointers which are zeroed when
* the observers get garbage collected. So to avoid consistency problems
* we disable gc while we copy all the observations we are interested in.
*/
lockNCTable(TABLE);
#if GS_WITH_GG
[collector disable];
#endif
/*
* Find all the observers that specified neither NAME nor OBJECT.
*/
for (o = WILDCARD; o != ENDOBS; o = o->next)
for (o = purgeCollected(WILDCARD); o != ENDOBS; o = o->next)
{
GSIArrayAddItem(a, (GSIArrayItem)o);
}
@ -991,7 +1032,7 @@ static NSNotificationCenter *default_center = nil;
n = GSIMapNodeForSimpleKey(NAMELESS, (GSIMapKey)object);
if (n != 0)
{
o = n->value.ext;
o = purgeCollected(n->value.ext);
while (o != ENDOBS)
{
GSIArrayAddItem(a, (GSIArrayItem)o);
@ -1023,7 +1064,7 @@ static NSNotificationCenter *default_center = nil;
n = GSIMapNodeForSimpleKey(m, (GSIMapKey)object);
if (n != 0)
{
o = n->value.ext;
o = purgeCollected(n->value.ext);
while (o != ENDOBS)
{
GSIArrayAddItem(a, (GSIArrayItem)o);
@ -1039,7 +1080,7 @@ static NSNotificationCenter *default_center = nil;
n = GSIMapNodeForSimpleKey(m, (GSIMapKey)nil);
if (n != 0)
{
o = n->value.ext;
o = purgeCollected(n->value.ext);
while (o != ENDOBS)
{
GSIArrayAddItem(a, (GSIArrayItem)o);
@ -1047,13 +1088,17 @@ static NSNotificationCenter *default_center = nil;
}
}
}
}
}
/*
* Finished with the table ... we can unlock it.
* Finished with the table ... we can unlock it and re-enable garbage
* collection, safe in the knowledge that the observers we will be
* notifying won't get collected prematurely.
*/
#if GS_WITH_GG
[collector enable];
#endif
unlockNCTable(TABLE);
/*

View file

@ -80,6 +80,10 @@
#include "GSPrivate.h"
#include "GSRunLoopCtxt.h"
#if GS_WITH_GC
#include <gc.h>
#endif
@interface NSAutoreleasePool (NSThread)
+ (void) _endThread: (NSThread*)thread;
@end
@ -506,6 +510,9 @@ gnustep_base_thread_callback(void)
objc_thread_set_data (NULL);
#if GS_WITH_GC && defined(HAVE_GC_REGISTER_MY_THREAD)
GC_unregister_my_thread();
#endif
/*
* Tell the runtime to exit the thread
*/
@ -734,6 +741,9 @@ gnustep_base_thread_callback(void)
NSStringFromSelector(_cmd)];
}
#if GS_WITH_GC && defined(HAVE_GC_REGISTER_MY_THREAD)
GC_register_my_thread();
#endif
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
if (_stackSize > 0)
{

119
configure vendored
View file

@ -3468,11 +3468,9 @@ fi
done
if test "$gc_ok" = no; then
{ { echo "$as_me:$LINENO: error: Garbage collection was required, but the gc.h header" >&5
echo "$as_me: error: Garbage collection was required, but the gc.h header" >&2;}
{ { echo "$as_me:$LINENO: error: Garbage collection was required, but the gc.h header couldn't be found." >&5
echo "$as_me: error: Garbage collection was required, but the gc.h header couldn't be found." >&2;}
{ (exit 1); exit 1; }; }
{ echo "$as_me:$LINENO: couldn't be found." >&5
echo "$as_me: couldn't be found." >&6;}
fi
saved_LIBS="$LIBS"
LIBS+=" -lgc"
@ -3573,11 +3571,110 @@ else
fi
if test "$gc_ok" = no; then
{ { echo "$as_me:$LINENO: error: Garbage collection was required, but the gc library" >&5
echo "$as_me: error: Garbage collection was required, but the gc library" >&2;}
{ { echo "$as_me:$LINENO: error: Garbage collection was required, but the gc library couldn't be found." >&5
echo "$as_me: error: Garbage collection was required, but the gc library couldn't be found." >&2;}
{ (exit 1); exit 1; }; }
{ echo "$as_me:$LINENO: couldn't be found." >&5
echo "$as_me: couldn't be found." >&6;}
fi
echo "$as_me:$LINENO: checking for GC_register_my_thread" >&5
echo $ECHO_N "checking for GC_register_my_thread... $ECHO_C" >&6
if test "${ac_cv_func_GC_register_my_thread+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define GC_register_my_thread to an innocuous variant, in case <limits.h> declares GC_register_my_thread.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define GC_register_my_thread innocuous_GC_register_my_thread
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char GC_register_my_thread (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef GC_register_my_thread
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char GC_register_my_thread ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_GC_register_my_thread) || defined (__stub___GC_register_my_thread)
choke me
#else
char (*f) () = GC_register_my_thread;
#endif
#ifdef __cplusplus
}
#endif
int
main ()
{
return f != GC_register_my_thread;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_func_GC_register_my_thread=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_func_GC_register_my_thread=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_GC_register_my_thread" >&5
echo "${ECHO_T}$ac_cv_func_GC_register_my_thread" >&6
if test "$ac_cv_func_GC_register_my_thread" = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_GC_REGISTER_MY_THREAD 1
_ACEOF
else
{ echo "$as_me:$LINENO: It looks like your libgc is quite old ... please use a newer one to support making the garbage collector aware of new threads." >&5
echo "$as_me: It looks like your libgc is quite old ... please use a newer one to support making the garbage collector aware of new threads." >&6;}
fi
LIBS="-lobjc_gc -ldl"
echo "$as_me:$LINENO: checking for class_ivar_set_gcinvisible" >&5
@ -3677,11 +3774,9 @@ else
fi
if test "$gc_ok" = no; then
{ { echo "$as_me:$LINENO: error: Garbage collection was required, but the gc runtime" >&5
echo "$as_me: error: Garbage collection was required, but the gc runtime" >&2;}
{ { echo "$as_me:$LINENO: error: Garbage collection was required, but the gc runtime couldn't be found." >&5
echo "$as_me: error: Garbage collection was required, but the gc runtime couldn't be found." >&2;}
{ (exit 1); exit 1; }; }
{ echo "$as_me:$LINENO: couldn't be found." >&5
echo "$as_me: couldn't be found." >&6;}
fi
LIBS="$saved_LIBS"

View file

@ -264,21 +264,25 @@ fi
if test $OBJC_WITH_GC = yes; then
AC_CHECK_HEADERS(gc.h, gc_ok=yes, gc_ok=no)
if test "$gc_ok" = no; then
AC_MSG_ERROR([Garbage collection was required, but the gc.h header])
AC_MSG_NOTICE([couldn't be found.])
AC_MSG_ERROR([Garbage collection was required, but the gc.h header couldn't be found.])
fi
saved_LIBS="$LIBS"
LIBS+=" -lgc"
AC_CHECK_FUNC(GC_malloc, gc_ok=yes, gc_ok=no)
if test "$gc_ok" = no; then
AC_MSG_ERROR([Garbage collection was required, but the gc library])
AC_MSG_NOTICE([couldn't be found.])
AC_MSG_ERROR([Garbage collection was required, but the gc library couldn't be found.])
fi
AC_CHECK_FUNC(GC_register_my_thread)
if test "$ac_cv_func_GC_register_my_thread" = yes; then
AC_DEFINE(HAVE_GC_REGISTER_MY_THREAD,1,
[Define if GC_register_my_thread function is available])
else
AC_MSG_NOTICE([It looks like your libgc is quite old ... please use a newer one to support making the garbage collector aware of new threads.])
fi
LIBS="-lobjc_gc -ldl"
AC_CHECK_FUNC(class_ivar_set_gcinvisible, gc_ok=yes, gc_ok=no)
if test "$gc_ok" = no; then
AC_MSG_ERROR([Garbage collection was required, but the gc runtime])
AC_MSG_NOTICE([couldn't be found.])
AC_MSG_ERROR([Garbage collection was required, but the gc runtime couldn't be found.])
fi
LIBS="$saved_LIBS"
AC_SUBST(OBJC_WITH_GC)