Minor performance improvements.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3209 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1998-11-12 10:58:17 +00:00
parent 7e2d21836f
commit acaae6854e
5 changed files with 217 additions and 117 deletions

View file

@ -110,6 +110,12 @@ extern fastImp _fastImp; /* Populated by _fastBuildCache() */
extern void _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! * Fast access to class info - DON'T pass nil to these!
* These should really do different things conditional upon the objc * These should really do different things conditional upon the objc

View file

@ -273,7 +273,7 @@ failure:
length: (unsigned)length length: (unsigned)length
{ {
return [[[dataMalloc alloc] initWithBytesNoCopy: bytes return [[[dataMalloc alloc] initWithBytesNoCopy: bytes
length: length] length: length]
autorelease]; 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) [self isKindOfClass: [NSMutableData class]] == NO)
return [self retain]; return [self retain];
else else
return [[dataMalloc allocWithZone: zone] return [[dataMalloc allocWithZone: z]
initWithBytes: [self bytes] length: [self length]]; initWithBytes: [self bytes] length: [self length]];
} }
@ -1397,96 +1397,121 @@ failure:
+ (NSData*) allocWithZone: (NSZone*)z + (NSData*) allocWithZone: (NSZone*)z
{ {
return (NSData*)NSAllocateObject(self, 0, z); return (NSData*)NSAllocateObject(self, 0, z);
} }
/* Creation and Destruction of objects. */ /* 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 - (void) dealloc
{ {
bytes = 0; bytes = 0;
length = 0; length = 0;
[super dealloc]; [super dealloc];
} }
- (id) init - (id) init
{ {
return [self initWithBytesNoCopy: 0 return [self initWithBytesNoCopy: 0
length: 0 length: 0
fromZone: [self zone]]; fromZone: [self zone]];
} }
- (id) initWithBytesNoCopy: (void*)aBuffer - (id) initWithBytesNoCopy: (void*)aBuffer
length: (unsigned)bufferSize length: (unsigned)bufferSize
fromZone: (NSZone*)aZone fromZone: (NSZone*)aZone
{ {
bytes = aBuffer; bytes = aBuffer;
length = bufferSize; length = bufferSize;
return self; return self;
} }
/* NSCoding */ /* NSCoding */
- (Class) classForArchiver - (Class) classForArchiver
{ {
return dataMalloc; /* Will not be static data when decoded. */ return dataMalloc; /* Will not be static data when decoded. */
} }
- (Class) classForCoder - (Class) classForCoder
{ {
return dataMalloc; /* Will not be static data when decoded. */ return dataMalloc; /* Will not be static data when decoded. */
} }
- (Class) classForPortCoder - (Class) classForPortCoder
{ {
return dataMalloc; /* Will not be static data when decoded. */ return dataMalloc; /* Will not be static data when decoded. */
} }
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
[aCoder encodeValueOfObjCType: @encode(unsigned long) [aCoder encodeValueOfObjCType: @encode(unsigned long)
at: &length]; at: &length];
[aCoder encodeArrayOfObjCType: @encode(unsigned char) [aCoder encodeArrayOfObjCType: @encode(unsigned char)
count: length count: length
at: bytes]; at: bytes];
} }
/* Basic methods */ /* Basic methods */
- (const void*) bytes - (const void*) bytes
{ {
return bytes; return bytes;
} }
- (void) getBytes: (void*)buffer - (void) getBytes: (void*)buffer
range: (NSRange)aRange range: (NSRange)aRange
{ {
if (aRange.location > length || NSMaxRange(aRange) > length) { if (aRange.location > length || NSMaxRange(aRange) > length)
[NSException raise: NSRangeException {
format: @"Range: (%u, %u) Size: %d", [NSException raise: NSRangeException
format: @"Range: (%u, %u) Size: %d",
aRange.location, aRange.length, length]; aRange.location, aRange.length, length];
} }
else { else
memcpy(buffer, bytes + aRange.location, aRange.length); {
memcpy(buffer, bytes + aRange.location, aRange.length);
} }
return; return;
} }
- (unsigned) length - (unsigned) length
{ {
return length; return length;
} }
static inline void static inline void
getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
{ {
if (*pos > limit || len > limit || len+*pos > limit) { if (*pos > limit || len > limit || len+*pos > limit)
[NSException raise: NSRangeException {
format: @"Range: (%u, %u) Size: %d", [NSException raise: NSRangeException
format: @"Range: (%u, %u) Size: %d",
*pos, len, limit]; *pos, len, limit];
} }
memcpy(dst, src + *pos, len); memcpy(dst, src + *pos, len);
*pos += len; *pos += len;
} }
- (void)deserializeDataAt: (void*)data - (void)deserializeDataAt: (void*)data
@ -1728,137 +1753,168 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
@implementation NSDataMalloc @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 - (void) dealloc
{ {
if (bytes) { if (bytes)
NSZoneFree(zone, bytes); {
bytes = 0; NSZoneFree(zone, bytes);
bytes = 0;
} }
[super dealloc]; [super dealloc];
} }
- (id) initWithBytes: (const void*)aBuffer length: (unsigned)bufferSize - (id) initWithBytes: (const void*)aBuffer length: (unsigned)bufferSize
{ {
void* tmp = 0; void* tmp = 0;
if (aBuffer != 0 && bufferSize > 0) { if (aBuffer != 0 && bufferSize > 0)
zone = [self zone]; {
tmp = NSZoneMalloc(zone, bufferSize); zone = [self zone];
if (tmp == 0) { tmp = NSZoneMalloc(zone, bufferSize);
NSLog(@"[NSDataMalloc -initWithBytes:length:] unable to allocate %lu bytes", bufferSize); if (tmp == 0)
[self release]; {
return nil; NSLog(@"[NSDataMalloc -initWithBytes:length:] unable to allocate %lu bytes", bufferSize);
[self release];
return nil;
} }
else { else
memcpy(tmp, aBuffer, bufferSize); {
memcpy(tmp, aBuffer, bufferSize);
} }
} }
self = [self initWithBytesNoCopy: tmp length: bufferSize fromZone: zone]; self = [self initWithBytesNoCopy: tmp length: bufferSize fromZone: zone];
return self; return self;
} }
- (id) initWithBytesNoCopy: (void*)aBuffer - (id) initWithBytesNoCopy: (void*)aBuffer
length: (unsigned)bufferSize 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 - (id) initWithBytesNoCopy: (void*)aBuffer
length: (unsigned)bufferSize length: (unsigned)bufferSize
fromZone: (NSZone*)aZone fromZone: (NSZone*)aZone
{ {
/* /*
* If the zone is zero, the data we have been given does not belong * 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. * to use so we must create an NSDataStatic object to contain it.
*/ */
if (aZone == 0) { if (aZone == 0)
NSData *data; {
NSData *data;
data = [[NSDataStatic alloc] initWithBytesNoCopy: aBuffer data = [[NSDataStatic alloc] initWithBytesNoCopy: aBuffer
length: bufferSize]; length: bufferSize];
[self release]; [self release];
return data; return data;
} }
zone = aZone; zone = aZone;
bytes = aBuffer; bytes = aBuffer;
if (bytes) { if (bytes)
length = bufferSize; {
length = bufferSize;
} }
return self; return self;
} }
- (id) initWithCoder: (NSCoder*)aCoder - (id) initWithCoder: (NSCoder*)aCoder
{ {
unsigned l; unsigned l;
void* b; void* b;
zone = [self zone]; zone = [self zone];
[aCoder decodeValueOfObjCType: @encode(unsigned long) at: &l]; [aCoder decodeValueOfObjCType: @encode(unsigned long) at: &l];
if (l) { if (l)
b = NSZoneMalloc(zone, l); {
if (b == 0) { b = NSZoneMalloc(zone, l);
NSLog(@"[NSDataMalloc -initWithCoder:] unable to get %lu bytes", l); if (b == 0)
[self release]; {
return nil; 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 { else
b = 0; {
b = 0;
} }
return [self initWithBytesNoCopy: b length: l fromZone: zone]; return [self initWithBytesNoCopy: b length: l fromZone: zone];
} }
- (id) initWithContentsOfFile: (NSString *)path - (id) initWithContentsOfFile: (NSString *)path
{ {
zone = [self zone]; zone = [self zone];
if (readContentsOfFile(path, &bytes, &length, zone) == NO) { if (readContentsOfFile(path, &bytes, &length, zone) == NO)
[self release]; {
self = nil; [self release];
self = nil;
} }
return self; return self;
} }
- (id) initWithContentsOfMappedFile: (NSString *)path - (id) initWithContentsOfMappedFile: (NSString *)path
{ {
#if HAVE_MMAP #if HAVE_MMAP
NSZone *z = [self zone]; NSZone *z = [self zone];
[self release]; [self release];
self = [NSDataMappedFile allocWithZone: z]; self = [NSDataMappedFile allocWithZone: z];
return [self initWithContentsOfMappedFile: path]; return [self initWithContentsOfMappedFile: path];
#else #else
return [self initWithContentsOfFile: path]; return [self initWithContentsOfFile: path];
#endif #endif
} }
- (id) initWithData: (NSData*)anObject - (id) initWithData: (NSData*)anObject
{ {
if (anObject == nil) { if (anObject == nil)
return [self initWithBytesNoCopy: 0 length: 0 fromZone: [self zone]]; {
return [self initWithBytesNoCopy: 0 length: 0 fromZone: [self zone]];
} }
if ([anObject isKindOfClass: [NSData class]] == NO) { if ([anObject isKindOfClass: [NSData class]] == NO)
NSLog(@"-initWithData: passed a non-data object"); {
[self release]; NSLog(@"-initWithData: passed a non-data object");
return nil; [self release];
return nil;
} }
return [self initWithBytes: [anObject bytes] length: [anObject length]]; return [self initWithBytes: [anObject bytes] length: [anObject length]];
} }
- (void*) relinquishAllocatedBytesFromZone: (NSZone*)aZone - (void*) relinquishAllocatedBytesFromZone: (NSZone*)aZone
{ {
if (aZone == zone || aZone == 0) { if (aZone == zone || aZone == 0)
void *buf = bytes; {
void *buf = bytes;
bytes = 0; bytes = 0;
length = 0; length = 0;
return buf; return buf;
} }
return 0; return 0;
} }
@end @end
@ -1872,11 +1928,12 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
- (void) dealloc - (void) dealloc
{ {
if (bytes) { if (bytes)
munmap(bytes, length); {
bytes = 0; munmap(bytes, length);
bytes = 0;
} }
[super dealloc]; [super dealloc];
} }
- (id) initWithContentsOfMappedFile: (NSString*)path - (id) initWithContentsOfMappedFile: (NSString*)path
@ -2068,6 +2125,18 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return mutableDataMalloc; 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 - (id) initWithBytes: (const void*)aBuffer length: (unsigned)bufferSize
{ {
self = [self initWithCapacity: bufferSize]; self = [self initWithCapacity: bufferSize];

View file

@ -26,7 +26,6 @@
#include <config.h> #include <config.h>
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSData.h>
#include <Foundation/NSCoder.h> #include <Foundation/NSCoder.h>
#include <gnustep/base/NSGString.h> #include <gnustep/base/NSGString.h>
#include <gnustep/base/NSGCString.h> #include <gnustep/base/NSGCString.h>
@ -299,11 +298,10 @@ static IMP msInitImp; /* designated initialiser for mutable */
- (const char *) cString - (const char *) cString
{ {
char *r = NSZoneMalloc(NSDefaultMallocZone(), _count+1); char *r = (char*)_fastMallocBuffer(_count+1);
memcpy(r, _contents_chars, _count); memcpy(r, _contents_chars, _count);
r[_count] = '\0'; r[_count] = '\0';
[NSData dataWithBytesNoCopy:r length: _count+1];
return r; return r;
} }

View file

@ -33,7 +33,6 @@
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSGString.h> #include <Foundation/NSGString.h>
#include <Foundation/NSData.h>
#include <Foundation/NSCoder.h> #include <Foundation/NSCoder.h>
#include <gnustep/base/IndexedCollection.h> #include <gnustep/base/IndexedCollection.h>
#include <gnustep/base/IndexedCollectionPrivate.h> #include <gnustep/base/IndexedCollectionPrivate.h>
@ -224,13 +223,11 @@
- (const char *) cString - (const char *) cString
{ {
char *r; char *r = (char*)_fastMallocBuffer(_count+1);
OBJC_MALLOC(r, char, _count+1);
if (_count > 0) if (_count > 0)
ustrtostr(r,_contents_chars, _count); ustrtostr(r,_contents_chars, _count);
r[_count] = '\0'; r[_count] = '\0';
[NSData dataWithBytesNoCopy: r length: _count+1];
return r; return r;
} }

View file

@ -44,6 +44,10 @@
fastCls _fastCls; /* Structure to cache classes. */ fastCls _fastCls; /* Structure to cache classes. */
fastImp _fastImp; /* Structure to cache methods. */ fastImp _fastImp; /* Structure to cache methods. */
@class _FastMallocBuffer;
static Class fastMallocClass;
static unsigned fastMallocOffset;
@class NSDataMalloc; @class NSDataMalloc;
@class NSMutableDataMalloc; @class NSMutableDataMalloc;
@ -76,7 +80,6 @@ void _fastBuildCache()
instanceMethodForSelector: @selector(isEqual:)]; instanceMethodForSelector: @selector(isEqual:)];
} }
/* /*
* Reference count and memory management * Reference count and memory management
@ -374,6 +377,8 @@ static BOOL double_release_check_enabled = NO;
#endif #endif
autorelease_class = [NSAutoreleasePool class]; autorelease_class = [NSAutoreleasePool class];
autorelease_imp = [autorelease_class methodForSelector: autorelease_sel]; autorelease_imp = [autorelease_class methodForSelector: autorelease_sel];
fastMallocClass = [_FastMallocBuffer class];
fastMallocOffset = fastMallocClass->instance_size % ALIGN;
_fastBuildCache(); _fastBuildCache();
} }
return; return;
@ -1081,3 +1086,28 @@ static BOOL double_release_check_enabled = NO;
} }
@end @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;
}