diff --git a/Source/NSArray.m b/Source/NSArray.m index e991f4d80..c493813e2 100644 --- a/Source/NSArray.m +++ b/Source/NSArray.m @@ -39,6 +39,8 @@ #include +@class NSGMutableCString; + @class NSArrayEnumerator; @class NSArrayEnumeratorReverse; @@ -601,7 +603,8 @@ static Class NSMutableArray_concrete_class; { NSMutableString *result; - result = [NSMutableString stringWithCapacity: 20*[self count]]; + result = [[[NSGMutableCString alloc] initWithCapacity: 20*[self count]] + autorelease]; [self descriptionWithLocale: locale indent: level to: (id)result]; diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 969a4b2bf..e0f56a3ef 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -39,6 +39,8 @@ @implementation NSDictionary +@class NSGMutableCString; + @class NSGDictionary; @class NSGMutableDictionary; @@ -503,10 +505,11 @@ compareIt(id o1, id o2, void* context) - (NSString*) descriptionInStringsFileFormat { - NSMutableString *result = [NSMutableString stringWithCapacity: 1024]; + NSMutableString *result; NSEnumerator *enumerator; id key; + result = [[[NSGMutableCString alloc] initWithCapacity: 1024] autorelease]; enumerator = [self keyEnumerator]; while ((key = [enumerator nextObject]) != nil) { @@ -536,7 +539,8 @@ compareIt(id o1, id o2, void* context) { NSMutableString *result; - result = [NSMutableString stringWithCapacity: 20*[self count]]; + result = [[[NSGMutableCString alloc] initWithCapacity: 20*[self count]] + autorelease]; [self descriptionWithLocale: locale indent: level to: (id)result]; diff --git a/Source/NSGCString.m b/Source/NSGCString.m index 2c004f07c..38ff4e7f8 100644 --- a/Source/NSGCString.m +++ b/Source/NSGCString.m @@ -74,6 +74,10 @@ static SEL msInitSel = @selector(initWithCapacity:); static IMP csInitImp; /* designated initialiser for cString */ static IMP msInitImp; /* designated initialiser for mutable */ +@interface NSGMutableCString (GNUDescription) +- (char*) _extendBy: (unsigned)len; +@end + @implementation NSGCString + (void) initialize @@ -539,6 +543,9 @@ static IMP msInitImp; /* designated initialiser for mutable */ - (void) descriptionTo: (id)output { + if (output == nil) + return; + if (_count == 0) { [output appendString: @"\"\""]; @@ -586,11 +593,21 @@ static IMP msInitImp; /* designated initialiser for mutable */ if (needQuote || length != _count) { - NSZone *z = fastZone(self); - char *buf = NSZoneMalloc(z, length+3); - char *ptr = buf; - NSString *result; + Class c = fastClass(output); + NSZone *z = NSDefaultMallocZone(); + char *buf; + char *ptr; + length += 2; + if (c == _fastCls._NSGMutableCString) + { + buf = [(NSGMutableCString*)output _extendBy: length]; + } + else + { + buf = NSZoneMalloc(z, length+1); + } + ptr = buf; *ptr++ = '"'; for (i = 0; i < _count; i++) { @@ -626,10 +643,15 @@ static IMP msInitImp; /* designated initialiser for mutable */ } *ptr++ = '"'; *ptr = '\0'; - result = [[_fastCls._NSGCString allocWithZone: NSDefaultMallocZone()] - initWithCStringNoCopy: buf length: length+2 fromZone: z]; - [output appendString: result]; - [result release]; + if (c != _fastCls._NSGMutableCString) + { + NSString *result; + + result = [[_fastCls._NSGCString allocWithZone: z] + initWithCStringNoCopy: buf length: length fromZone: z]; + [output appendString: result]; + [result release]; + } } else { @@ -757,6 +779,14 @@ typedef struct { @defs(NSGMutableCString) } NSGMutableCStringStruct; +static inline void +stringGrowBy(NSGMutableCStringStruct *self, unsigned size) +{ + self->_capacity = MAX(self->_capacity*2, self->_count+size+1); + self->_contents_chars + = NSZoneRealloc(self->_zone, self->_contents_chars, self->_capacity); +} + static inline void stringIncrementCountAndMakeHoleAt(NSGMutableCStringStruct *self, int index, int size) @@ -939,10 +969,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self, unsigned c = [aString cStringLength]; char save; if (_count + c >= _capacity) - { - _capacity = MAX(_capacity*2, _count+c+1); - _contents_chars = NSZoneRealloc(_zone, _contents_chars, _capacity); - } + stringGrowBy((NSGMutableCStringStruct *)self, c); stringIncrementCountAndMakeHoleAt((NSGMutableCStringStruct*)self, index, c); save = _contents_chars[index+c]; // getCString will put a nul here. [aString getCString: _contents_chars + index]; @@ -961,11 +988,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self, unsigned l = other->_count; if (_count + l > _capacity) - { - _capacity = MAX(_capacity*2, _count+l); - _contents_chars = - NSZoneRealloc(fastZone(self), _contents_chars, _capacity); - } + stringGrowBy((NSGMutableCStringStruct *)self, l); memcpy(_contents_chars + _count, other->_contents_chars, l); _count += l; _hash = 0; @@ -974,11 +997,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self, { unsigned l = [aString cStringLength]; if (_count + l >= _capacity) - { - _capacity = MAX(_capacity*2, _count+l+1); - _contents_chars = - NSZoneRealloc(fastZone(self), _contents_chars, _capacity); - } + stringGrowBy((NSGMutableCStringStruct *)self, l); [aString getCString: _contents_chars + _count]; _count += l; _hash = 0; @@ -1061,6 +1080,16 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self, stringDecrementCountAndFillHoleAt((NSGMutableCStringStruct*)self, index, 1); } +- (char*) _extendBy: (unsigned)len +{ + char *ptr; + + stringGrowBy((NSGMutableCStringStruct *)self, len); + ptr = _contents_chars + _count; + _count += len; + _hash = 0; + return ptr; +} @end @implementation NXConstantString diff --git a/Source/NSSerializer.m b/Source/NSSerializer.m index 6619eeea1..436d08071 100644 --- a/Source/NSSerializer.m +++ b/Source/NSSerializer.m @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -32,10 +31,10 @@ #include #include -@class NSGCString; -@class NSGString; -@class NSGArray; -@class NSGMutableArray; +#include +#include +#include + @class NSGDictionary; @class NSGMutableDictionary; @class NSDataMalloc; @@ -82,6 +81,14 @@ static char st_dict = (char)ST_DICT; static char st_mdict = (char)ST_MDICT; static char st_data = (char)ST_DATA; +typedef struct { + @defs(NSGArray) +} NSGArrayStruct; + +typedef struct { + @defs(NSGMutableArray) +} NSGMutableArrayStruct; + /* @@ -339,11 +346,13 @@ static BOOL shouldBeCompact = NO; /* * Variables to cache class information. */ -static Class GArrayClass = 0; -static Class GMutableArrayClass = 0; -static Class GDataClass = 0; -static Class GDictionaryClass = 0; -static Class GMutableDictionaryClass = 0; +static Class IACls = 0; /* Immutable Array */ +static Class MACls = 0; /* Mutable Array */ +static Class DCls = 0; /* Data */ +static Class IDCls = 0; /* Immutable Dictionary */ +static Class MDCls = 0; /* Mutable Dictionary */ +static Class USCls = 0; /* Unicode String */ +static Class CSCls = 0; /* C String */ typedef struct { NSData *data; @@ -355,8 +364,22 @@ typedef struct { FastArray_t array; } _NSDeserializerInfo; -static SEL debSel = @selector(deserializeBytes:length:atCursor:); -static SEL deiSel = @selector(deserializeIntAtCursor:); +static SEL debSel = @selector(deserializeBytes:length:atCursor:); +static SEL deiSel = @selector(deserializeIntAtCursor:); +static SEL csInitSel = @selector(initWithCStringNoCopy:length:fromZone:); +static SEL usInitSel = @selector(initWithCharactersNoCopy:length:fromZone:); +static SEL dInitSel = @selector(initWithBytesNoCopy:length:fromZone:); +static SEL iaInitSel = @selector(initWithObjects:count:); +static SEL maInitSel = @selector(initWithObjects:count:); +static SEL idInitSel = @selector(initWithObjects:forKeys:count:); +static SEL mdInitSel = @selector(initWithObjects:forKeys:count:); +static IMP csInitImp; +static IMP usInitImp; +static IMP dInitImp; +static IMP iaInitImp; +static IMP maInitImp; +static IMP idInitImp; +static IMP mdInitImp; static void initDeserializerInfo(_NSDeserializerInfo* info, NSData *d, unsigned *c, BOOL m) @@ -400,10 +423,8 @@ deserializeFromInfo(_NSDeserializerInfo* info) char *b = objc_malloc(size); (*info->debImp)(info->data, debSel, b, size, info->cursor); - s = [_fastCls._NSGCString allocWithZone: NSDefaultMallocZone()]; - s = [s initWithCStringNoCopy: b - length: size-1 - fromZone: NSDefaultMallocZone()]; + s = (NSGCString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone()); + s = (*csInitImp)(s, csInitSel, b, size-1, NSDefaultMallocZone()); if (info->didUnique) FastArrayAddItem(&info->array, (FastArrayItem)s); return s; @@ -415,10 +436,8 @@ deserializeFromInfo(_NSDeserializerInfo* info) unichar *b = objc_malloc(size*2); (*info->debImp)(info->data, debSel, b, size*2, info->cursor); - s = [_fastCls._NSGString allocWithZone: NSDefaultMallocZone()]; - s = [s initWithCharactersNoCopy: b - length: size - fromZone: NSDefaultMallocZone()]; + s = (NSGString*)NSAllocateObject(USCls, 0, NSDefaultMallocZone()); + s = (*usInitImp)(s, usInitSel, b, size, NSDefaultMallocZone()); if (info->didUnique) FastArrayAddItem(&info->array, (FastArrayItem)s); return s; @@ -427,9 +446,9 @@ deserializeFromInfo(_NSDeserializerInfo* info) case ST_ARRAY: case ST_MARRAY: { - id objects[size]; - id a; - int i; + id objects[size]; + id a; + unsigned i; for (i = 0; i < size; i++) { @@ -440,24 +459,24 @@ deserializeFromInfo(_NSDeserializerInfo* info) { [objects[--i] release]; } + objc_free(objects); return nil; } } if (code == ST_MARRAY || info->mutable) { - a = [GMutableArrayClass allocWithZone: NSDefaultMallocZone()]; - a = [a initWithObjects: objects - count: size]; + a = NSAllocateObject(MACls, 0, NSDefaultMallocZone()); + a = (*maInitImp)(a, maInitSel, objects, size); } else { - a = [GArrayClass allocWithZone: NSDefaultMallocZone()]; - a = [a initWithObjects: objects - count: size]; + a = NSAllocateObject(IACls, 0, NSDefaultMallocZone()); + a = (*iaInitImp)(a, iaInitSel, objects, size); } - while (i > 0) + + for (i = 0; i < size; i++) { - [objects[--i] release]; + [objects[i] release]; } return a; } @@ -496,21 +515,17 @@ deserializeFromInfo(_NSDeserializerInfo* info) } if (code == ST_MDICT || info->mutable) { - d=[GMutableDictionaryClass allocWithZone: NSDefaultMallocZone()]; - d = [d initWithObjects: objects - forKeys: keys - count: size]; + d = NSAllocateObject(MDCls, 0, NSDefaultMallocZone()); + d = (*mdInitImp)(d, mdInitSel, objects, keys, size); } else { - d = [GDictionaryClass allocWithZone: NSDefaultMallocZone()]; - d = [d initWithObjects: objects - forKeys: keys - count: size]; + d = NSAllocateObject(IDCls, 0, NSDefaultMallocZone()); + d = (*idInitImp)(d, idInitSel, objects, keys, size); } - while (i > 0) + for (i = 0; i < size; i++) { - [keys[--i] release]; + [keys[i] release]; [objects[i] release]; } return d; @@ -522,10 +537,8 @@ deserializeFromInfo(_NSDeserializerInfo* info) void *b = objc_malloc(size); (*info->debImp)(info->data, debSel, b, size, info->cursor); - d = [GDataClass allocWithZone: NSDefaultMallocZone()]; - d = [d initWithBytesNoCopy: b - length: size - fromZone: NSDefaultMallocZone()]; + d = (NSData*)NSAllocateObject(DCls, 0, NSDefaultMallocZone()); + d = (*dInitImp)(d, dInitSel, b, size, NSDefaultMallocZone()); return d; } @@ -605,11 +618,20 @@ deserializeFromInfo(_NSDeserializerInfo* info) { if (self == [NSDeserializer class]) { - GArrayClass = [NSGArray class]; - GMutableArrayClass = [NSGMutableArray class]; - GDataClass = [NSDataMalloc class]; - GDictionaryClass = [NSGDictionary class]; - GMutableDictionaryClass = [NSGMutableDictionary class]; + IACls = [NSGArray class]; + MACls = [NSGMutableArray class]; + DCls = [NSDataMalloc class]; + IDCls = [NSGDictionary class]; + MDCls = [NSGMutableDictionary class]; + USCls = [NSGString class]; + CSCls = [NSGCString class]; + csInitImp = [CSCls instanceMethodForSelector: csInitSel]; + usInitImp = [USCls instanceMethodForSelector: usInitSel]; + dInitImp = [DCls instanceMethodForSelector: dInitSel]; + iaInitImp = [IACls instanceMethodForSelector: iaInitSel]; + maInitImp = [MACls instanceMethodForSelector: maInitSel]; + idInitImp = [IDCls instanceMethodForSelector: idInitSel]; + mdInitImp = [MDCls instanceMethodForSelector: mdInitSel]; } }