mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
gc improvements
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28192 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
565c79f59d
commit
669d22f6d9
6 changed files with 486 additions and 476 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2009-04-10 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/GSPrivate.h:
|
||||||
|
* Source/NSString.m:
|
||||||
|
* Source/NSObject.m:
|
||||||
|
* Source/GSString.m:
|
||||||
|
* Source/NSZone.m:
|
||||||
|
GC tweaks ... Improve realloc when in gc world.
|
||||||
|
|
||||||
2009-04-03 Adam Fedor <fedor@gnu.org>
|
2009-04-03 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
* Source/NSObject.m: Revert previous patch (David to fix up later).
|
* Source/NSObject.m: Revert previous patch (David to fix up later).
|
||||||
|
|
|
@ -165,7 +165,7 @@ typedef union {
|
||||||
unsigned int _count;
|
unsigned int _count;
|
||||||
struct {
|
struct {
|
||||||
unsigned int wide: 1; // 16-bit characters in string?
|
unsigned int wide: 1; // 16-bit characters in string?
|
||||||
unsigned int free: 1; // Set if the instance owns the
|
unsigned int owned: 1; // Set if the instance owns the
|
||||||
// _contents buffer
|
// _contents buffer
|
||||||
unsigned int unused: 2;
|
unsigned int unused: 2;
|
||||||
unsigned int hash: 28;
|
unsigned int hash: 28;
|
||||||
|
@ -186,12 +186,12 @@ typedef union {
|
||||||
unsigned int _count;
|
unsigned int _count;
|
||||||
struct {
|
struct {
|
||||||
unsigned int wide: 1;
|
unsigned int wide: 1;
|
||||||
unsigned int free: 1;
|
unsigned int owned: 1;
|
||||||
unsigned int unused: 2;
|
unsigned int unused: 2;
|
||||||
unsigned int hash: 28;
|
unsigned int hash: 28;
|
||||||
} _flags;
|
} _flags;
|
||||||
NSZone *_zone;
|
|
||||||
unsigned int _capacity;
|
unsigned int _capacity;
|
||||||
|
NSZone *_zone;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -94,9 +94,6 @@ a single flag for the structure classes: free. This is set only if the
|
||||||
_contents buffer is guaranteed to remain valid at least until the instance
|
_contents buffer is guaranteed to remain valid at least until the instance
|
||||||
has been deallocated.
|
has been deallocated.
|
||||||
|
|
||||||
(It really should be named 'ownsContents' or something similar, but it's
|
|
||||||
'free' in GSMutableString, and the structures need to be interchangeable.)
|
|
||||||
|
|
||||||
Many optimizations, such as retaining instead of copying, and using pointers
|
Many optimizations, such as retaining instead of copying, and using pointers
|
||||||
to another strings _contents buffer, are valid only if this flag is set.
|
to another strings _contents buffer, are valid only if this flag is set.
|
||||||
|
|
||||||
|
@ -125,8 +122,8 @@ method which can be used to initialize that specific subclass.
|
||||||
|
|
||||||
GS*BufferString, concrete subclasses that store the data in an external
|
GS*BufferString, concrete subclasses that store the data in an external
|
||||||
(wrt. the instance itself) buffer. The buffer may or may not be owned
|
(wrt. the instance itself) buffer. The buffer may or may not be owned
|
||||||
by the instance; the 'free' flag indicates which. If it is set,
|
by the instance; the 'owned' flag indicates which. If it is set,
|
||||||
we need to free the buffer when we are deallocated.
|
we may need to free the buffer when we are deallocated.
|
||||||
*/
|
*/
|
||||||
@interface GSCBufferString : GSCString
|
@interface GSCBufferString : GSCString
|
||||||
{
|
{
|
||||||
|
@ -367,7 +364,7 @@ static void getCString_u(GSStr self, char *buffer, unsigned int maxLength,
|
||||||
* Remove any BOM and perform byte swapping if required.
|
* Remove any BOM and perform byte swapping if required.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
|
||||||
NSStringEncoding encoding)
|
NSStringEncoding encoding)
|
||||||
{
|
{
|
||||||
unsigned char *b = *bytes;
|
unsigned char *b = *bytes;
|
||||||
|
@ -379,17 +376,16 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
// Got a byte order marker ... remove it.
|
// Got a byte order marker ... remove it.
|
||||||
if (len == sizeof(unichar))
|
if (len == sizeof(unichar))
|
||||||
{
|
{
|
||||||
if (*shouldFree)
|
if (*owned)
|
||||||
{
|
{
|
||||||
NSZoneFree(NSZoneFromPointer(b), b);
|
NSZoneFree(NSZoneFromPointer(b), b);
|
||||||
|
*owned = NO;
|
||||||
}
|
}
|
||||||
*length = 0;
|
*length = 0;
|
||||||
*shouldFree = NO;
|
|
||||||
*bytes = 0;
|
*bytes = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSZone *z = NSZoneFromPointer(b);
|
|
||||||
unsigned char *from = b;
|
unsigned char *from = b;
|
||||||
unsigned char *to;
|
unsigned char *to;
|
||||||
unichar u;
|
unichar u;
|
||||||
|
@ -398,7 +394,11 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
len -= sizeof(unichar);
|
len -= sizeof(unichar);
|
||||||
memcpy(&u, from, sizeof(unichar));
|
memcpy(&u, from, sizeof(unichar));
|
||||||
from += sizeof(unichar);
|
from += sizeof(unichar);
|
||||||
to = NSZoneMalloc(z, len);
|
#if GS_WITH_GC
|
||||||
|
to = NSAllocateCollectable(len, 0);
|
||||||
|
#else
|
||||||
|
to = NSZoneMalloc(NSDefaultMallocZone(), len);
|
||||||
|
#endif
|
||||||
if (u == 0xFEFF)
|
if (u == 0xFEFF)
|
||||||
{
|
{
|
||||||
// Native byte order
|
// Native byte order
|
||||||
|
@ -414,13 +414,16 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
to[i+1] = from[i];
|
to[i+1] = from[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*shouldFree == YES)
|
if (*owned == YES)
|
||||||
{
|
{
|
||||||
NSZoneFree(z, b);
|
NSZoneFree(NSZoneFromPointer(b), b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*owned = YES;
|
||||||
}
|
}
|
||||||
*length = len;
|
*length = len;
|
||||||
*bytes = to;
|
*bytes = to;
|
||||||
*shouldFree = YES;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (encoding == NSUTF8StringEncoding && len >= 3
|
else if (encoding == NSUTF8StringEncoding && len >= 3
|
||||||
|
@ -428,32 +431,38 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
{
|
{
|
||||||
if (len == 3)
|
if (len == 3)
|
||||||
{
|
{
|
||||||
if (*shouldFree)
|
if (*owned)
|
||||||
{
|
{
|
||||||
NSZoneFree(NSZoneFromPointer(b), b);
|
NSZoneFree(NSZoneFromPointer(b), b);
|
||||||
|
*owned = NO;
|
||||||
}
|
}
|
||||||
*length = 0;
|
*length = 0;
|
||||||
*shouldFree = NO;
|
|
||||||
*bytes = 0;
|
*bytes = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSZone *z = NSZoneFromPointer(b);
|
|
||||||
unsigned char *from = b;
|
unsigned char *from = b;
|
||||||
unsigned char *to;
|
unsigned char *to;
|
||||||
|
|
||||||
// Got a byte order marker ... remove it.
|
// Got a byte order marker ... remove it.
|
||||||
len -= 3;
|
len -= 3;
|
||||||
from += 3;
|
from += 3;
|
||||||
to = NSZoneMalloc(z, len);
|
#if GS_WITH_GC
|
||||||
|
to = NSAllocateCollectable(len, 0);
|
||||||
|
#else
|
||||||
|
to = NSZoneMalloc(NSDefaultMallocZone(), len);
|
||||||
|
#endif
|
||||||
memcpy(to, from, len);
|
memcpy(to, from, len);
|
||||||
if (*shouldFree == YES)
|
if (*owned == YES)
|
||||||
{
|
{
|
||||||
NSZoneFree(z, b);
|
NSZoneFree(NSZoneFromPointer(b), b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*owned = YES;
|
||||||
}
|
}
|
||||||
*length = len;
|
*length = len;
|
||||||
*bytes = to;
|
*bytes = to;
|
||||||
*shouldFree = YES;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,7 +489,11 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
*/
|
*/
|
||||||
if (original == bytes)
|
if (original == bytes)
|
||||||
{
|
{
|
||||||
|
#if GS_WITH_GC
|
||||||
|
chars = NSAllocateCollectable(length, 0);
|
||||||
|
#else
|
||||||
chars = NSZoneMalloc(GSObjCZone(self), length);
|
chars = NSZoneMalloc(GSObjCZone(self), length);
|
||||||
|
#endif
|
||||||
memcpy(chars, bytes, length);
|
memcpy(chars, bytes, length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -585,7 +598,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.c = chars.c;
|
me->_contents.c = chars.c;
|
||||||
me->_count = length;
|
me->_count = length;
|
||||||
me->_flags.wide = 0;
|
me->_flags.wide = 0;
|
||||||
me->_flags.free = flag;
|
me->_flags.owned = flag;
|
||||||
return (id)me;
|
return (id)me;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,7 +646,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
||||||
me->_count = length;
|
me->_count = length;
|
||||||
me->_flags.wide = 0;
|
me->_flags.wide = 0;
|
||||||
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
while (length-- > 0)
|
while (length-- > 0)
|
||||||
{
|
{
|
||||||
me->_contents.c[length] = chars.u[length];
|
me->_contents.c[length] = chars.u[length];
|
||||||
|
@ -650,7 +663,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.u = chars.u;
|
me->_contents.u = chars.u;
|
||||||
me->_count = length;
|
me->_count = length;
|
||||||
me->_flags.wide = 1;
|
me->_flags.wide = 1;
|
||||||
me->_flags.free = flag;
|
me->_flags.owned = flag;
|
||||||
}
|
}
|
||||||
return (id)me;
|
return (id)me;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +724,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
len = [format length];
|
len = [format length];
|
||||||
if (len >= 1024)
|
if (len >= 1024)
|
||||||
{
|
{
|
||||||
fmt = objc_malloc((len+1)*sizeof(unichar));
|
fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
|
||||||
}
|
}
|
||||||
[format getCharacters: fmt];
|
[format getCharacters: fmt];
|
||||||
fmt[len] = '\0';
|
fmt[len] = '\0';
|
||||||
|
@ -726,11 +739,11 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
f._capacity = sizeof(buf);
|
f._capacity = sizeof(buf);
|
||||||
f._count = 0;
|
f._count = 0;
|
||||||
f._flags.wide = 0;
|
f._flags.wide = 0;
|
||||||
f._flags.free = 0;
|
f._flags.owned = 0;
|
||||||
GSPrivateFormat(&f, fmt, argList, locale);
|
GSPrivateFormat(&f, fmt, argList, locale);
|
||||||
if (fmt != fbuf)
|
if (fmt != fbuf)
|
||||||
{
|
{
|
||||||
objc_free(fmt);
|
NSZoneFree(NSDefaultMallocZone(), fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -748,7 +761,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
||||||
me->_count = f._count;
|
me->_count = f._count;
|
||||||
me->_flags.wide = 1;
|
me->_flags.wide = 1;
|
||||||
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
memcpy(me->_contents.u, f._contents.u, f._count*sizeof(unichar));
|
memcpy(me->_contents.u, f._contents.u, f._count*sizeof(unichar));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -758,7 +771,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
||||||
me->_count = f._count;
|
me->_count = f._count;
|
||||||
me->_flags.wide = 0;
|
me->_flags.wide = 0;
|
||||||
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
memcpy(me->_contents.c, f._contents.c, f._count);
|
memcpy(me->_contents.c, f._contents.c, f._count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,7 +779,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
* If the string had to grow beyond the initial buffer size, we must
|
* If the string had to grow beyond the initial buffer size, we must
|
||||||
* release any allocated memory.
|
* release any allocated memory.
|
||||||
*/
|
*/
|
||||||
if (f._flags.free == 1)
|
if (f._flags.owned == 1)
|
||||||
{
|
{
|
||||||
NSZoneFree(f._zone, f._contents.c);
|
NSZoneFree(f._zone, f._contents.c);
|
||||||
}
|
}
|
||||||
|
@ -805,7 +818,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
|
||||||
me->_count = length;
|
me->_count = length;
|
||||||
me->_flags.wide = 0;
|
me->_flags.wide = 0;
|
||||||
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
memcpy(me->_contents.c, ((GSStr)string)->_contents.c, length);
|
memcpy(me->_contents.c, ((GSStr)string)->_contents.c, length);
|
||||||
}
|
}
|
||||||
else if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
|
else if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
|
||||||
|
@ -820,7 +833,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
||||||
me->_count = length;
|
me->_count = length;
|
||||||
me->_flags.wide = 1;
|
me->_flags.wide = 1;
|
||||||
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
memcpy(me->_contents.u, ((GSStr)string)->_contents.u,
|
memcpy(me->_contents.u, ((GSStr)string)->_contents.u,
|
||||||
length*sizeof(unichar));
|
length*sizeof(unichar));
|
||||||
}
|
}
|
||||||
|
@ -835,7 +848,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *shouldFree,
|
||||||
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
|
||||||
me->_count = length;
|
me->_count = length;
|
||||||
me->_flags.wide = 1;
|
me->_flags.wide = 1;
|
||||||
me->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
[string getCharacters: me->_contents.u];
|
[string getCharacters: me->_contents.u];
|
||||||
}
|
}
|
||||||
return (id)me;
|
return (id)me;
|
||||||
|
@ -1607,7 +1620,7 @@ getCString_c(GSStr self, char *buffer, unsigned int maxLength,
|
||||||
o._contents.c = self->_contents.c;
|
o._contents.c = self->_contents.c;
|
||||||
GSStrWiden((GSStr)&o);
|
GSStrWiden((GSStr)&o);
|
||||||
getCString_u((GSStr)&o, buffer, maxLength, aRange, leftoverRange);
|
getCString_u((GSStr)&o, buffer, maxLength, aRange, leftoverRange);
|
||||||
if (o._flags.free == 1)
|
if (o._flags.owned == 1)
|
||||||
{
|
{
|
||||||
NSZoneFree(o._zone, o._contents.u);
|
NSZoneFree(o._zone, o._contents.u);
|
||||||
}
|
}
|
||||||
|
@ -2229,7 +2242,7 @@ static void GSStrMakeSpace(GSStr s, unsigned size)
|
||||||
{
|
{
|
||||||
s->_capacity = want;
|
s->_capacity = want;
|
||||||
}
|
}
|
||||||
if (s->_flags.free == 1)
|
if (s->_flags.owned == 1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we own the character buffer, we can simply realloc.
|
* If we own the character buffer, we can simply realloc.
|
||||||
|
@ -2287,7 +2300,7 @@ static void GSStrMakeSpace(GSStr s, unsigned size)
|
||||||
memcpy(s->_contents.c, tmp, s->_count);
|
memcpy(s->_contents.c, tmp, s->_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s->_flags.free = 1;
|
s->_flags.owned = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2341,13 +2354,13 @@ static void GSStrWiden(GSStr s)
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"widen of string failed"];
|
format: @"widen of string failed"];
|
||||||
}
|
}
|
||||||
if (s->_flags.free == 1)
|
if (s->_flags.owned == 1)
|
||||||
{
|
{
|
||||||
NSZoneFree(s->_zone, s->_contents.c);
|
NSZoneFree(s->_zone, s->_contents.c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s->_flags.free = 1;
|
s->_flags.owned = 1;
|
||||||
}
|
}
|
||||||
s->_contents.u = tmp;
|
s->_contents.u = tmp;
|
||||||
s->_flags.wide = 1;
|
s->_flags.wide = 1;
|
||||||
|
@ -2603,7 +2616,7 @@ substring_c(GSStr self, NSRange aRange)
|
||||||
o->_contents.c = self->_contents.c + aRange.location;
|
o->_contents.c = self->_contents.c + aRange.location;
|
||||||
o->_count = aRange.length;
|
o->_count = aRange.length;
|
||||||
o->_flags.wide = 0;
|
o->_flags.wide = 0;
|
||||||
o->_flags.free = 0;
|
o->_flags.owned = 0;
|
||||||
ASSIGN(o->_parent, (id)self);
|
ASSIGN(o->_parent, (id)self);
|
||||||
return AUTORELEASE((id)o);
|
return AUTORELEASE((id)o);
|
||||||
}
|
}
|
||||||
|
@ -2622,7 +2635,7 @@ substring_u(GSStr self, NSRange aRange)
|
||||||
o->_contents.u = self->_contents.u + aRange.location;
|
o->_contents.u = self->_contents.u + aRange.location;
|
||||||
o->_count = aRange.length;
|
o->_count = aRange.length;
|
||||||
o->_flags.wide = 1;
|
o->_flags.wide = 1;
|
||||||
o->_flags.free = 0;
|
o->_flags.owned = 0;
|
||||||
ASSIGN(o->_parent, (id)self);
|
ASSIGN(o->_parent, (id)self);
|
||||||
return AUTORELEASE((id)o);
|
return AUTORELEASE((id)o);
|
||||||
}
|
}
|
||||||
|
@ -3078,7 +3091,7 @@ agree, create a new GSCInlineString otherwise.
|
||||||
*/
|
*/
|
||||||
- (id) copyWithZone: (NSZone*)z
|
- (id) copyWithZone: (NSZone*)z
|
||||||
{
|
{
|
||||||
if (!_flags.free || NSShouldRetainWithZone(self, z) == NO)
|
if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
@defs(GSCInlineString)
|
@defs(GSCInlineString)
|
||||||
|
@ -3089,7 +3102,7 @@ agree, create a new GSCInlineString otherwise.
|
||||||
o->_count = _count;
|
o->_count = _count;
|
||||||
memcpy(o->_contents.c, _contents.c, _count);
|
memcpy(o->_contents.c, _contents.c, _count);
|
||||||
o->_flags.wide = 0;
|
o->_flags.wide = 0;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return (id)o;
|
return (id)o;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3105,7 +3118,7 @@ agree, create a new GSCInlineString otherwise.
|
||||||
@implementation GSCBufferString
|
@implementation GSCBufferString
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (_flags.free && _contents.c != 0)
|
if (_flags.owned && _contents.c != 0)
|
||||||
{
|
{
|
||||||
NSZoneFree(NSZoneFromPointer(_contents.c), _contents.c);
|
NSZoneFree(NSZoneFromPointer(_contents.c), _contents.c);
|
||||||
_contents.c = 0;
|
_contents.c = 0;
|
||||||
|
@ -3143,7 +3156,7 @@ agree, create a new GSCInlineString otherwise.
|
||||||
o->_count = _count;
|
o->_count = _count;
|
||||||
memcpy(o->_contents.c, _contents.c, _count);
|
memcpy(o->_contents.c, _contents.c, _count);
|
||||||
o->_flags.wide = 0;
|
o->_flags.wide = 0;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return (id)o;
|
return (id)o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3415,7 +3428,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
*/
|
*/
|
||||||
- (id) copyWithZone: (NSZone*)z
|
- (id) copyWithZone: (NSZone*)z
|
||||||
{
|
{
|
||||||
if (!_flags.free || NSShouldRetainWithZone(self, z) == NO)
|
if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
@defs(GSUnicodeInlineString)
|
@defs(GSUnicodeInlineString)
|
||||||
|
@ -3427,7 +3440,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
o->_count = _count;
|
o->_count = _count;
|
||||||
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
|
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
|
||||||
o->_flags.wide = 1;
|
o->_flags.wide = 1;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return (id)o;
|
return (id)o;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3443,7 +3456,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
@implementation GSUnicodeBufferString
|
@implementation GSUnicodeBufferString
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (_flags.free && _contents.u != 0)
|
if (_flags.owned && _contents.u != 0)
|
||||||
{
|
{
|
||||||
NSZoneFree(NSZoneFromPointer(_contents.u), _contents.u);
|
NSZoneFree(NSZoneFromPointer(_contents.u), _contents.u);
|
||||||
_contents.u = 0;
|
_contents.u = 0;
|
||||||
|
@ -3482,7 +3495,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
o->_count = _count;
|
o->_count = _count;
|
||||||
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
|
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
|
||||||
o->_flags.wide = 1;
|
o->_flags.wide = 1;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return (id)o;
|
return (id)o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3529,7 +3542,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
len = [format length];
|
len = [format length];
|
||||||
if (len >= 1024)
|
if (len >= 1024)
|
||||||
{
|
{
|
||||||
fmt = objc_malloc((len+1)*sizeof(unichar));
|
fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
|
||||||
}
|
}
|
||||||
[format getCharacters: fmt];
|
[format getCharacters: fmt];
|
||||||
fmt[len] = '\0';
|
fmt[len] = '\0';
|
||||||
|
@ -3550,7 +3563,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
_flags.hash = 0; // Invalidate the hash for this string.
|
_flags.hash = 0; // Invalidate the hash for this string.
|
||||||
if (fmt != buf)
|
if (fmt != buf)
|
||||||
{
|
{
|
||||||
objc_free(fmt);
|
NSZoneFree(NSDefaultMallocZone(), fmt);
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
@ -3612,7 +3625,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
o->_count = _count;
|
o->_count = _count;
|
||||||
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
|
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
|
||||||
o->_flags.wide = 1;
|
o->_flags.wide = 1;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return (id)o;
|
return (id)o;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3626,7 +3639,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
o->_count = _count;
|
o->_count = _count;
|
||||||
memcpy(o->_contents.c, _contents.c, _count);
|
memcpy(o->_contents.c, _contents.c, _count);
|
||||||
o->_flags.wide = 0;
|
o->_flags.wide = 0;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return (id)o;
|
return (id)o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3666,7 +3679,7 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
if (_contents.c != 0)
|
if (_contents.c != 0)
|
||||||
{
|
{
|
||||||
NSZoneFree(self->_zone, self->_contents.c);
|
NSZoneFree(self->_zone, self->_contents.c);
|
||||||
|
@ -3830,7 +3843,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
BOOL isLatin1 = NO;
|
BOOL isLatin1 = NO;
|
||||||
BOOL shouldFree = NO;
|
BOOL shouldFree = NO;
|
||||||
|
|
||||||
_flags.free = YES;
|
_flags.owned = YES;
|
||||||
#if GS_WITH_GC
|
#if GS_WITH_GC
|
||||||
_zone = GSAtomicMallocZone();
|
_zone = GSAtomicMallocZone();
|
||||||
#else
|
#else
|
||||||
|
@ -4007,7 +4020,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
#endif
|
#endif
|
||||||
_contents.c = NSZoneMalloc(_zone, capacity + 1);
|
_contents.c = NSZoneMalloc(_zone, capacity + 1);
|
||||||
_flags.wide = 0;
|
_flags.wide = 0;
|
||||||
_flags.free = 1;
|
_flags.owned = 1;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4048,7 +4061,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
len = [format length];
|
len = [format length];
|
||||||
if (len >= 1024)
|
if (len >= 1024)
|
||||||
{
|
{
|
||||||
fmt = objc_malloc((len+1)*sizeof(unichar));
|
fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
|
||||||
}
|
}
|
||||||
[format getCharacters: fmt];
|
[format getCharacters: fmt];
|
||||||
fmt[len] = '\0';
|
fmt[len] = '\0';
|
||||||
|
@ -4056,7 +4069,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
GSPrivateFormat((GSStr)self, fmt, argList, locale);
|
GSPrivateFormat((GSStr)self, fmt, argList, locale);
|
||||||
if (fmt != fbuf)
|
if (fmt != fbuf)
|
||||||
{
|
{
|
||||||
objc_free(fmt);
|
NSZoneFree(NSDefaultMallocZone(), fmt);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -4108,7 +4121,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
|
|
||||||
- (id) makeImmutableCopyOnFail: (BOOL)force
|
- (id) makeImmutableCopyOnFail: (BOOL)force
|
||||||
{
|
{
|
||||||
NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
GSDebugAllocationRemove(isa, self);
|
GSDebugAllocationRemove(isa, self);
|
||||||
#endif
|
#endif
|
||||||
|
@ -4404,7 +4417,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
memcpy(o->_contents.u, _contents.u + aRange.location,
|
memcpy(o->_contents.u, _contents.u + aRange.location,
|
||||||
aRange.length * sizeof(unichar));
|
aRange.length * sizeof(unichar));
|
||||||
o->_flags.wide = 1;
|
o->_flags.wide = 1;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return AUTORELEASE((id)o);
|
return AUTORELEASE((id)o);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4419,7 +4432,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
o->_count = aRange.length;
|
o->_count = aRange.length;
|
||||||
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
|
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
|
||||||
o->_flags.wide = 0;
|
o->_flags.wide = 0;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return AUTORELEASE((id)o);
|
return AUTORELEASE((id)o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4445,7 +4458,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
memcpy(o->_contents.u, _contents.u + aRange.location,
|
memcpy(o->_contents.u, _contents.u + aRange.location,
|
||||||
aRange.length * sizeof(unichar));
|
aRange.length * sizeof(unichar));
|
||||||
o->_flags.wide = 1;
|
o->_flags.wide = 1;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return AUTORELEASE((id)o);
|
return AUTORELEASE((id)o);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4460,7 +4473,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
|
||||||
o->_count = aRange.length;
|
o->_count = aRange.length;
|
||||||
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
|
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
|
||||||
o->_flags.wide = 0;
|
o->_flags.wide = 0;
|
||||||
o->_flags.free = 1; // Ignored on dealloc, but means we own buffer
|
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
|
||||||
return AUTORELEASE((id)o);
|
return AUTORELEASE((id)o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -542,8 +542,7 @@ NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone)
|
||||||
if (new != nil)
|
if (new != nil)
|
||||||
{
|
{
|
||||||
new->class_pointer = aClass;
|
new->class_pointer = aClass;
|
||||||
if (get_imp(aClass, finalize_sel) != finalize_imp
|
if (get_imp(aClass, finalize_sel) != finalize_imp)
|
||||||
&& __objc_responds_to(new, finalize_sel))
|
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
/*
|
/*
|
||||||
|
@ -817,7 +816,7 @@ GSDescriptionForClassMethod(pcl self, SEL aSel)
|
||||||
* in a deadlock in the garbage collecting library.
|
* in a deadlock in the garbage collecting library.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
warn_proc(char *msg, GC_word arg)
|
GSGarbageCollectorLog(char *msg, GC_word arg)
|
||||||
{
|
{
|
||||||
char buf[strlen(msg)+1024];
|
char buf[strlen(msg)+1024];
|
||||||
sprintf(buf, msg, (unsigned long)arg);
|
sprintf(buf, msg, (unsigned long)arg);
|
||||||
|
@ -841,7 +840,7 @@ warn_proc(char *msg, GC_word arg)
|
||||||
* This is not necessary on most platforms, but is good practice.
|
* This is not necessary on most platforms, but is good practice.
|
||||||
*/
|
*/
|
||||||
GC_init();
|
GC_init();
|
||||||
GC_set_warn_proc(warn_proc);
|
GC_set_warn_proc(GSGarbageCollectorLog);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
|
|
@ -1103,7 +1103,7 @@ handle_printf_atsign (FILE *stream,
|
||||||
len = [format length];
|
len = [format length];
|
||||||
if (len >= 1024)
|
if (len >= 1024)
|
||||||
{
|
{
|
||||||
fmt = objc_malloc((len+1)*sizeof(unichar));
|
fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
|
||||||
}
|
}
|
||||||
[format getCharacters: fmt range: ((NSRange){0, len})];
|
[format getCharacters: fmt range: ((NSRange){0, len})];
|
||||||
fmt[len] = '\0';
|
fmt[len] = '\0';
|
||||||
|
@ -1120,12 +1120,12 @@ handle_printf_atsign (FILE *stream,
|
||||||
#if HAVE_WIDE_PRINTF_FUNCTION
|
#if HAVE_WIDE_PRINTF_FUNCTION
|
||||||
f._flags.wide = 0;
|
f._flags.wide = 0;
|
||||||
#endif /* HAVE_WIDE_PRINTF_FUNCTION */
|
#endif /* HAVE_WIDE_PRINTF_FUNCTION */
|
||||||
f._flags.free = 0;
|
f._flags.owned = 0;
|
||||||
GSPrivateFormat(&f, fmt, argList, locale);
|
GSPrivateFormat(&f, fmt, argList, locale);
|
||||||
GSPrivateStrExternalize(&f);
|
GSPrivateStrExternalize(&f);
|
||||||
if (fmt != fbuf)
|
if (fmt != fbuf)
|
||||||
{
|
{
|
||||||
objc_free(fmt);
|
NSZoneFree(NSDefaultMallocZone(), fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1151,7 +1151,7 @@ handle_printf_atsign (FILE *stream,
|
||||||
* If the string had to grow beyond the initial buffer size, we must
|
* If the string had to grow beyond the initial buffer size, we must
|
||||||
* release any allocated memory.
|
* release any allocated memory.
|
||||||
*/
|
*/
|
||||||
if (f._flags.free == 1)
|
if (f._flags.owned == 1)
|
||||||
{
|
{
|
||||||
NSZoneFree(f._zone, f._contents.c);
|
NSZoneFree(f._zone, f._contents.c);
|
||||||
}
|
}
|
||||||
|
@ -2999,7 +2999,7 @@ handle_printf_atsign (FILE *stream,
|
||||||
*/
|
*/
|
||||||
if (len >= 4096)
|
if (len >= 4096)
|
||||||
{
|
{
|
||||||
u = objc_malloc(len * sizeof(unichar));
|
u = NSZoneMalloc(NSDefaultMallocZone(), len * sizeof(unichar));
|
||||||
}
|
}
|
||||||
[self getCharacters: u];
|
[self getCharacters: u];
|
||||||
if (flag == NO)
|
if (flag == NO)
|
||||||
|
@ -3021,7 +3021,7 @@ handle_printf_atsign (FILE *stream,
|
||||||
}
|
}
|
||||||
if (u != buf)
|
if (u != buf)
|
||||||
{
|
{
|
||||||
objc_free(u);
|
NSZoneFree(NSDefaultMallocZone(), u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
|
|
793
Source/NSZone.m
793
Source/NSZone.m
|
@ -96,6 +96,364 @@
|
||||||
#include "Foundation/NSZone.h"
|
#include "Foundation/NSZone.h"
|
||||||
#include "Foundation/NSLock.h"
|
#include "Foundation/NSLock.h"
|
||||||
|
|
||||||
|
/* Default zone functions for default zone. */
|
||||||
|
static void* default_malloc (NSZone *zone, size_t size);
|
||||||
|
static void* default_realloc (NSZone *zone, void *ptr, size_t size);
|
||||||
|
static void default_free (NSZone *zone, void *ptr);
|
||||||
|
static void default_recycle (NSZone *zone);
|
||||||
|
static BOOL default_check (NSZone *zone);
|
||||||
|
static BOOL default_lookup (NSZone *zone, void *ptr);
|
||||||
|
static struct NSZoneStats default_stats (NSZone *zone);
|
||||||
|
|
||||||
|
static void*
|
||||||
|
default_malloc (NSZone *zone, size_t size)
|
||||||
|
{
|
||||||
|
void *mem;
|
||||||
|
|
||||||
|
mem = objc_malloc(size);
|
||||||
|
if (mem == NULL)
|
||||||
|
[NSException raise: NSMallocException
|
||||||
|
format: @"Default zone has run out of memory"];
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
default_realloc (NSZone *zone, void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
void *mem;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
objc_free(ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (ptr == 0)
|
||||||
|
{
|
||||||
|
mem = objc_malloc(size);
|
||||||
|
if (mem == NULL)
|
||||||
|
[NSException raise: NSMallocException
|
||||||
|
format: @"Default zone has run out of memory"];
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
mem = objc_realloc(ptr, size);
|
||||||
|
if (mem == NULL)
|
||||||
|
[NSException raise: NSMallocException
|
||||||
|
format: @"Default zone has run out of memory"];
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
default_free (NSZone *zone, void *ptr)
|
||||||
|
{
|
||||||
|
objc_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
default_recycle (NSZone *zone)
|
||||||
|
{
|
||||||
|
/* Recycle the default zone? Thou hast got to be kiddin'. */
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"Trying to recycle default zone"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
default_check (NSZone *zone)
|
||||||
|
{
|
||||||
|
/* We can't check memory managed by objc_malloc(). */
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"No checking for default zone"];
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
default_lookup (NSZone *zone, void *ptr)
|
||||||
|
{
|
||||||
|
/* Assume all memory is in default zone. */
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct NSZoneStats
|
||||||
|
default_stats (NSZone *zone)
|
||||||
|
{
|
||||||
|
struct NSZoneStats dummy = {0,0,0,0,0};
|
||||||
|
|
||||||
|
/* We can't obtain statistics from the memory managed by objc_malloc(). */
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"No statistics for default zone"];
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSZone default_zone =
|
||||||
|
{
|
||||||
|
default_malloc, default_realloc, default_free, default_recycle,
|
||||||
|
default_check, default_lookup, default_stats, 0, @"default", 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For backward compatibility.
|
||||||
|
*/
|
||||||
|
NSZone *__nszone_private_hidden_default_zone = &default_zone;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets name of the given zone (useful for debugging and logging).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
NSSetZoneName (NSZone *zone, NSString *name)
|
||||||
|
{
|
||||||
|
if (!zone)
|
||||||
|
zone = NSDefaultMallocZone();
|
||||||
|
[gnustep_global_lock lock];
|
||||||
|
name = [name copy];
|
||||||
|
if (zone->name != nil)
|
||||||
|
[zone->name release];
|
||||||
|
zone->name = name;
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString*
|
||||||
|
NSZoneName (NSZone *zone)
|
||||||
|
{
|
||||||
|
if (!zone)
|
||||||
|
zone = NSDefaultMallocZone();
|
||||||
|
return zone->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GS_WITH_GC
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
#define GC_DEBUG 1
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
#include <gc.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy zones used with garbage collection.
|
||||||
|
* The 'atomic' zone is for memory that will be assumed not to contain
|
||||||
|
* pointers for garbage collection purposes.
|
||||||
|
*/
|
||||||
|
static NSZone atomic_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);
|
||||||
|
memset(ptr, '\0', size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = (void*)GC_MALLOC_IGNORE_OFF_PAGE(size);
|
||||||
|
memset(ptr, '\0', size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (options & NSCollectorDisabledOption)
|
||||||
|
{
|
||||||
|
ptr = (void*)calloc(1, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = (void*)GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
|
||||||
|
memset(ptr, '\0', size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options)
|
||||||
|
{
|
||||||
|
if (ptr == 0)
|
||||||
|
{
|
||||||
|
ptr = NSAllocateCollectable(size, options);
|
||||||
|
}
|
||||||
|
else if (size > 0 && GC_base(ptr) == 0)
|
||||||
|
{
|
||||||
|
/* This is not collectable memory, so we don't know how big it is.
|
||||||
|
* that means we must use realloc first, to get a known size, and
|
||||||
|
* then, if needed, allocate a chunk the right size and copy to it.
|
||||||
|
*/
|
||||||
|
ptr = realloc(ptr, size);
|
||||||
|
if (ptr != 0)
|
||||||
|
{
|
||||||
|
if ((options & NSScannedOption)
|
||||||
|
|| !(options & NSCollectorDisabledOption))
|
||||||
|
{
|
||||||
|
void *tmp = NSAllocateCollectable(size, options);
|
||||||
|
|
||||||
|
memcpy(tmp, ptr, size);
|
||||||
|
free(ptr);
|
||||||
|
ptr = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSZone*
|
||||||
|
NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
|
||||||
|
{
|
||||||
|
NSLog(@" *** Creating a zone while running GC is ignored.");
|
||||||
|
return &default_zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSZone*
|
||||||
|
NSDefaultMallocZone (void)
|
||||||
|
{
|
||||||
|
return &default_zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSZone*
|
||||||
|
GSAtomicMallocZone (void)
|
||||||
|
{
|
||||||
|
return &atomic_zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSZone*
|
||||||
|
NSZoneFromPointer (void *ptr)
|
||||||
|
{
|
||||||
|
return &default_zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSRecycleZone (NSZone *zone)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NSZoneCheck (NSZone *zone)
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct
|
||||||
|
NSZoneStats NSZoneStats (NSZone *zone)
|
||||||
|
{
|
||||||
|
struct NSZoneStats stats = { 0 };
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GSMakeWeakPointer(Class class, const char *iVarName)
|
||||||
|
{
|
||||||
|
class_ivar_set_gcinvisible(class, iVarName, YES);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
GSAssignZeroingWeakPointer(void **destination, void *source)
|
||||||
|
{
|
||||||
|
if (destination == 0)
|
||||||
|
{
|
||||||
|
return NO; // Bad destination pointer
|
||||||
|
}
|
||||||
|
if (*destination == source)
|
||||||
|
{
|
||||||
|
return YES; // Already assigned.
|
||||||
|
}
|
||||||
|
if (source != 0 && GC_base(source) == 0)
|
||||||
|
{
|
||||||
|
return NO; // Source is not garbage collectable.
|
||||||
|
}
|
||||||
|
if (*destination != 0)
|
||||||
|
{
|
||||||
|
GC_unregister_disappearing_link(destination);
|
||||||
|
}
|
||||||
|
*destination = source;
|
||||||
|
if (source != 0)
|
||||||
|
{
|
||||||
|
GC_general_register_disappearing_link(destination, source);
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
NSZoneMalloc (NSZone *zone, NSUInteger size)
|
||||||
|
{
|
||||||
|
return NSZoneCalloc(zone, 1, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
NSZoneCalloc (NSZone *zone, NSUInteger elems, NSUInteger bytes)
|
||||||
|
{
|
||||||
|
size_t size = elems * bytes;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (zone == &atomic_zone)
|
||||||
|
{
|
||||||
|
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
||||||
|
memset(ptr, '\0', size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = (void*)malloc(size);
|
||||||
|
if (ptr == 0)
|
||||||
|
{
|
||||||
|
ptr = GSOutOfMemory(size, NO);
|
||||||
|
}
|
||||||
|
if (ptr != 0)
|
||||||
|
{
|
||||||
|
memset(ptr, '\0', size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
NSZoneRealloc (NSZone *zone, void *ptr, NSUInteger size)
|
||||||
|
{
|
||||||
|
if (GC_base(ptr) != 0)
|
||||||
|
{
|
||||||
|
ptr = GC_REALLOC(ptr, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = realloc(ptr, size);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSZoneFree (NSZone *zone, void *ptr)
|
||||||
|
{
|
||||||
|
if (GC_base(ptr) != 0)
|
||||||
|
{
|
||||||
|
GC_FREE(ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* GS_WITH_GC */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to get more memory - the normal process has failed.
|
* Try to get more memory - the normal process has failed.
|
||||||
* If we can't do anything, just return a null pointer.
|
* If we can't do anything, just return a null pointer.
|
||||||
|
@ -109,7 +467,6 @@ GSOutOfMemory(NSUInteger size, BOOL retry)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GS_WITH_GC == 0
|
|
||||||
|
|
||||||
/* Alignment */
|
/* Alignment */
|
||||||
#ifdef ALIGN
|
#ifdef ALIGN
|
||||||
|
@ -355,17 +712,6 @@ struct _nfree_zone_struct
|
||||||
size_t use;
|
size_t use;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Default zone functions for default zone. */
|
|
||||||
static void* default_malloc (NSZone *zone, size_t size);
|
|
||||||
static void* default_realloc (NSZone *zone, void *ptr, size_t size);
|
|
||||||
static void default_free (NSZone *zone, void *ptr);
|
|
||||||
static void default_recycle (NSZone *zone);
|
|
||||||
static BOOL default_check (NSZone *zone);
|
|
||||||
static BOOL default_lookup (NSZone *zone, void *ptr);
|
|
||||||
static struct NSZoneStats default_stats (NSZone *zone);
|
|
||||||
|
|
||||||
/* Memory management functions for freeable zones. */
|
/* Memory management functions for freeable zones. */
|
||||||
static void* fmalloc (NSZone *zone, size_t size);
|
static void* fmalloc (NSZone *zone, size_t size);
|
||||||
static void* frealloc (NSZone *zone, void *ptr, size_t size);
|
static void* frealloc (NSZone *zone, void *ptr, size_t size);
|
||||||
|
@ -399,49 +745,6 @@ static void rffree (NSZone *zone, void *ptr);
|
||||||
static void rnfree (NSZone *zone, void *ptr);
|
static void rnfree (NSZone *zone, void *ptr);
|
||||||
|
|
||||||
|
|
||||||
static NSZone default_zone =
|
|
||||||
{
|
|
||||||
default_malloc, default_realloc, default_free, default_recycle,
|
|
||||||
default_check, default_lookup, default_stats, DEFBLOCK, @"default", 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For backward compatibility.
|
|
||||||
*/
|
|
||||||
NSZone *__nszone_private_hidden_default_zone = &default_zone;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lists of zones to be used to determine if a pointer is in a zone.
|
|
||||||
*/
|
|
||||||
static NSZone *zone_list = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches and finds the zone ptr was allocated from. The speed depends
|
|
||||||
* upon the number of zones and their size.
|
|
||||||
*/
|
|
||||||
GS_DECLARE NSZone*
|
|
||||||
NSZoneFromPointer(void *ptr)
|
|
||||||
{
|
|
||||||
NSZone *zone;
|
|
||||||
|
|
||||||
if (ptr == 0) return 0;
|
|
||||||
if (zone_list == 0) return &default_zone;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See if we can find the zone in our list of all zones.
|
|
||||||
*/
|
|
||||||
[gnustep_global_lock lock];
|
|
||||||
for (zone = zone_list; zone != 0; zone = zone->next)
|
|
||||||
{
|
|
||||||
if ((zone->lookup)(zone, ptr) == YES)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[gnustep_global_lock unlock];
|
|
||||||
return (zone == 0) ? &default_zone : zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
destroy_zone(NSZone* zone)
|
destroy_zone(NSZone* zone)
|
||||||
{
|
{
|
||||||
|
@ -459,84 +762,6 @@ destroy_zone(NSZone* zone)
|
||||||
objc_free((void*)zone);
|
objc_free((void*)zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
default_malloc (NSZone *zone, size_t size)
|
|
||||||
{
|
|
||||||
void *mem;
|
|
||||||
|
|
||||||
mem = objc_malloc(size);
|
|
||||||
if (mem == NULL)
|
|
||||||
[NSException raise: NSMallocException
|
|
||||||
format: @"Default zone has run out of memory"];
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
default_realloc (NSZone *zone, void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
void *mem;
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
objc_free(ptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (ptr == 0)
|
|
||||||
{
|
|
||||||
mem = objc_malloc(size);
|
|
||||||
if (mem == NULL)
|
|
||||||
[NSException raise: NSMallocException
|
|
||||||
format: @"Default zone has run out of memory"];
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
mem = objc_realloc(ptr, size);
|
|
||||||
if (mem == NULL)
|
|
||||||
[NSException raise: NSMallocException
|
|
||||||
format: @"Default zone has run out of memory"];
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
default_free (NSZone *zone, void *ptr)
|
|
||||||
{
|
|
||||||
objc_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
default_recycle (NSZone *zone)
|
|
||||||
{
|
|
||||||
/* Recycle the default zone? Thou hast got to be kiddin'. */
|
|
||||||
[NSException raise: NSGenericException
|
|
||||||
format: @"Trying to recycle default zone"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
default_check (NSZone *zone)
|
|
||||||
{
|
|
||||||
/* We can't check memory managed by objc_malloc(). */
|
|
||||||
[NSException raise: NSGenericException
|
|
||||||
format: @"No checking for default zone"];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
default_lookup (NSZone *zone, void *ptr)
|
|
||||||
{
|
|
||||||
/* Assume all memory is in default zone. */
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct NSZoneStats
|
|
||||||
default_stats (NSZone *zone)
|
|
||||||
{
|
|
||||||
struct NSZoneStats dummy = {0,0,0,0,0};
|
|
||||||
|
|
||||||
/* We can't obtain statistics from the memory managed by objc_malloc(). */
|
|
||||||
[NSException raise: NSGenericException
|
|
||||||
format: @"No statistics for default zone"];
|
|
||||||
return dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search the buffer to see if there is any memory chunks large enough
|
/* Search the buffer to see if there is any memory chunks large enough
|
||||||
to satisfy request using first fit. If the memory chunk found has
|
to satisfy request using first fit. If the memory chunk found has
|
||||||
a size exactly equal to the one requested, remove it from the buffer
|
a size exactly equal to the one requested, remove it from the buffer
|
||||||
|
@ -1589,6 +1814,38 @@ rrealloc (NSZone *zone, void *ptr, size_t size)
|
||||||
|
|
||||||
static void rnfree (NSZone *zone, void *ptr);
|
static void rnfree (NSZone *zone, void *ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lists of zones to be used to determine if a pointer is in a zone.
|
||||||
|
*/
|
||||||
|
static NSZone *zone_list = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches and finds the zone ptr was allocated from. The speed depends
|
||||||
|
* upon the number of zones and their size.
|
||||||
|
*/
|
||||||
|
GS_DECLARE NSZone*
|
||||||
|
NSZoneFromPointer(void *ptr)
|
||||||
|
{
|
||||||
|
NSZone *zone;
|
||||||
|
|
||||||
|
if (ptr == 0) return 0;
|
||||||
|
if (zone_list == 0) return &default_zone;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if we can find the zone in our list of all zones.
|
||||||
|
*/
|
||||||
|
[gnustep_global_lock lock];
|
||||||
|
for (zone = zone_list; zone != 0; zone = zone->next)
|
||||||
|
{
|
||||||
|
if ((zone->lookup)(zone, ptr) == YES)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
return (zone == 0) ? &default_zone : zone;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new zone of start bytes, which will grow and shrink by
|
* Creates a new zone of start bytes, which will grow and shrink by
|
||||||
* granularity bytes. If canFree is 0, memory in zone is allocated but
|
* granularity bytes. If canFree is 0, memory in zone is allocated but
|
||||||
|
@ -1724,22 +1981,6 @@ NSZoneCalloc (NSZone *zone, NSUInteger elems, NSUInteger bytes)
|
||||||
return memset(NSZoneMalloc(zone, elems*bytes), 0, elems*bytes);
|
return memset(NSZoneMalloc(zone, elems*bytes), 0, elems*bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets name of the given zone (useful for debugging and logging).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
NSSetZoneName (NSZone *zone, NSString *name)
|
|
||||||
{
|
|
||||||
if (!zone)
|
|
||||||
zone = NSDefaultMallocZone();
|
|
||||||
[gnustep_global_lock lock];
|
|
||||||
name = [name copy];
|
|
||||||
if (zone->name != nil)
|
|
||||||
[zone->name release];
|
|
||||||
zone->name = name;
|
|
||||||
[gnustep_global_lock unlock];
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
NSAllocateCollectable(NSUInteger size, NSUInteger options)
|
NSAllocateCollectable(NSUInteger size, NSUInteger options)
|
||||||
{
|
{
|
||||||
|
@ -1749,252 +1990,8 @@ NSAllocateCollectable(NSUInteger size, NSUInteger options)
|
||||||
void *
|
void *
|
||||||
NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options)
|
NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options)
|
||||||
{
|
{
|
||||||
return NSZoneRealloc(NSDefaultMallocZone(), ptr, size);
|
return NSZoneRealloc(0, ptr, size);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
#define GC_DEBUG 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gc.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dummy zones used with garbage collection.
|
|
||||||
* The 'atomic' zone is for memory that will be assumed not to contain
|
|
||||||
* pointers for garbage collection purposes.
|
|
||||||
*/
|
|
||||||
static NSZone default_zone =
|
|
||||||
{
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, @"default", 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static NSZone atomic_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);
|
|
||||||
memset(ptr, '\0', size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = (void*)GC_MALLOC_IGNORE_OFF_PAGE(size);
|
|
||||||
memset(ptr, '\0', size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (options & NSCollectorDisabledOption)
|
|
||||||
{
|
|
||||||
ptr = (void*)calloc(1, size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = (void*)GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
|
|
||||||
memset(ptr, '\0', 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
|
|
||||||
|
|
||||||
#if GS_WITH_GC
|
|
||||||
|
|
||||||
NSZone*
|
|
||||||
NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree)
|
|
||||||
{
|
|
||||||
return &default_zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSZone*
|
|
||||||
NSDefaultMallocZone (void)
|
|
||||||
{
|
|
||||||
return &default_zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSZone*
|
|
||||||
GSAtomicMallocZone (void)
|
|
||||||
{
|
|
||||||
return &atomic_zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSZone*
|
|
||||||
NSZoneFromPointer (void *ptr)
|
|
||||||
{
|
|
||||||
return &default_zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSRecycleZone (NSZone *zone)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GSMakeWeakPointer(Class class, const char *iVarName)
|
|
||||||
{
|
|
||||||
class_ivar_set_gcinvisible(class, iVarName, YES);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include <gc.h>
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
GSAssignZeroingWeakPointer(void **destination, void *source)
|
|
||||||
{
|
|
||||||
if (destination == 0)
|
|
||||||
{
|
|
||||||
return NO; // Bad destination pointer
|
|
||||||
}
|
|
||||||
if (*destination == source)
|
|
||||||
{
|
|
||||||
return YES; // Already assigned.
|
|
||||||
}
|
|
||||||
if (source != 0 && GC_base(source) == 0)
|
|
||||||
{
|
|
||||||
return NO; // Source is not garbage collectable.
|
|
||||||
}
|
|
||||||
if (*destination != 0)
|
|
||||||
{
|
|
||||||
GC_unregister_disappearing_link(destination);
|
|
||||||
}
|
|
||||||
*destination = source;
|
|
||||||
if (source != 0)
|
|
||||||
{
|
|
||||||
GC_general_register_disappearing_link(destination, source);
|
|
||||||
}
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
NSZoneMalloc (NSZone *zone, NSUInteger size)
|
|
||||||
{
|
|
||||||
return NSZoneCalloc(zone, 1, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
NSZoneCalloc (NSZone *zone, NSUInteger elems, NSUInteger bytes)
|
|
||||||
{
|
|
||||||
size_t size = elems * bytes;
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
if (zone == &atomic_zone)
|
|
||||||
{
|
|
||||||
ptr = (void*)GC_MALLOC_ATOMIC(size);
|
|
||||||
memset(ptr, '\0', size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = (void*)malloc(size);
|
|
||||||
if (ptr == 0)
|
|
||||||
{
|
|
||||||
ptr = GSOutOfMemory(size, NO);
|
|
||||||
}
|
|
||||||
if (ptr != 0)
|
|
||||||
{
|
|
||||||
memset(ptr, '\0', size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
NSZoneRealloc (NSZone *zone, void *ptr, NSUInteger size)
|
|
||||||
{
|
|
||||||
if (GC_base(ptr) != 0)
|
|
||||||
{
|
|
||||||
ptr = GC_REALLOC(ptr, size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = realloc(ptr, size);
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSZoneFree (NSZone *zone, void *ptr)
|
|
||||||
{
|
|
||||||
if (GC_base(ptr) != 0)
|
|
||||||
{
|
|
||||||
GC_FREE(ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* GS_WITH_GC */
|
|
||||||
|
|
||||||
NSZone*
|
NSZone*
|
||||||
NSDefaultMallocZone (void)
|
NSDefaultMallocZone (void)
|
||||||
|
@ -2057,14 +2054,6 @@ NSZoneFree (NSZone *zone, void *ptr)
|
||||||
(zone->free)(zone, ptr);
|
(zone->free)(zone, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString*
|
|
||||||
NSZoneName (NSZone *zone)
|
|
||||||
{
|
|
||||||
if (!zone)
|
|
||||||
zone = NSDefaultMallocZone();
|
|
||||||
return zone->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
NSZoneCheck (NSZone *zone)
|
NSZoneCheck (NSZone *zone)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue