From acaae6854e00e70a096fc6fbd1f6dc177b27deca Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 12 Nov 1998 10:58:17 +0000 Subject: [PATCH] Minor performance improvements. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3209 72102866-910b-0410-8b05-ffd578937521 --- Headers/gnustep/base/fast.x | 6 + Source/NSData.m | 287 ++++++++++++++++++++++-------------- Source/NSGCString.m | 4 +- Source/NSGString.m | 5 +- Source/NSObject.m | 32 +++- 5 files changed, 217 insertions(+), 117 deletions(-) diff --git a/Headers/gnustep/base/fast.x b/Headers/gnustep/base/fast.x index a7b99675a..53402a890 100644 --- a/Headers/gnustep/base/fast.x +++ b/Headers/gnustep/base/fast.x @@ -110,6 +110,12 @@ extern fastImp _fastImp; /* Populated by _fastBuildCache() */ extern void _fastBuildCache(); +/* + * The '_fastMallocBuffer()' function is called to get a chunk of + * memory that will automatically be released when the current + * autorelease pool goes away. +extern void *_fastMallocBuffer(unsigned size); + /* * Fast access to class info - DON'T pass nil to these! * These should really do different things conditional upon the objc diff --git a/Source/NSData.m b/Source/NSData.m index ac92a1e7e..b7b9584c7 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -273,7 +273,7 @@ failure: length: (unsigned)length { return [[[dataMalloc alloc] initWithBytesNoCopy: bytes - length: length] + length: length] autorelease]; } @@ -869,13 +869,13 @@ failure: } } -- (id) copyWithZone: (NSZone*)zone +- (id) copyWithZone: (NSZone*)z { - if (NSShouldRetainWithZone(self, zone) && + if (NSShouldRetainWithZone(self, z) && [self isKindOfClass: [NSMutableData class]] == NO) return [self retain]; else - return [[dataMalloc allocWithZone: zone] + return [[dataMalloc allocWithZone: z] initWithBytes: [self bytes] length: [self length]]; } @@ -1397,96 +1397,121 @@ failure: + (NSData*) allocWithZone: (NSZone*)z { - return (NSData*)NSAllocateObject(self, 0, z); + return (NSData*)NSAllocateObject(self, 0, z); } /* Creation and Destruction of objects. */ +- (id) copy +{ + return [self retain]; +} + +- (id) copyWithZone: (NSZone*)z +{ + return [self retain]; +} + +- (id) mutableCopy +{ + return [[mutableDataMalloc allocWithZone: NSDefaultMallocZone()] + initWithBytes: bytes length: length]; +} + +- (id) mutableCopyWithZone: (NSZone*)z +{ + return [[mutableDataMalloc allocWithZone: z] + initWithBytes: bytes length: length]; +} + - (void) dealloc { - bytes = 0; - length = 0; - [super dealloc]; + bytes = 0; + length = 0; + [super dealloc]; } - (id) init { - return [self initWithBytesNoCopy: 0 - length: 0 - fromZone: [self zone]]; + return [self initWithBytesNoCopy: 0 + length: 0 + fromZone: [self zone]]; } - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned)bufferSize fromZone: (NSZone*)aZone { - bytes = aBuffer; - length = bufferSize; - return self; + bytes = aBuffer; + length = bufferSize; + return self; } /* NSCoding */ - (Class) classForArchiver { - return dataMalloc; /* Will not be static data when decoded. */ + return dataMalloc; /* Will not be static data when decoded. */ } - (Class) classForCoder { - return dataMalloc; /* Will not be static data when decoded. */ + return dataMalloc; /* Will not be static data when decoded. */ } - (Class) classForPortCoder { - return dataMalloc; /* Will not be static data when decoded. */ + return dataMalloc; /* Will not be static data when decoded. */ } - (void) encodeWithCoder: (NSCoder*)aCoder { - [aCoder encodeValueOfObjCType: @encode(unsigned long) - at: &length]; - [aCoder encodeArrayOfObjCType: @encode(unsigned char) - count: length - at: bytes]; + [aCoder encodeValueOfObjCType: @encode(unsigned long) + at: &length]; + [aCoder encodeArrayOfObjCType: @encode(unsigned char) + count: length + at: bytes]; } /* Basic methods */ - (const void*) bytes { - return bytes; + return bytes; } - (void) getBytes: (void*)buffer range: (NSRange)aRange { - if (aRange.location > length || NSMaxRange(aRange) > length) { - [NSException raise: NSRangeException - format: @"Range: (%u, %u) Size: %d", + if (aRange.location > length || NSMaxRange(aRange) > length) + { + [NSException raise: NSRangeException + format: @"Range: (%u, %u) Size: %d", aRange.location, aRange.length, length]; } - else { - memcpy(buffer, bytes + aRange.location, aRange.length); + else + { + memcpy(buffer, bytes + aRange.location, aRange.length); } - return; + return; } - (unsigned) length { - return length; + return length; } static inline void getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) { - if (*pos > limit || len > limit || len+*pos > limit) { - [NSException raise: NSRangeException - format: @"Range: (%u, %u) Size: %d", + if (*pos > limit || len > limit || len+*pos > limit) + { + [NSException raise: NSRangeException + format: @"Range: (%u, %u) Size: %d", *pos, len, limit]; } - memcpy(dst, src + *pos, len); - *pos += len; + memcpy(dst, src + *pos, len); + *pos += len; } - (void)deserializeDataAt: (void*)data @@ -1728,137 +1753,168 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) @implementation NSDataMalloc +- (id) copy +{ + if (NSShouldRetainWithZone(self, NSDefaultMallocZone())) + return [self retain]; + else + return [[dataMalloc allocWithZone: NSDefaultMallocZone()] + initWithBytes: bytes length: length]; +} + +- (id) copyWithZone: (NSZone*)z +{ + if (NSShouldRetainWithZone(self, z)) + return [self retain]; + else + return [[dataMalloc allocWithZone: z] + initWithBytes: bytes length: length]; +} + - (void) dealloc { - if (bytes) { - NSZoneFree(zone, bytes); - bytes = 0; + if (bytes) + { + NSZoneFree(zone, bytes); + bytes = 0; } - [super dealloc]; + [super dealloc]; } - (id) initWithBytes: (const void*)aBuffer length: (unsigned)bufferSize { - void* tmp = 0; + void* tmp = 0; - if (aBuffer != 0 && bufferSize > 0) { - zone = [self zone]; - tmp = NSZoneMalloc(zone, bufferSize); - if (tmp == 0) { - NSLog(@"[NSDataMalloc -initWithBytes:length:] unable to allocate %lu bytes", bufferSize); - [self release]; - return nil; + if (aBuffer != 0 && bufferSize > 0) + { + zone = [self zone]; + tmp = NSZoneMalloc(zone, bufferSize); + if (tmp == 0) + { + NSLog(@"[NSDataMalloc -initWithBytes:length:] unable to allocate %lu bytes", bufferSize); + [self release]; + return nil; } - else { - memcpy(tmp, aBuffer, bufferSize); + else + { + memcpy(tmp, aBuffer, bufferSize); } } - self = [self initWithBytesNoCopy: tmp length: bufferSize fromZone: zone]; - return self; + self = [self initWithBytesNoCopy: tmp length: bufferSize fromZone: zone]; + return self; } - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned)bufferSize { - NSZone *z = NSZoneFromPointer(aBuffer); + NSZone *z = NSZoneFromPointer(aBuffer); - return [self initWithBytesNoCopy: aBuffer length: bufferSize fromZone: z]; + return [self initWithBytesNoCopy: aBuffer length: bufferSize fromZone: z]; } - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned)bufferSize fromZone: (NSZone*)aZone { - /* - * If the zone is zero, the data we have been given does not belong - * to use so we must create an NSDataStatic object to contain it. - */ - if (aZone == 0) { - NSData *data; + /* + * If the zone is zero, the data we have been given does not belong + * to use so we must create an NSDataStatic object to contain it. + */ + if (aZone == 0) + { + NSData *data; - data = [[NSDataStatic alloc] initWithBytesNoCopy: aBuffer - length: bufferSize]; - [self release]; - return data; + data = [[NSDataStatic alloc] initWithBytesNoCopy: aBuffer + length: bufferSize]; + [self release]; + return data; } - zone = aZone; - bytes = aBuffer; - if (bytes) { - length = bufferSize; + zone = aZone; + bytes = aBuffer; + if (bytes) + { + length = bufferSize; } - return self; + return self; } - (id) initWithCoder: (NSCoder*)aCoder { - unsigned l; - void* b; + unsigned l; + void* b; - zone = [self zone]; + zone = [self zone]; - [aCoder decodeValueOfObjCType: @encode(unsigned long) at: &l]; - if (l) { - b = NSZoneMalloc(zone, l); - if (b == 0) { - NSLog(@"[NSDataMalloc -initWithCoder:] unable to get %lu bytes", l); - [self release]; - return nil; + [aCoder decodeValueOfObjCType: @encode(unsigned long) at: &l]; + if (l) + { + b = NSZoneMalloc(zone, l); + if (b == 0) + { + NSLog(@"[NSDataMalloc -initWithCoder:] unable to get %lu bytes", l); + [self release]; + return nil; } - [aCoder decodeArrayOfObjCType: @encode(unsigned char) count: l at: b]; + [aCoder decodeArrayOfObjCType: @encode(unsigned char) count: l at: b]; } - else { - b = 0; + else + { + b = 0; } - return [self initWithBytesNoCopy: b length: l fromZone: zone]; + return [self initWithBytesNoCopy: b length: l fromZone: zone]; } - (id) initWithContentsOfFile: (NSString *)path { - zone = [self zone]; - if (readContentsOfFile(path, &bytes, &length, zone) == NO) { - [self release]; - self = nil; + zone = [self zone]; + if (readContentsOfFile(path, &bytes, &length, zone) == NO) + { + [self release]; + self = nil; } - return self; + return self; } - (id) initWithContentsOfMappedFile: (NSString *)path { #if HAVE_MMAP - NSZone *z = [self zone]; + NSZone *z = [self zone]; - [self release]; - self = [NSDataMappedFile allocWithZone: z]; - return [self initWithContentsOfMappedFile: path]; + [self release]; + self = [NSDataMappedFile allocWithZone: z]; + return [self initWithContentsOfMappedFile: path]; #else - return [self initWithContentsOfFile: path]; + return [self initWithContentsOfFile: path]; #endif } - (id) initWithData: (NSData*)anObject { - if (anObject == nil) { - return [self initWithBytesNoCopy: 0 length: 0 fromZone: [self zone]]; + if (anObject == nil) + { + return [self initWithBytesNoCopy: 0 length: 0 fromZone: [self zone]]; } - if ([anObject isKindOfClass: [NSData class]] == NO) { - NSLog(@"-initWithData: passed a non-data object"); - [self release]; - return nil; + if ([anObject isKindOfClass: [NSData class]] == NO) + { + NSLog(@"-initWithData: passed a non-data object"); + [self release]; + return nil; } - return [self initWithBytes: [anObject bytes] length: [anObject length]]; + return [self initWithBytes: [anObject bytes] length: [anObject length]]; } - (void*) relinquishAllocatedBytesFromZone: (NSZone*)aZone { - if (aZone == zone || aZone == 0) { - void *buf = bytes; + if (aZone == zone || aZone == 0) + { + void *buf = bytes; - bytes = 0; - length = 0; - return buf; + bytes = 0; + length = 0; + return buf; } - return 0; + return 0; } @end @@ -1872,11 +1928,12 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) - (void) dealloc { - if (bytes) { - munmap(bytes, length); - bytes = 0; + if (bytes) + { + munmap(bytes, length); + bytes = 0; } - [super dealloc]; + [super dealloc]; } - (id) initWithContentsOfMappedFile: (NSString*)path @@ -2068,6 +2125,18 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) return mutableDataMalloc; } +- (id) copy +{ + return [[dataMalloc allocWithZone: NSDefaultMallocZone()] + initWithBytes: bytes length: length]; +} + +- (id) copyWithZone: (NSZone*)z +{ + return [[dataMalloc allocWithZone: z] + initWithBytes: bytes length: length]; +} + - (id) initWithBytes: (const void*)aBuffer length: (unsigned)bufferSize { self = [self initWithCapacity: bufferSize]; diff --git a/Source/NSGCString.m b/Source/NSGCString.m index feed324b3..0def86ce0 100644 --- a/Source/NSGCString.m +++ b/Source/NSGCString.m @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -299,11 +298,10 @@ static IMP msInitImp; /* designated initialiser for mutable */ - (const char *) cString { - char *r = NSZoneMalloc(NSDefaultMallocZone(), _count+1); + char *r = (char*)_fastMallocBuffer(_count+1); memcpy(r, _contents_chars, _count); r[_count] = '\0'; - [NSData dataWithBytesNoCopy:r length: _count+1]; return r; } diff --git a/Source/NSGString.m b/Source/NSGString.m index e8600ca7d..7d6fcbafc 100644 --- a/Source/NSGString.m +++ b/Source/NSGString.m @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -224,13 +223,11 @@ - (const char *) cString { - char *r; + char *r = (char*)_fastMallocBuffer(_count+1); - OBJC_MALLOC(r, char, _count+1); if (_count > 0) ustrtostr(r,_contents_chars, _count); r[_count] = '\0'; - [NSData dataWithBytesNoCopy: r length: _count+1]; return r; } diff --git a/Source/NSObject.m b/Source/NSObject.m index e1687ab2d..a7838d03a 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -44,6 +44,10 @@ fastCls _fastCls; /* Structure to cache classes. */ fastImp _fastImp; /* Structure to cache methods. */ +@class _FastMallocBuffer; +static Class fastMallocClass; +static unsigned fastMallocOffset; + @class NSDataMalloc; @class NSMutableDataMalloc; @@ -76,7 +80,6 @@ void _fastBuildCache() instanceMethodForSelector: @selector(isEqual:)]; } - /* * Reference count and memory management @@ -374,6 +377,8 @@ static BOOL double_release_check_enabled = NO; #endif autorelease_class = [NSAutoreleasePool class]; autorelease_imp = [autorelease_class methodForSelector: autorelease_sel]; + fastMallocClass = [_FastMallocBuffer class]; + fastMallocOffset = fastMallocClass->instance_size % ALIGN; _fastBuildCache(); } return; @@ -1081,3 +1086,28 @@ static BOOL double_release_check_enabled = NO; } @end + +/* + * Stuff for temporary memory management. + */ +@interface _FastMallocBuffer : NSObject +@end + +@implementation _FastMallocBuffer +@end + +/* + * Function for giving us the fastest possible allocation of memory to + * be used for temporary storage. + */ +void * +_fastMallocBuffer(unsigned size) +{ + _FastMallocBuffer *o; + + o = (_FastMallocBuffer*)NSAllocateObject(fastMallocClass, + size + fastMallocOffset, NSDefaultMallocZone()); + (*autorelease_imp)(autorelease_class, autorelease_sel, o); + return ((void*)&o[1])+fastMallocOffset; +} +