mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
GC changes for MacOS-X compatiblity
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27630 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ff7212cf67
commit
6bccff5fc7
20 changed files with 537 additions and 294 deletions
35
ChangeLog
35
ChangeLog
|
@ -1,3 +1,38 @@
|
|||
2009-01-19 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSZone.h:
|
||||
* Source/NSZone.m:
|
||||
Add NSAllocateCollectable() and NSReallocateCollectable() functions.
|
||||
Move inline stuff from header to source fle so that GC differences
|
||||
are hidden. Change behavior under GC so that the default malloc
|
||||
zone is non-collectable (as under MacOS-X).
|
||||
* Headers/Additions/GNUstepBase/GSIMap.h:
|
||||
Use scanned collectable memory for map.
|
||||
* Source/Additions/GSObjCRuntime.m:
|
||||
Use NSAllocateCollectable() for fast buffer.
|
||||
* Source/GSArray.m:
|
||||
* Source/GSCountedSet.m:
|
||||
* Source/GSDictionary.m:
|
||||
* Source/GSSet.m:
|
||||
* Source/NSArchiver.m:
|
||||
* Source/NSConnection.m:
|
||||
* Source/NSHashTable.m:
|
||||
* Source/NSKeyedArchiver.m:
|
||||
* Source/NSMapTable.m:
|
||||
* Source/NSNotificationCenter.m:
|
||||
* Source/NSObject.m:
|
||||
* Source/NSPortCoder.m:
|
||||
* Source/NSSerializer.m:
|
||||
* Source/NSPropertyList.m:
|
||||
Use scanned collectable memory in places where we allocate memory to
|
||||
hold pointers. This change is needed because of the switch to have
|
||||
the default zone use unscanned uncollectable memory as in MacOS-X.
|
||||
These changes probably just scratch the surface ... we need to review
|
||||
all memory allocation as, anywhere we allocate memory now will need
|
||||
to be done differently under GC. This does mean that all existing
|
||||
code needs more work to port to GC than it otherwise would. On the
|
||||
other hand, a switch to GC is really quite a major design change.
|
||||
|
||||
2009-01-17 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* Source/unix/GSRunLoopCtxt.m (+awakenedBefore): Fix typo.
|
||||
|
|
|
@ -421,11 +421,11 @@ GSIMapMoreNodes(GSIMapTable map, unsigned required)
|
|||
/*
|
||||
* Our nodes may be allocated from the atomic zone - but we don't want
|
||||
* them freed - so we must keep the array of pointers to memory chunks in
|
||||
* the default zone
|
||||
* scanned memory.
|
||||
*/
|
||||
if (map->zone == GSAtomicMallocZone())
|
||||
{
|
||||
newArray = (GSIMapNode*)NSZoneMalloc(NSDefaultMallocZone(), arraySize);
|
||||
newArray = (GSIMapNode*)NSAllocateCollectable(arraySize, NSScannedOption);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -438,7 +438,8 @@ GSIMapMoreNodes(GSIMapTable map, unsigned required)
|
|||
|
||||
if (map->nodeChunks != 0)
|
||||
{
|
||||
memcpy(newArray, map->nodeChunks, (map->chunkCount)*sizeof(GSIMapNode));
|
||||
memcpy(newArray, map->nodeChunks,
|
||||
(map->chunkCount)*sizeof(GSIMapNode));
|
||||
NSZoneFree(map->zone, map->nodeChunks);
|
||||
}
|
||||
map->nodeChunks = newArray;
|
||||
|
|
|
@ -136,40 +136,31 @@ struct _NSZone
|
|||
* If we can't do anything, just return a null pointer.
|
||||
* Try to do some logging if possible.
|
||||
*/
|
||||
void *GSOutOfMemory(size_t size, BOOL retry);
|
||||
void*
|
||||
GSOutOfMemory(size_t size, BOOL retry);
|
||||
|
||||
#ifdef IN_NSZONE_M
|
||||
#define GS_ZONE_SCOPE extern
|
||||
#define GS_ZONE_ATTR
|
||||
#else
|
||||
#define GS_ZONE_SCOPE static inline
|
||||
#define GS_ZONE_ATTR __attribute__((unused))
|
||||
#endif
|
||||
NSZone*
|
||||
NSCreateZone (size_t start, size_t gran, BOOL canFree);
|
||||
|
||||
/* Default zone. Name is hopelessly long so that no one will ever
|
||||
want to use it. ;) Private variable. */
|
||||
GS_EXPORT NSZone* __nszone_private_hidden_default_zone;
|
||||
NSZone*
|
||||
NSDefaultMallocZone (void);
|
||||
|
||||
#ifndef GS_WITH_GC
|
||||
#define GS_WITH_GC 0
|
||||
#endif
|
||||
#if GS_WITH_GC
|
||||
/**
|
||||
* Returns the default zone used for memory allocation, created at startup.
|
||||
* This zone cannot be recycled.
|
||||
*/
|
||||
NSZone*
|
||||
GSAtomicMallocZone (void);
|
||||
|
||||
#include <gc.h>
|
||||
/**
|
||||
* Returns the default zone used for scanned memory allocation ... a
|
||||
* garbage collectable chunk of memory which is scanned for pointers.
|
||||
*/
|
||||
NSZone*
|
||||
GSScannedMallocZone (void);
|
||||
|
||||
GS_EXPORT NSZone* __nszone_private_hidden_atomic_zone;
|
||||
|
||||
GS_ZONE_SCOPE NSZone* NSCreateZone (size_t start, size_t gran, BOOL canFree)
|
||||
{ return __nszone_private_hidden_default_zone; }
|
||||
|
||||
GS_ZONE_SCOPE NSZone* NSDefaultMallocZone (void)
|
||||
{ return __nszone_private_hidden_default_zone; }
|
||||
|
||||
GS_ZONE_SCOPE NSZone* GSAtomicMallocZone (void)
|
||||
{ return __nszone_private_hidden_atomic_zone; }
|
||||
|
||||
GS_ZONE_SCOPE NSZone* NSZoneFromPointer (void *ptr)
|
||||
{ return __nszone_private_hidden_default_zone; }
|
||||
NSZone*
|
||||
NSZoneFromPointer (void *ptr);
|
||||
|
||||
/**
|
||||
* Allocates and returns memory for elems items of size bytes, in the
|
||||
|
@ -178,19 +169,8 @@ GS_ZONE_SCOPE NSZone* NSZoneFromPointer (void *ptr)
|
|||
* allocate and no more can be obtained from system, unless using the
|
||||
* default zone, in which case NULL is returned.
|
||||
*/
|
||||
GS_ZONE_SCOPE void* NSZoneMalloc (NSZone *zone, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (zone == GSAtomicMallocZone())
|
||||
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
||||
else
|
||||
ptr = (void*)GC_MALLOC(size);
|
||||
|
||||
if (ptr == 0)
|
||||
ptr = GSOutOfMemory(size, YES);
|
||||
return ptr;
|
||||
}
|
||||
void*
|
||||
NSZoneMalloc (NSZone *zone, size_t size);
|
||||
|
||||
/**
|
||||
* Allocates and returns cleared memory for elems items of size bytes, in the
|
||||
|
@ -199,134 +179,8 @@ GS_ZONE_SCOPE void* NSZoneMalloc (NSZone *zone, size_t size)
|
|||
* allocate and no more can be obtained from system, unless using the
|
||||
* default zone, in which case NULL is returned.
|
||||
*/
|
||||
GS_ZONE_SCOPE void* NSZoneCalloc (NSZone *zone, size_t elems, size_t bytes)
|
||||
{
|
||||
size_t size = elems * bytes;
|
||||
void *ptr;
|
||||
|
||||
if (zone == __nszone_private_hidden_atomic_zone)
|
||||
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
||||
else
|
||||
ptr = (void*)GC_MALLOC(size);
|
||||
|
||||
if (ptr == 0)
|
||||
ptr = GSOutOfMemory(size, NO);
|
||||
memset(ptr, '\0', size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE void* NSZoneRealloc (NSZone *zone, void *ptr, size_t size)
|
||||
{
|
||||
ptr = GC_REALLOC(ptr, size);
|
||||
if (ptr == 0)
|
||||
GSOutOfMemory(size, NO);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE void NSRecycleZone (NSZone *zone)
|
||||
{
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE void NSZoneFree (NSZone *zone, void *ptr)
|
||||
{
|
||||
GC_FREE(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name of the given zone (useful for debugging and logging).
|
||||
*/
|
||||
GS_ZONE_SCOPE void NSSetZoneName (NSZone *zone, NSString *name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name of the given zone (useful for debugging and logging).
|
||||
*/
|
||||
GS_ZONE_SCOPE NSString* NSZoneName (NSZone *zone)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
|
||||
|
||||
/**
|
||||
* Allocates mmemory of size bytes from zone, with the assumption that the
|
||||
* memory will never contain pointers. This is only relevant in situations
|
||||
* where a form of garbage collection is enabled, and NSZoneMalloc() should
|
||||
* always be used otherwise. Not defined by OpenStep or OS X.
|
||||
*/
|
||||
GS_ZONE_SCOPE void* NSZoneMallocAtomic (NSZone *zone, size_t size)
|
||||
{
|
||||
return NSZoneMalloc(GSAtomicMallocZone(), size);
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE BOOL NSZoneCheck (NSZone *zone)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE struct NSZoneStats NSZoneStats (NSZone *zone)
|
||||
{
|
||||
struct NSZoneStats stats = { 0 };
|
||||
return stats;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* GS_WITH_GC */
|
||||
|
||||
GS_EXPORT NSZone* NSCreateZone (size_t start, size_t gran, BOOL canFree);
|
||||
|
||||
GS_ZONE_SCOPE NSZone* NSDefaultMallocZone (void) GS_ZONE_ATTR;
|
||||
|
||||
/**
|
||||
* Returns the default zone used for memory allocation, created at startup.
|
||||
* This zone cannot be recycled.
|
||||
*/
|
||||
GS_ZONE_SCOPE NSZone* NSDefaultMallocZone (void)
|
||||
{
|
||||
return __nszone_private_hidden_default_zone;
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE NSZone* GSAtomicMallocZone (void) GS_ZONE_ATTR;
|
||||
|
||||
/**
|
||||
* Returns the default zone used for atomic memory allocation (see
|
||||
* NSMallocAtomic()), if no zone is specified.
|
||||
*/
|
||||
GS_ZONE_SCOPE NSZone* GSAtomicMallocZone (void)
|
||||
{
|
||||
return NSDefaultMallocZone();
|
||||
}
|
||||
|
||||
GS_EXPORT NSZone* NSZoneFromPointer (void *ptr);
|
||||
|
||||
GS_ZONE_SCOPE void* NSZoneMalloc (NSZone *zone, size_t size) GS_ZONE_ATTR;
|
||||
|
||||
/**
|
||||
* Allocates and returns cleared memory for elems items of size bytes, in the
|
||||
* given zone. Returns NULL if allocation of size 0 requested. Raises
|
||||
* <code>NSMallocException</code> if not enough free memory in zone to
|
||||
* allocate and no more can be obtained from system, unless using the
|
||||
* default zone, in which case NULL is returned.
|
||||
*/
|
||||
GS_ZONE_SCOPE void* NSZoneMalloc (NSZone *zone, size_t size)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->malloc)(zone, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and returns cleared memory for elems items of size bytes, in the
|
||||
* given zone. Returns NULL if allocation of size 0 requested. Raises
|
||||
* <code>NSMallocException</code> if not enough free memory in zone to
|
||||
* allocate and no more can be obtained from system, unless using the
|
||||
* default zone, in which case NULL is returned.
|
||||
*/
|
||||
GS_EXPORT void* NSZoneCalloc (NSZone *zone, size_t elems, size_t bytes);
|
||||
|
||||
GS_ZONE_SCOPE void*
|
||||
NSZoneRealloc (NSZone *zone, void *ptr, size_t size) GS_ZONE_ATTR;
|
||||
void*
|
||||
NSZoneCalloc (NSZone *zone, size_t elems, size_t bytes);
|
||||
|
||||
/**
|
||||
* Reallocates the chunk of memory in zone pointed to by ptr to a new one of
|
||||
|
@ -335,14 +189,8 @@ NSZoneRealloc (NSZone *zone, void *ptr, size_t size) GS_ZONE_ATTR;
|
|||
* zone and no more memory can be obtained from the system, unless using the
|
||||
* default zone, in which case NULL is returned.
|
||||
*/
|
||||
GS_ZONE_SCOPE void* NSZoneRealloc (NSZone *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->realloc)(zone, ptr, size);
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE void NSRecycleZone (NSZone *zone) GS_ZONE_ATTR;
|
||||
void*
|
||||
NSZoneRealloc (NSZone *zone, void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Return memory for an entire zone to system. In fact, this will not be done
|
||||
|
@ -351,14 +199,8 @@ GS_ZONE_SCOPE void NSRecycleZone (NSZone *zone) GS_ZONE_ATTR;
|
|||
* must simply equal the number of allocation calls. The default zone, on the
|
||||
* other hand, cannot be recycled.
|
||||
*/
|
||||
GS_ZONE_SCOPE void NSRecycleZone (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
(zone->recycle)(zone);
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE void NSZoneFree (NSZone *zone, void *ptr) GS_ZONE_ATTR;
|
||||
void
|
||||
NSRecycleZone (NSZone *zone);
|
||||
|
||||
/**
|
||||
* Frees memory pointed to by ptr (which should have been allocated by a
|
||||
|
@ -366,91 +208,89 @@ GS_ZONE_SCOPE void NSZoneFree (NSZone *zone, void *ptr) GS_ZONE_ATTR;
|
|||
* returns it to zone. Note, if this is a nonfreeable zone, the memory is
|
||||
* not actually freed, but the count of number of free()s is updated.
|
||||
*/
|
||||
GS_ZONE_SCOPE void NSZoneFree (NSZone *zone, void *ptr)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
(zone->free)(zone, ptr);
|
||||
}
|
||||
|
||||
GS_EXPORT void NSSetZoneName (NSZone *zone, NSString *name);
|
||||
|
||||
GS_ZONE_SCOPE NSString* NSZoneName (NSZone *zone) GS_ZONE_ATTR;
|
||||
void
|
||||
NSZoneFree (NSZone *zone, void *ptr);
|
||||
|
||||
/**
|
||||
* Returns the name assigned to the zone, if one has been given (see
|
||||
* NSSetZoneName()), otherwise nil. Useful for debugging/logging.
|
||||
* Sets name of the given zone (useful for debugging and logging).
|
||||
*/
|
||||
GS_ZONE_SCOPE NSString* NSZoneName (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return zone->name;
|
||||
}
|
||||
void
|
||||
NSSetZoneName (NSZone *zone, NSString *name);
|
||||
|
||||
/**
|
||||
* Sets name of the given zone (useful for debugging and logging).
|
||||
*/
|
||||
NSString*
|
||||
NSZoneName (NSZone *zone);
|
||||
|
||||
#if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
|
||||
GS_ZONE_SCOPE void*
|
||||
NSZoneMallocAtomic (NSZone *zone, size_t size) GS_ZONE_ATTR;
|
||||
|
||||
/**
|
||||
* Allocates memory of size bytes from zone, with the assumption that the
|
||||
* memory will never contain pointers. This is only relevant in situations
|
||||
* where a form of garbage collection is enabled, and NSZoneMalloc() should
|
||||
* always be used otherwise. Not defined by OpenStep or OS X.
|
||||
*/
|
||||
GS_ZONE_SCOPE void* NSZoneMallocAtomic (NSZone *zone, size_t size)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->malloc)(zone, size);
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE BOOL NSZoneCheck (NSZone *zone) GS_ZONE_ATTR;
|
||||
|
||||
/**
|
||||
* Checks integrity of a zone. Not defined by OpenStep or OS X.
|
||||
*/
|
||||
GS_ZONE_SCOPE BOOL NSZoneCheck (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->check)(zone);
|
||||
}
|
||||
|
||||
GS_ZONE_SCOPE struct NSZoneStats NSZoneStats (NSZone *zone) GS_ZONE_ATTR;
|
||||
BOOL
|
||||
NSZoneCheck (NSZone *zone);
|
||||
|
||||
/**
|
||||
* Obtain statistics about the zone. Implementation emphasis is on
|
||||
* correctness, not speed. Not defined by OpenStep or OS X.
|
||||
*/
|
||||
GS_ZONE_SCOPE struct NSZoneStats NSZoneStats (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->stats)(zone);
|
||||
}
|
||||
#endif /* GS_API_NONE */
|
||||
struct NSZoneStats
|
||||
NSZoneStats (NSZone *zone);
|
||||
|
||||
#endif /* GS_WITH_GC */
|
||||
#endif
|
||||
|
||||
GS_EXPORT NSUInteger
|
||||
NSPageSize (void) __attribute__ ((const));
|
||||
|
||||
GS_EXPORT NSUInteger NSPageSize (void) __attribute__ ((const));
|
||||
GS_EXPORT NSUInteger
|
||||
NSLogPageSize (void) __attribute__ ((const));
|
||||
|
||||
GS_EXPORT NSUInteger NSLogPageSize (void) __attribute__ ((const));
|
||||
GS_EXPORT NSUInteger
|
||||
NSRoundDownToMultipleOfPageSize (NSUInteger bytes) __attribute__ ((const));
|
||||
|
||||
GS_EXPORT NSUInteger NSRoundDownToMultipleOfPageSize (NSUInteger bytes)
|
||||
__attribute__ ((const));
|
||||
GS_EXPORT NSUInteger
|
||||
NSRoundUpToMultipleOfPageSize (NSUInteger bytes) __attribute__ ((const));
|
||||
|
||||
GS_EXPORT NSUInteger NSRoundUpToMultipleOfPageSize (NSUInteger bytes)
|
||||
__attribute__ ((const));
|
||||
GS_EXPORT NSUInteger
|
||||
NSRealMemoryAvailable (void);
|
||||
|
||||
GS_EXPORT NSUInteger NSRealMemoryAvailable (void);
|
||||
GS_EXPORT void*
|
||||
NSAllocateMemoryPages (NSUInteger bytes);
|
||||
|
||||
GS_EXPORT void* NSAllocateMemoryPages (NSUInteger bytes);
|
||||
GS_EXPORT void
|
||||
NSDeallocateMemoryPages (void *ptr, NSUInteger bytes);
|
||||
|
||||
GS_EXPORT void NSDeallocateMemoryPages (void *ptr, NSUInteger bytes);
|
||||
GS_EXPORT void
|
||||
NSCopyMemoryPages (const void *src, void *dest, NSUInteger bytes);
|
||||
|
||||
GS_EXPORT void NSCopyMemoryPages (const void *src, void *dest, NSUInteger bytes);
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, OS_API_LATEST)
|
||||
|
||||
enum {
|
||||
NSScannedOption = (1<<0),
|
||||
NSCollectorDisabledOption = (1<<1),
|
||||
};
|
||||
|
||||
/** Allocate memory. If garbage collection is not enabled this uses the
|
||||
* default malloc zone and the options are ignored.<br />
|
||||
* If garbage collection is enabled, the allocate memory is normally not
|
||||
* scanned for pointers but is isttself garbage collectable. The options
|
||||
* argument is a bitmask in which NSScannedOption sets the memory to be
|
||||
* scanned for pointers by the garbage collector, and
|
||||
* NSCollectorDisabledOption causes the memory to be excempt from being
|
||||
* garbage collected itsself.
|
||||
*/
|
||||
GS_EXPORT void *
|
||||
NSAllocateCollectable(NSUInteger size, NSUInteger options);
|
||||
|
||||
/** Reallocate memory to be of a different size and/or to have different
|
||||
* options settings. The behavior of options is as for
|
||||
* the NSAllocateCollectable() function.
|
||||
*/
|
||||
GS_EXPORT void *
|
||||
NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -2342,7 +2342,7 @@ void *
|
|||
GSAutoreleasedBuffer(unsigned size)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
return GC_malloc(size);
|
||||
return NSAllocateCollectable(size, NSScannedOption);
|
||||
#else
|
||||
#ifdef ALIGN
|
||||
#undef ALIGN
|
||||
|
|
|
@ -147,7 +147,12 @@ static Class GSInlineArrayClass;
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
#if GS_WITH_GC
|
||||
_contents_array = NSAllocateCollectable(sizeof(id)*count,
|
||||
NSScannedOption);
|
||||
#else
|
||||
_contents_array = NSZoneMalloc([self zone], sizeof(id)*count);
|
||||
#endif
|
||||
if (_contents_array == 0)
|
||||
{
|
||||
RELEASE(self);
|
||||
|
@ -204,7 +209,12 @@ static Class GSInlineArrayClass;
|
|||
at: &_count];
|
||||
if (_count > 0)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
_contents_array = NSAllocateCollectable(sizeof(id) * _count,
|
||||
NSScannedOption);
|
||||
#else
|
||||
_contents_array = NSZoneCalloc([self zone], _count, sizeof(id));
|
||||
#endif
|
||||
if (_contents_array == 0)
|
||||
{
|
||||
[NSException raise: NSMallocException
|
||||
|
@ -497,7 +507,11 @@ static Class GSInlineArrayClass;
|
|||
{
|
||||
cap = 1;
|
||||
}
|
||||
#if GS_WITH_GC
|
||||
_contents_array = NSAllocateCollectable(sizeof(id)*cap, NSScannedOption);
|
||||
#else
|
||||
_contents_array = NSZoneMalloc([self zone], sizeof(id)*cap);
|
||||
#endif
|
||||
_capacity = cap;
|
||||
_grow_factor = cap > 1 ? cap/2 : 1;
|
||||
return self;
|
||||
|
@ -1074,7 +1088,7 @@ static Class GSInlineArrayClass;
|
|||
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &c];
|
||||
a = (id)NSAllocateObject(GSArrayClass, 0, GSObjCZone(self));
|
||||
a->_contents_array = NSZoneMalloc(GSObjCZone(self), sizeof(id)*c);
|
||||
a->_contents_array = NSAllocateCollectable(sizeof(id)*c, NSScannedOption);
|
||||
#else
|
||||
GSInlineArray *a;
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ static void _setup(void)
|
|||
NSMutableArray *a;
|
||||
NSDictionary *d;
|
||||
|
||||
GSIMapInitWithZoneAndCapacity(&attrMap, NSDefaultMallocZone(), 32);
|
||||
GSIMapInitWithZoneAndCapacity(&attrMap, GSScannedMallocZone(), 32);
|
||||
|
||||
infSel = @selector(newWithZone:value:at:);
|
||||
addSel = @selector(addObject:);
|
||||
|
|
|
@ -183,7 +183,11 @@
|
|||
/* Designated initialiser */
|
||||
- (id) initWithCapacity: (unsigned)cap
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), cap);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, [self zone], cap);
|
||||
#endif
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -199,7 +203,11 @@
|
|||
|
||||
(*imp)(aCoder, sel, utype, &count);
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), count);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, [self zone], count);
|
||||
#endif
|
||||
while (count-- > 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, otype, &value);
|
||||
|
|
|
@ -156,7 +156,11 @@ static SEL objSel;
|
|||
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
||||
at: &count];
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), count);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), count);
|
||||
#endif
|
||||
while (count-- > 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, type, &key);
|
||||
|
@ -172,7 +176,11 @@ static SEL objSel;
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), c);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), c);
|
||||
#endif
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
GSIMapNode node;
|
||||
|
@ -214,7 +222,11 @@ static SEL objSel;
|
|||
NSZone *z = GSObjCZone(self);
|
||||
unsigned c = [other count];
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), c);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, z, c);
|
||||
#endif
|
||||
|
||||
if (c > 0)
|
||||
{
|
||||
|
@ -366,7 +378,11 @@ static SEL objSel;
|
|||
/* Designated initialiser */
|
||||
- (id) initWithCapacity: (unsigned)cap
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), cap);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), cap);
|
||||
#endif
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,11 @@ static Class mutableSetClass;
|
|||
|
||||
(*imp)(aCoder, sel, @encode(unsigned), &count);
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), count);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, [self zone], count);
|
||||
#endif
|
||||
while (count-- > 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, type, &value);
|
||||
|
@ -242,7 +246,11 @@ static Class mutableSetClass;
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), c);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, [self zone], c);
|
||||
#endif
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
GSIMapNode node;
|
||||
|
@ -576,7 +584,11 @@ static Class mutableSetClass;
|
|||
/* Designated initialiser */
|
||||
- (id) initWithCapacity: (unsigned)cap
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&map, GSScannedMallocZone(), cap);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&map, [self zone], cap);
|
||||
#endif
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,9 @@ static Class NSMutableDataMallocClass;
|
|||
/*
|
||||
* Set up map tables.
|
||||
*/
|
||||
#if GS_WITH_GC
|
||||
zone = GSScannedMallocZone();
|
||||
#endif
|
||||
_clsMap = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t)*6);
|
||||
_cIdMap = &_clsMap[1];
|
||||
_uIdMap = &_clsMap[2];
|
||||
|
|
|
@ -949,6 +949,9 @@ static NSLock *cached_proxies_gate = nil;
|
|||
*/
|
||||
_requestQueue = [NSMutableArray new];
|
||||
|
||||
#if GS_WITH_GC
|
||||
z = GSScannedMallocZone();
|
||||
#endif
|
||||
/*
|
||||
* This maps request sequence numbers to the NSPortCoder objects representing
|
||||
* replies arriving from the remote connection.
|
||||
|
|
|
@ -155,6 +155,9 @@ NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if GS_WITH_GC
|
||||
zone = GSScannedMallocZone();
|
||||
#endif
|
||||
t = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount);
|
||||
t->extra = ((GSIMapTable)table)->extra;
|
||||
|
@ -213,6 +216,9 @@ NSCreateHashTableWithZone(
|
|||
{
|
||||
GSIMapTable table;
|
||||
|
||||
#if GS_WITH_GC
|
||||
zone = GSScannedMallocZone();
|
||||
#endif
|
||||
table = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(table, zone, capacity);
|
||||
table->extra = callBacks;
|
||||
|
|
|
@ -809,6 +809,9 @@ static NSDictionary *makeReference(unsigned ref)
|
|||
/*
|
||||
* Set up map tables.
|
||||
*/
|
||||
#if GS_WITH_GC
|
||||
zone = GSScannedMallocZone();
|
||||
#endif
|
||||
_cIdMap = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t)*5);
|
||||
_uIdMap = &_cIdMap[1];
|
||||
_repMap = &_cIdMap[2];
|
||||
|
|
|
@ -207,6 +207,9 @@ NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if GS_WITH_GC
|
||||
zone = GSScannedMallocZone();
|
||||
#endif
|
||||
t = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount);
|
||||
t->extra.k = ((GSIMapTable)table)->extra.k;
|
||||
|
@ -270,6 +273,9 @@ NSCreateMapTableWithZone(
|
|||
{
|
||||
GSIMapTable table;
|
||||
|
||||
#if GS_WITH_GC
|
||||
zone = GSScannedMallocZone();
|
||||
#endif
|
||||
table = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(table, zone, capacity);
|
||||
table->extra.k = keyCallBacks;
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#define purgeCollected(X) (X)
|
||||
#endif
|
||||
|
||||
static NSZone *_zone = 0;
|
||||
|
||||
/**
|
||||
* Concrete class implementing NSNotification.
|
||||
*/
|
||||
|
@ -286,7 +288,7 @@ static Observation *obsNew(NCTable* t)
|
|||
size = CHUNKSIZE * sizeof(Observation);
|
||||
#if GS_WITH_GC
|
||||
t->chunks[t->numChunks - 1]
|
||||
= (Observation*)NSZoneMallocAtomic(NSDefaultMallocZone(), size);
|
||||
= (Observation*)NSZoneMalloc(GSAtomicMallocZone(), size);
|
||||
#else
|
||||
t->chunks[t->numChunks - 1]
|
||||
= (Observation*)NSZoneMalloc(NSDefaultMallocZone(), size);
|
||||
|
@ -312,8 +314,8 @@ static GSIMapTable mapNew(NCTable *t)
|
|||
{
|
||||
GSIMapTable m;
|
||||
|
||||
m = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(m, NSDefaultMallocZone(), 2);
|
||||
m = NSZoneMalloc(_zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(m, _zone, 2);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
@ -399,16 +401,16 @@ static NCTable *newNCTable(void)
|
|||
{
|
||||
NCTable *t;
|
||||
|
||||
t = (NCTable*)NSZoneMalloc(NSDefaultMallocZone(), sizeof(NCTable));
|
||||
t = (NCTable*)NSZoneMalloc(_zone, sizeof(NCTable));
|
||||
memset((void*)t, '\0', sizeof(NCTable));
|
||||
t->chunkIndex = CHUNKSIZE;
|
||||
t->wildcard = ENDOBS;
|
||||
|
||||
t->nameless = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t->nameless, NSDefaultMallocZone(), 16);
|
||||
t->nameless = NSZoneMalloc(_zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t->nameless, _zone, 16);
|
||||
|
||||
t->named = NSZoneMalloc(NSDefaultMallocZone(), sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t->named, NSDefaultMallocZone(), 128);
|
||||
t->named = NSZoneMalloc(_zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t->named, _zone, 128);
|
||||
|
||||
// t->_lock = [GSLazyRecursiveLock new];
|
||||
t->_lock = [NSRecursiveLock new];
|
||||
|
@ -582,6 +584,11 @@ static NSNotificationCenter *default_center = nil;
|
|||
{
|
||||
if (self == [NSNotificationCenter class])
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
_zone = GSScannedMallocZone();
|
||||
#else
|
||||
_zone = NSDefaultMallocZone();
|
||||
#endif
|
||||
if (concrete == 0)
|
||||
{
|
||||
concrete = [GSNotification class];
|
||||
|
@ -1001,7 +1008,7 @@ static NSNotificationCenter *default_center = nil;
|
|||
/*
|
||||
* Initialise static array to store copies of observers.
|
||||
*/
|
||||
GSIArrayInitWithZoneAndStaticCapacity(a, NSDefaultMallocZone(), 64, i);
|
||||
GSIArrayInitWithZoneAndStaticCapacity(a, _zone, 64, i);
|
||||
|
||||
/*
|
||||
* Lock the table of observations while we traverse it.
|
||||
|
|
|
@ -668,7 +668,14 @@ NSIncrementExtraRefCount(id anObject)
|
|||
inline NSZone *
|
||||
GSObjCZone(NSObject *object)
|
||||
{
|
||||
return 0;
|
||||
/* If we have GC enabled, all objects are garbage collected and memory
|
||||
* they allocate should generally be garbage collectable but not scanned
|
||||
* for pointers.
|
||||
* If an object wants to have memory which IS scanned for pointers by the
|
||||
* garbage collector, it should use NSAllocateCollectable() to get it,
|
||||
* rather than using the old zone based memory allocation.
|
||||
*/
|
||||
return GSAtomicMallocZone();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -686,8 +693,10 @@ NSAllocateObject(Class aClass, unsigned extraBytes, NSZone *zone)
|
|||
{
|
||||
id new;
|
||||
int size;
|
||||
GC_descr gc_type;
|
||||
|
||||
NSCAssert((CLS_ISCLASS(aClass)), @"Bad class for new object");
|
||||
gc_type = (GC_descr)aClass->gc_object_type;
|
||||
size = aClass->instance_size + extraBytes;
|
||||
if (size % sizeof(void*) != 0)
|
||||
{
|
||||
|
@ -696,29 +705,20 @@ NSAllocateObject(Class aClass, unsigned extraBytes, NSZone *zone)
|
|||
*/
|
||||
size += sizeof(void*) - size % sizeof(void*);
|
||||
}
|
||||
if (zone == GSAtomicMallocZone())
|
||||
|
||||
if (gc_type == 0)
|
||||
{
|
||||
new = NSZoneCalloc(zone, 1, size);
|
||||
NSLog(@"No garbage collection information for '%s'",
|
||||
GSNameFromClass(aClass));
|
||||
}
|
||||
else
|
||||
{
|
||||
GC_descr gc_type = (GC_descr)aClass->gc_object_type;
|
||||
|
||||
if (gc_type == 0)
|
||||
{
|
||||
new = NSZoneCalloc(zone, 1, size);
|
||||
NSLog(@"No garbage collection information for '%s'",
|
||||
GSNameFromClass(aClass));
|
||||
}
|
||||
else
|
||||
{
|
||||
new = GC_calloc_explicitly_typed(1, size, gc_type);
|
||||
}
|
||||
new = GC_calloc_explicitly_typed(1, size, gc_type);
|
||||
}
|
||||
|
||||
if (new != nil)
|
||||
{
|
||||
memset(new, 0, size);
|
||||
new->class_pointer = aClass;
|
||||
if (get_imp(aClass, finalize_sel) != finalize_imp
|
||||
&& __objc_responds_to(new, finalize_sel))
|
||||
|
|
|
@ -1709,6 +1709,9 @@ static IMP _xRefImp; /* Serialize a crossref. */
|
|||
_eObjImp = [self methodForSelector: eObjSel];
|
||||
_eValImp = [self methodForSelector: eValSel];
|
||||
|
||||
#if GS_WITH_GC
|
||||
_zone = GSScannedMallocZone();
|
||||
#endif
|
||||
/*
|
||||
* Set up map tables.
|
||||
*/
|
||||
|
|
|
@ -723,7 +723,7 @@ static inline id parseQuotedString(pldata* pld)
|
|||
return nil;
|
||||
}
|
||||
length = temp_length - shrink;
|
||||
chars = NSZoneMalloc(NSDefaultMallocZone(), sizeof(unichar) * length);
|
||||
chars = NSAllocateCollectable(sizeof(unichar) * length, 0);
|
||||
escaped = 0;
|
||||
hex = NO;
|
||||
for (j = 0, k = 0; j < temp_length; j++)
|
||||
|
@ -845,7 +845,7 @@ static inline id parseUnquotedString(pldata *pld)
|
|||
}
|
||||
|
||||
length = pld->pos - start;
|
||||
chars = NSZoneMalloc(NSDefaultMallocZone(), sizeof(unichar) * length);
|
||||
chars = NSAllocateCollectable(sizeof(unichar) * length, 0);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
chars[i] = pld->ptr[start + i];
|
||||
|
@ -1606,7 +1606,7 @@ PString(NSString *obj, NSMutableData *output)
|
|||
}
|
||||
else
|
||||
{
|
||||
ustring = NSZoneMalloc(NSDefaultMallocZone(), length*sizeof(unichar));
|
||||
ustring = NSAllocateCollectable(sizeof(unichar) * length, 0);
|
||||
}
|
||||
end = &ustring[length];
|
||||
[obj getCharacters: ustring];
|
||||
|
@ -1747,7 +1747,7 @@ XString(NSString* obj, NSMutableData *output)
|
|||
unsigned rpos;
|
||||
unsigned wpos;
|
||||
|
||||
base = NSZoneMalloc(NSDefaultMallocZone(), end * sizeof(unichar));
|
||||
base = NSAllocateCollectable(sizeof(unichar) * end, 0);
|
||||
[obj getCharacters: base];
|
||||
for (len = rpos = 0; rpos < end; rpos++)
|
||||
{
|
||||
|
@ -1779,7 +1779,7 @@ XString(NSString* obj, NSMutableData *output)
|
|||
break;
|
||||
}
|
||||
}
|
||||
map = NSZoneMalloc(NSDefaultMallocZone(), len * sizeof(unichar));
|
||||
map = NSAllocateCollectable(sizeof(unichar) * len, 0);
|
||||
for (wpos = rpos = 0; rpos < end; rpos++)
|
||||
{
|
||||
c = base[rpos];
|
||||
|
@ -3151,7 +3151,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
|||
char *buffer;
|
||||
|
||||
len = [self readCountAt: &counter];
|
||||
buffer = NSZoneMalloc(NSDefaultMallocZone(), len+1);
|
||||
buffer = NSAllocateCollectable(len + 1, 0);
|
||||
[data getBytes: buffer range: NSMakeRange(counter, len)];
|
||||
buffer[len] = '\0';
|
||||
if (mutability == NSPropertyListMutableContainersAndLeaves)
|
||||
|
@ -3196,7 +3196,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
|||
unichar *buffer;
|
||||
|
||||
len = [self readCountAt: &counter];
|
||||
buffer = NSZoneMalloc(NSDefaultMallocZone(), sizeof(unichar)*len);
|
||||
buffer = NSAllocateCollectable(sizeof(unichar) * len, 0);
|
||||
[data getBytes: buffer range: NSMakeRange(counter, sizeof(unichar)*len)];
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
|
@ -3265,7 +3265,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
|||
id *objects;
|
||||
|
||||
len = [self readCountAt: &counter];
|
||||
objects = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id) * len);
|
||||
objects = NSAllocateCollectable(sizeof(id) * len, NSScannedOption);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
|
@ -3330,8 +3330,8 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
|||
id *values;
|
||||
|
||||
len = [self readCountAt: &counter];
|
||||
keys = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*len);
|
||||
values = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*len);
|
||||
keys = NSAllocateCollectable(sizeof(id) * len * 2, NSScannedOption);
|
||||
values = keys + len;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
int oid = [self readObjectIndexAt: &counter];
|
||||
|
@ -3359,7 +3359,6 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
|||
forKeys: keys
|
||||
count: len];
|
||||
}
|
||||
NSZoneFree(NSDefaultMallocZone(), values);
|
||||
NSZoneFree(NSDefaultMallocZone(), keys);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -157,7 +157,11 @@ initSerializerInfo(_NSSerializerInfo* info, NSMutableData *d, BOOL u)
|
|||
(*info->appImp)(d, appSel, &info->shouldUnique, 1);
|
||||
if (u)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GSIMapInitWithZoneAndCapacity(&info->map, GSScannedMallocZone(), 16);
|
||||
#else
|
||||
GSIMapInitWithZoneAndCapacity(&info->map, NSDefaultMallocZone(), 16);
|
||||
#endif
|
||||
info->count = 0;
|
||||
}
|
||||
}
|
||||
|
|
295
Source/NSZone.m
295
Source/NSZone.m
|
@ -405,10 +405,6 @@ static NSZone default_zone =
|
|||
default_check, default_lookup, default_stats, DEFBLOCK, @"default", 0
|
||||
};
|
||||
|
||||
/* Default zone. Name is hopelessly long so that no one will ever
|
||||
want to use it. ;) */
|
||||
NSZone* __nszone_private_hidden_default_zone = &default_zone;
|
||||
|
||||
/*
|
||||
* Lists of zones to be used to determine if a pointer is in a zone.
|
||||
*/
|
||||
|
@ -1739,6 +1735,17 @@ NSSetZoneName (NSZone *zone, NSString *name)
|
|||
[gnustep_global_lock unlock];
|
||||
}
|
||||
|
||||
void *
|
||||
NSAllocateCollectable(NSUInteger size, NSUInteger options)
|
||||
{
|
||||
return NSZoneCalloc(NSDefaultMallocZone(), 1, size);
|
||||
}
|
||||
|
||||
void *
|
||||
NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options)
|
||||
{
|
||||
return NSZoneRealloc(NSDefaultMallocZone(), ptr, size);
|
||||
}
|
||||
#else
|
||||
|
||||
#include <gc.h>
|
||||
|
@ -1752,14 +1759,290 @@ static NSZone default_zone =
|
|||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, @"default", 0
|
||||
};
|
||||
NSZone* __nszone_private_hidden_default_zone = &default_zone;
|
||||
|
||||
static NSZone atomic_zone =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, @"default", 0
|
||||
};
|
||||
NSZone* __nszone_private_hidden_atomic_zone = &atomic_zone;
|
||||
|
||||
static NSZone scanned_zone =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, @"default", 0
|
||||
};
|
||||
|
||||
void *
|
||||
NSAllocateCollectable(NSUInteger size, NSUInteger options)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (options & NSScannedOption)
|
||||
{
|
||||
if (options & NSCollectorDisabledOption)
|
||||
{
|
||||
ptr = (void*)GC_MALLOC_UNCOLLECTABLE(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = (void*)GC_MALLOC(size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (options & NSCollectorDisabledOption)
|
||||
{
|
||||
ptr = (void*)calloc(1, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options)
|
||||
{
|
||||
if (ptr == 0)
|
||||
{
|
||||
ptr = NSAllocateCollectable(size, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
void *tmp = NSAllocateCollectable(size, options);
|
||||
unsigned length = GC_size(ptr);
|
||||
|
||||
if (length > size)
|
||||
{
|
||||
length = size;
|
||||
}
|
||||
if (tmp != 0 && length > 0)
|
||||
{
|
||||
memcpy(tmp, ptr, length);
|
||||
}
|
||||
GC_free(ptr);
|
||||
ptr = tmp;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endif /* GS_WITH_GC */
|
||||
|
||||
|
||||
#ifdef IN_NSZONE_M
|
||||
#define GS_ZONE_SCOPE extern
|
||||
#define GS_ZONE_ATTR
|
||||
#else
|
||||
#define GS_ZONE_SCOPE static inline
|
||||
#define GS_ZONE_ATTR __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef GS_WITH_GC
|
||||
#define GS_WITH_GC 0
|
||||
#endif
|
||||
#if GS_WITH_GC
|
||||
|
||||
#include <gc.h>
|
||||
|
||||
|
||||
NSZone*
|
||||
NSCreateZone (size_t start, size_t gran, BOOL canFree)
|
||||
{
|
||||
return &default_zone;
|
||||
}
|
||||
|
||||
NSZone*
|
||||
NSDefaultMallocZone (void)
|
||||
{
|
||||
return &default_zone;
|
||||
}
|
||||
|
||||
NSZone*
|
||||
GSAtomicMallocZone (void)
|
||||
{
|
||||
return &atomic_zone;
|
||||
}
|
||||
|
||||
NSZone*
|
||||
GSScannedMallocZone (void)
|
||||
{
|
||||
return &scanned_zone;
|
||||
}
|
||||
|
||||
NSZone*
|
||||
NSZoneFromPointer (void *ptr)
|
||||
{
|
||||
return &default_zone;
|
||||
}
|
||||
|
||||
void*
|
||||
NSZoneMalloc (NSZone *zone, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (zone == GSAtomicMallocZone())
|
||||
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
||||
else if (zone == GSScannedMallocZone())
|
||||
ptr = (void*)GC_MALLOC(size);
|
||||
else
|
||||
ptr = (void*)malloc(size);
|
||||
|
||||
if (ptr == 0)
|
||||
ptr = GSOutOfMemory(size, YES);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void*
|
||||
NSZoneCalloc (NSZone *zone, size_t elems, size_t bytes)
|
||||
{
|
||||
size_t size = elems * bytes;
|
||||
void *ptr;
|
||||
|
||||
if (zone == &atomic_zone)
|
||||
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
||||
else if (zone == &scanned_zone)
|
||||
ptr = (void*)GC_MALLOC(size);
|
||||
else
|
||||
ptr = (void*)malloc(size);
|
||||
|
||||
if (ptr == 0)
|
||||
ptr = GSOutOfMemory(size, NO);
|
||||
memset(ptr, '\0', size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void*
|
||||
NSZoneRealloc (NSZone *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (GC_base(ptr) != 0)
|
||||
{
|
||||
ptr = GC_REALLOC(ptr, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = realloc(ptr, size);
|
||||
}
|
||||
if (ptr == 0)
|
||||
GSOutOfMemory(size, NO);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
NSRecycleZone (NSZone *zone)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSZoneFree (NSZone *zone, void *ptr)
|
||||
{
|
||||
if (GC_base(ptr) != 0)
|
||||
{
|
||||
GC_FREE(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NSSetZoneName (NSZone *zone, NSString *name)
|
||||
{
|
||||
}
|
||||
|
||||
NSString*
|
||||
NSZoneName (NSZone *zone)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSZoneCheck (NSZone *zone)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
struct
|
||||
NSZoneStats NSZoneStats (NSZone *zone)
|
||||
{
|
||||
struct NSZoneStats stats = { 0 };
|
||||
return stats;
|
||||
}
|
||||
|
||||
#else /* GS_WITH_GC */
|
||||
|
||||
NSZone*
|
||||
NSDefaultMallocZone (void)
|
||||
{
|
||||
return &default_zone;
|
||||
}
|
||||
|
||||
NSZone*
|
||||
GSAtomicMallocZone (void)
|
||||
{
|
||||
return &default_zone;
|
||||
}
|
||||
|
||||
NSZone*
|
||||
GSScannedMallocZone (void)
|
||||
{
|
||||
return &default_zone;
|
||||
}
|
||||
|
||||
void*
|
||||
NSZoneMalloc (NSZone *zone, size_t size)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->malloc)(zone, size);
|
||||
}
|
||||
|
||||
void*
|
||||
NSZoneRealloc (NSZone *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->realloc)(zone, ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
NSRecycleZone (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
(zone->recycle)(zone);
|
||||
}
|
||||
|
||||
void
|
||||
NSZoneFree (NSZone *zone, void *ptr)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
(zone->free)(zone, ptr);
|
||||
}
|
||||
|
||||
NSString*
|
||||
NSZoneName (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return zone->name;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSZoneCheck (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->check)(zone);
|
||||
}
|
||||
|
||||
struct NSZoneStats
|
||||
NSZoneStats (NSZone *zone)
|
||||
{
|
||||
if (!zone)
|
||||
zone = NSDefaultMallocZone();
|
||||
return (zone->stats)(zone);
|
||||
}
|
||||
|
||||
#endif /* GS_WITH_GC */
|
||||
|
|
Loading…
Reference in a new issue