Preliminary changes for GC

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3612 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-01-28 17:21:03 +00:00
parent f14aaf6268
commit cd1e3d393f
4 changed files with 224 additions and 23 deletions

View file

@ -192,6 +192,15 @@ extern NSRecursiveLock *gnustep_global_lock;
- read: (TypedStream*)aStream;
- write: (TypedStream*)aStream;
@end
/*
* Protocol for garbage collection finalization - same as libFoundation
* for compatibility.
*/
@protocol GCFinalization
- (void) gcFinalize;
@end
#endif
#include <Foundation/NSDate.h>
@ -210,8 +219,22 @@ extern NSRecursiveLock *gnustep_global_lock;
/*
* RETAIN(), RELEASE(), and AUTORELEASE() are placeholders for the
* (possible) future day when we have garbage collecting.
* future day when we have garbage collecting.
*/
#ifndef GS_WITH_GC
#define GS_WITH_GC 0
#endif
#if GS_WITH_GC
#define RETAIN(object) ((id)object)
#define RELEASE(object)
#define AUTORELEASE(object) ((id)object)
#define ASSIGN(object,value) (object = value)
#define DESTROY(object) (object = nil)
#else
#define RETAIN(object) [object retain]
#define RELEASE(object) [object release]
#define AUTORELEASE(object) [object autorelease]
@ -241,5 +264,6 @@ if (value != object) \
* object later.
*/
#define DESTROY(object) ([object release], object = nil)
#endif
#endif /* __NSObject_h_GNUSTEP_BASE_INCLUDE */

View file

@ -23,16 +23,12 @@
#ifndef __NSZone_h_GNUSTEP_BASE_INCLUDE
#define __NSZone_h_GNUSTEP_BASE_INCLUDE
#include <objc/objc.h>
@class NSString;
typedef struct _NSZone NSZone;
/* The members are the same as the structure mstats which is in the
GNU C library. */
struct NSZoneStats
@ -60,19 +56,93 @@ struct _NSZone
NSZone *next;
};
void *GSOutOfMemory(size_t size, BOOL retry);
#ifndef GS_WITH_GC
#define GS_WITH_GC 0
#endif
#if GS_WITH_GC
#include <gc.h>
extern inline NSZone* NSCreateZone (size_t start, size_t gran, BOOL canFree)
{ return 0; }
extern inline NSZone* NSDefaultMallocZone (void)
{ return 0; }
extern inline NSZone* NSZoneFromPointer (void *ptr)
{ return 0; }
extern inline void* NSZoneMalloc (NSZone *zone, size_t size)
{
void *ptr = (void*)GC_MALLOC(size);
if (ptr == 0)
ptr = GSOutOfMemory(size, YES);
return ptr;
}
extern inline void* NSZoneCalloc (NSZone *zone, size_t elems, size_t bytes)
{
size_t size = elems * bytes;
void *ptr = (void*)GC_MALLOC(size);
void *ptr = (void*)GC_MALLOC(size, YES);
if (ptr == 0)
ptr = GSOutOfMemory(size);
memset(ptr, '\0', size);
return ptr;
}
extern inline void* NSZoneRealloc (NSZone *zone, void *ptr, size_t size)
{
ptr = GC_REALLOC(ptr, size);
if (ptr == 0)
GSOutOfMemory(size, NO);
return ptr;
}
extern inline void NSRecycleZone (NSZone *zone)
{
}
extern inline void NSZoneFree (NSZone *zone, void *ptr)
{
GC_FREE(ptr);
}
extern inline void NSSetZoneName (NSZone *zone, NSString *name)
{
}
extern inline NSString* NSZoneName (NSZone *zone)
{
return nil;
}
extern inline BOOL NSZoneCheck (NSZone *zone)
{
return YES;
}
extern inline struct NSZoneStats NSZoneStats (NSZone *zone)
{
struct NSZoneStats stats = { 0 };
return stats;
}
#else /* GS_WITH_GC */
/* Default zone. Name is hopelessly long so that no one will ever
want to use it. ;) Private variable. */
extern NSZone* __nszone_private_hidden_default_zone;
extern NSZone* NSCreateZone (size_t start, size_t gran, BOOL canFree);
extern inline NSZone* NSDefaultMallocZone (void)
{ return __nszone_private_hidden_default_zone; }
extern void NSSetDefaultMallocZone (NSZone *zone); // Not in OpenStep
extern NSZone* NSZoneFromPointer (void *ptr);
extern inline void* NSZoneMalloc (NSZone *zone, size_t size)
@ -108,4 +178,6 @@ extern inline struct NSZoneStats NSZoneStats (NSZone *zone)
{ if (!zone) zone = NSDefaultMallocZone();
return (zone->stats)(zone); }
#endif /* GS_WITH_GC */
#endif /* not __NSZone_h_GNUSTEP_BASE_INCLUDE */

View file

@ -100,8 +100,10 @@ void _fastBuildCache()
* correct zone to free memory very fast.
*/
#if GS_WITH_GC == 0
#define REFCNT_LOCAL 1
#define CACHE_ZONE 1
#endif
#if defined(REFCNT_LOCAL) || defined(CACHE_ZONE)
@ -140,6 +142,22 @@ typedef struct obj_layout *obj;
#endif /* defined(REFCNT_LOCAL) || defined(CACHE_ZONE) */
#if GS_WITH_GC
void
NSIncrementExtraRefCount(id anObject)
{
}
#define NSIncrementExtraRefCount(X)
BOOL
NSDecrementExtraRefCountWasZero(id anObject)
{
return NO;
}
#define NSDecrementExtraRefCountWasZero(X) NO
#else /* GS_WITH_GC */
/*
* Now do conditional compilation of reference count functions
* depending on whether we are using local or global counting.
@ -226,12 +244,72 @@ extraRefCount (id anObject)
#endif /* defined(REFCNT_LOCAL) */
#endif /* GS_WITH_GC */
/*
* Now do conditional compilation of memory allocation functions
* depending on what information (if any) we are storing before
* the start of each object.
*/
#if GS_WITH_GC
inline NSZone *
fastZone(NSObject *object)
{
return 0;
}
static void
GSFinalize(void* object, void* data)
{
[(id)object gcFinalize];
/* Set the class of anObject to FREED_OBJECT. The further messages to this
object will cause an error to occur. */
((id)object)->class_pointer = __freedObjectClass;
#ifndef NDEBUG
GSDebugAllocationRemove(((id)object)->class_pointer);
#endif
((id)object)->class_pointer = (void*) 0xdeadface;
}
inline NSObject *
NSAllocateObject (Class aClass, unsigned extraBytes, NSZone *zone)
{
id new = nil;
int size = aClass->instance_size + extraBytes;
if (CLS_ISCLASS (aClass))
new = NSZoneMalloc (zone, size);
if (new != nil)
{
memset (new, 0, size);
new->class_pointer = aClass;
}
if ([new respondsToSelector: @selector(gcFinalize)])
{
#ifndef NDEBUG
/*
* We only do allocation counting for objects that can be
* finalised - for other objects we have no way of decrementing
* the count when the object is collected.
*/
GSDebugAllocationAdd(aClass);
#endif
GC_REGISTER_FINALIZER (new, GSFinalize, NULL, NULL, NULL);
}
return new;
}
inline void
NSDeallocateObject(NSObject *anObject)
{
}
#else /* GS_WITH_GC */
#if defined(REFCNT_LOCAL) || defined(CACHE_ZONE)
#if defined(CACHE_ZONE)
@ -239,9 +317,9 @@ extraRefCount (id anObject)
inline NSZone *
fastZone(NSObject *object)
{
if (fastClass(object) == _fastCls._NXConstantString)
return NSDefaultMallocZone();
return ((obj)object)[-1].zone;
if (fastClass(object) == _fastCls._NXConstantString)
return NSDefaultMallocZone();
return ((obj)object)[-1].zone;
}
#else /* defined(CACHE_ZONE) */
@ -249,9 +327,9 @@ fastZone(NSObject *object)
inline NSZone *
fastZone(NSObject *object)
{
if (fastClass(object) == _fastCls._NXConstantString)
return NSDefaultMallocZone();
return NSZoneFromPointer(&((obj)object)[-1]);
if (fastClass(object) == _fastCls._NXConstantString)
return NSDefaultMallocZone();
return NSZoneFromPointer(&((obj)object)[-1]);
}
#endif /* defined(CACHE_ZONE) */
@ -345,11 +423,17 @@ NSDeallocateObject(NSObject *anObject)
#endif /* defined(REFCNT_LOCAL) || defined(CACHE_ZONE) */
#endif /* GS_WITH_GC */
BOOL
NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone)
{
return (!requestedZone || requestedZone == NSDefaultMallocZone()
#if GS_WITH_GC
return YES;
#else
return (!requestedZone || requestedZone == NSDefaultMallocZone()
|| fastZone(anObject) == requestedZone);
#endif
}
@ -630,6 +714,7 @@ static BOOL double_release_check_enabled = NO;
- autorelease
{
#if GS_WITH_GC == 0
if (double_release_check_enabled)
{
unsigned release_count;
@ -643,6 +728,7 @@ static BOOL double_release_check_enabled = NO;
}
(*autorelease_imp)(autorelease_class, autorelease_sel, self);
#endif
return self;
}
@ -781,6 +867,7 @@ static BOOL double_release_check_enabled = NO;
- (oneway void) release
{
#if GS_WITH_GC == 0
if (double_release_check_enabled)
{
unsigned release_count;
@ -793,7 +880,7 @@ static BOOL double_release_check_enabled = NO;
if (NSDecrementExtraRefCountWasZero(self))
[self dealloc];
return;
#endif
}
+ (oneway void) release
@ -815,7 +902,9 @@ static BOOL double_release_check_enabled = NO;
- retain
{
#if GS_WITH_GC == 0
NSIncrementExtraRefCount(self);
#endif
return self;
}
@ -826,7 +915,11 @@ static BOOL double_release_check_enabled = NO;
- (unsigned) retainCount
{
#if GS_WITH_GC
return UINT_MAX;
#else
return extraRefCount(self) + 1;
#endif
}
+ (unsigned) retainCount

View file

@ -92,6 +92,22 @@
#include <Foundation/NSLock.h>
/*
* Try to get more memory - the normal process has failed.
* If we can't do anything, bomb out.
*/
void *
GSOutOfMemory(size_t size, BOOL retry)
{
/*
* It would be nice to raise an exception - but how can we if there is
* no memory available?
*/
abort();
}
#if GS_WITH_GC == 0
/* Alignment */
#define ALIGN ((__alignof__(double) < 8) ? 8 : __alignof__(double))
#define MINGRAN 256 /* Minimum granularity. */
@ -1659,13 +1675,6 @@ NSDefaultMallocZone (void)
return __nszone_private_hidden_default_zone;
}
/* Not in OpenStep. */
void
NSSetDefaultMallocZone (NSZone *zone)
{
__nszone_private_hidden_default_zone = zone;
}
inline void*
NSZoneMalloc (NSZone *zone, size_t size)
{
@ -1743,3 +1752,6 @@ NSZoneStats (NSZone *zone)
zone = NSDefaultMallocZone();
return (zone->stats)(zone);
}
#endif /* GS_WITH_GC */