Tweak to prevent stack overflow on windows, without significant loss of

performance ... use stack for smallish temporary storage, but heap for
larger storage requirements.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@17860 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2003-10-14 09:00:42 +00:00
parent b8d2e9aee1
commit 88bd37b151
4 changed files with 57 additions and 23 deletions

View file

@ -1,3 +1,9 @@
2003-10-14 Richard Frith-Macdonald <rfm@gnu.org>
* GSPrivate.h: New macros to aid with appropriate use of stack
or heap for allocating temporary storage.
* NSArray.m: Use new OBUFBEGIN() and OBUFEND() macros.
2003-10-09 Adam Fedor <fedor@gnu.org> 2003-10-09 Adam Fedor <fedor@gnu.org>
* configure.ac: Add special check for sys/mount.h for NetBSD. * configure.ac: Add special check for sys/mount.h for NetBSD.

View file

@ -589,7 +589,7 @@ static Class GSInlineArrayClass;
_contents_array[pos-1] = _contents_array[pos]; _contents_array[pos-1] = _contents_array[pos];
} }
_count--; _count--;
_contents_array[_count] = 0; _contents_array[_count] = 0;
RELEASE(obj); RELEASE(obj);
} }
} }

View file

@ -24,6 +24,17 @@
#define __GSPrivate_h_ #define __GSPrivate_h_
/*
* Macros to manage memory for chunks of code that need to work with
* arrays of objects. Use OBUFBEGIN() to start the block of code using
* the array and OBUFEND() to end it. The idea is to ensure that small
* arrays are allocated on the stack (for speed), but large arrays are
* allocated from the heap (to avoid stack overflow).
*/
#define OBUFMAX 1024
#define OBUFBEGIN(P, S) { id _xxx[(S) <= OBUFMAX ? (S) : 0]; id *(P) = ((S) <= OBUFMAX) ? _xxx : (id*)NSZoneMalloc(NSDefaultMallocZone(), (S) * sizeof(id));
#define OBUFEND(P, S) if ((S) > OBUFMAX) NSZoneFree(NSDefaultMallocZone(), (P)); }
/* /*
* Function to get the name of a string encoding as an NSString. * Function to get the name of a string encoding as an NSString.
*/ */

View file

@ -265,16 +265,20 @@ static SEL rlSel;
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
format: @"Attempt to add nil to an array"]; format: @"Attempt to add nil to an array"];
if (c == 0) if (c == 0)
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()] {
initWithObjects: &anObject count: 1]; na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
initWithObjects: &anObject count: 1];
}
else else
{ {
id objects[c+1]; OBUFBEGIN(objects, c+1)
[self getObjects: objects]; [self getObjects: objects];
objects[c] = anObject; objects[c] = anObject;
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()] na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
initWithObjects: objects count: c+1]; initWithObjects: objects count: c+1];
OBUFEND(objects, c+1)
} }
return AUTORELEASE(na); return AUTORELEASE(na);
} }
@ -290,13 +294,15 @@ static SEL rlSel;
c = [self count]; c = [self count];
l = [anotherArray count]; l = [anotherArray count];
{
id objects[c+l];
[self getObjects: objects]; OBUFBEGIN(objects, c+l)
[anotherArray getObjects: &objects[c]];
na = [NSArrayClass arrayWithObjects: objects count: c+l]; [self getObjects: objects];
} [anotherArray getObjects: &objects[c]];
na = [NSArrayClass arrayWithObjects: objects count: c+l];
OBUFEND(objects, c+l)
return na; return na;
} }
@ -352,12 +358,13 @@ static SEL rlSel;
if (count > 0) if (count > 0)
{ {
id a[count]; OBUFBEGIN(a, count)
[self getObjects: a]; [self getObjects: a];
[aCoder encodeArrayOfObjCType: @encode(id) [aCoder encodeArrayOfObjCType: @encode(id)
count: count count: count
at: a]; at: a];
OBUFEND(a, count)
} }
} }
@ -494,7 +501,7 @@ static SEL rlSel;
- (id) initWithArray: (NSArray*)array copyItems: (BOOL)shouldCopy - (id) initWithArray: (NSArray*)array copyItems: (BOOL)shouldCopy
{ {
unsigned c = [array count]; unsigned c = [array count];
id objects[c]; OBUFBEGIN(objects, c)
[array getObjects: objects]; [array getObjects: objects];
if (shouldCopy == YES) if (shouldCopy == YES)
@ -517,6 +524,7 @@ static SEL rlSel;
{ {
self = [self initWithObjects: objects count: c]; self = [self initWithObjects: objects count: c];
} }
OBUFEND(objects, c)
return self; return self;
} }
@ -528,10 +536,11 @@ static SEL rlSel;
- (id) initWithArray: (NSArray*)array - (id) initWithArray: (NSArray*)array
{ {
unsigned c = [array count]; unsigned c = [array count];
id objects[c]; OBUFBEGIN(objects, c)
[array getObjects: objects]; [array getObjects: objects];
self = [self initWithObjects: objects count: c]; self = [self initWithObjects: objects count: c];
OBUFEND(objects, c)
return self; return self;
} }
@ -547,7 +556,7 @@ static SEL rlSel;
at: &count]; at: &count];
if (count > 0) if (count > 0)
{ {
id contents[count]; OBUFBEGIN(contents, count)
[aCoder decodeArrayOfObjCType: @encode(id) [aCoder decodeArrayOfObjCType: @encode(id)
count: count count: count
@ -559,6 +568,7 @@ static SEL rlSel;
[contents[count] release]; [contents[count] release];
} }
#endif #endif
OBUFEND(contents, count)
} }
else else
{ {
@ -974,10 +984,11 @@ compare(id elem1, id elem2, void* context)
} }
else else
{ {
id objects[aRange.length]; OBUFBEGIN(objects, aRange.length)
[self getObjects: objects range: aRange]; [self getObjects: objects range: aRange];
na = [NSArray arrayWithObjects: objects count: aRange.length]; na = [NSArray arrayWithObjects: objects count: aRange.length];
OBUFEND(objects, aRange.length)
} }
return na; return na;
} }
@ -1728,12 +1739,15 @@ compare(id elem1, id elem2, void* context)
- (id) initWithArray: (NSArray*)anArray - (id) initWithArray: (NSArray*)anArray
{ {
[super init]; self = [super init];
array = anArray; if (self != nil)
IF_NO_GC(RETAIN(array)); {
pos = 0; array = anArray;
get = [array methodForSelector: oaiSel]; IF_NO_GC(RETAIN(array));
cnt = (unsigned (*)(NSArray*, SEL))[array methodForSelector: countSel]; pos = 0;
get = [array methodForSelector: oaiSel];
cnt = (unsigned (*)(NSArray*, SEL))[array methodForSelector: countSel];
}
return self; return self;
} }
@ -1765,8 +1779,11 @@ compare(id elem1, id elem2, void* context)
- (id) initWithArray: (NSArray*)anArray - (id) initWithArray: (NSArray*)anArray
{ {
[super initWithArray: anArray]; self = [super initWithArray: anArray];
pos = (*cnt)(array, countSel); if (self != nil)
{
pos = (*cnt)(array, countSel);
}
return self; return self;
} }