more gc fixups

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28228 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-04-17 08:12:52 +00:00
parent 92c3166df3
commit e537692852
7 changed files with 191 additions and 139 deletions

View file

@ -173,16 +173,16 @@ NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
{ {
BOOL result = YES; BOOL result = YES;
NSHashEnumerator enumerator; NSHashEnumerator enumerator;
GSIMapNode n; GSIMapNode n1;
enumerator = NSEnumerateHashTable(table1); enumerator = NSEnumerateHashTable(table1);
if (GSObjCClass(table2) == concreteClass) if (GSObjCClass(table2) == concreteClass)
{ {
GSIMapTable t2 = (GSIMapTable)table2; GSIMapTable t2 = (GSIMapTable)table2;
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0) while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0)
{ {
if (GSIMapNodeForKey(t2, n->key) == 0) if (GSIMapNodeForKey(t2, n1->key) == 0)
{ {
result = NO; result = NO;
break; break;
@ -191,12 +191,13 @@ NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
} }
else else
{ {
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0) while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0)
{ {
void *v1 = n1->key.ptr;
void *v2; void *v2;
v2 = NSHashGet(table2, n->key.ptr); v2 = NSHashGet(table2, v1);
if (v2 == 0 && v2 != n->key.ptr) if (v2 == 0 && v2 != v1)
{ {
result = NO; result = NO;
break; break;
@ -215,9 +216,10 @@ NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
enumerator = NSEnumerateHashTable(table1); enumerator = NSEnumerateHashTable(table1);
while ((v1 = NSNextHashEnumeratorItem(&enumerator)) != 0) while ((v1 = NSNextHashEnumeratorItem(&enumerator)) != 0)
{ {
void *v2 = NSHashGet(table2, v1); void *v2;
if ((v2 = NSHashGet(table2, v1)) == 0) v2 = NSHashGet(table2, v1);
if (v2 == 0 && v2 != v1)
{ {
result = NO; result = NO;
break; break;
@ -793,29 +795,20 @@ const NSHashTableCallBacks NSPointerToStructHashCallBacks =
- (id) initWithPointerFunctions: (NSPointerFunctions*)functions - (id) initWithPointerFunctions: (NSPointerFunctions*)functions
capacity: (NSUInteger)initialCapacity capacity: (NSUInteger)initialCapacity
{ {
if (functions == nil)
{
functions = [NSPointerFunctions pointerFunctionsWithOptions: 0];
}
legacy = NO; legacy = NO;
if ([functions class] == [NSConcretePointerFunctions class]) if (![functions isKindOfClass: [NSConcretePointerFunctions class]])
{ {
memcpy(&self->cb.pf, &((NSConcretePointerFunctions*)functions)->_x, static NSConcretePointerFunctions *defaultFunctions = nil;
sizeof(self->cb.pf));
} if (defaultFunctions == nil)
else {
{ defaultFunctions
self->cb.pf.acquireFunction = [functions acquireFunction]; = [[NSConcretePointerFunctions alloc] initWithOptions: 0];
self->cb.pf.descriptionFunction = [functions descriptionFunction]; }
self->cb.pf.hashFunction = [functions hashFunction]; functions = defaultFunctions;
self->cb.pf.isEqualFunction = [functions isEqualFunction];
self->cb.pf.relinquishFunction = [functions relinquishFunction];
self->cb.pf.sizeFunction = [functions sizeFunction];
self->cb.pf.usesStrongWriteBarrier
= [functions usesStrongWriteBarrier];
self->cb.pf.usesWeakReadAndWriteBarriers
= [functions usesWeakReadAndWriteBarriers];
} }
memcpy(&self->cb.pf, &((NSConcretePointerFunctions*)functions)->_x,
sizeof(self->cb.pf));
#if GC_WITH_GC #if GC_WITH_GC
if (self->cb.pf.usesWeakReadAndWriteBarriers) if (self->cb.pf.usesWeakReadAndWriteBarriers)
@ -831,11 +824,6 @@ const NSHashTableCallBacks NSPointerToStructHashCallBacks =
return self; return self;
} }
- (BOOL) isEqualToHashTable: (NSHashTable*)other
{
return NSCompareHashTables(self, other);
}
- (NSEnumerator*) objectEnumerator - (NSEnumerator*) objectEnumerator
{ {
return [self subclassResponsibility: _cmd]; return [self subclassResponsibility: _cmd];

View file

@ -179,6 +179,13 @@ NSAllMapTableValues(NSMapTable *table)
return valueArray; return valueArray;
} }
static BOOL
equalPointers(const void *item1, const void *item2,
NSUInteger (*size)(const void *item))
{
return (item1 == item2) ? YES : NO;
}
/** /**
* Compares the two map tables for equality. * Compares the two map tables for equality.
* If the tables are different sizes, returns NO. * If the tables are different sizes, returns NO.
@ -190,43 +197,123 @@ NSAllMapTableValues(NSMapTable *table)
BOOL BOOL
NSCompareMapTables(NSMapTable *table1, NSMapTable *table2) NSCompareMapTables(NSMapTable *table1, NSMapTable *table2)
{ {
GSIMapTable t1 = (GSIMapTable)table1; if (table1 == table2)
GSIMapTable t2 = (GSIMapTable)table2;
if (t1 == t2)
{ {
return YES; return YES;
} }
if (t1 == nil) if (table1 == nil)
{ {
NSWarnFLog(@"Null first argument supplied"); NSWarnFLog(@"Null first argument supplied");
return NO; return NO;
} }
if (t2 == nil) if (table2 == nil)
{ {
NSWarnFLog(@"Null second argument supplied"); NSWarnFLog(@"Null second argument supplied");
return NO; return NO;
} }
if (t1->nodeCount != t2->nodeCount) if ([table1 count] != [table2 count])
{ {
return NO; return NO;
} }
if (GSObjCClass(table1) != concreteClass
&& GSObjCClass(table2) == concreteClass)
{
id t = table1;
table1 = table2;
table2 = t;
}
if (GSObjCClass(table1) == concreteClass)
{
NSConcreteMapTable *c1 = (NSConcreteMapTable*)table1;
GSIMapTable t1 = (GSIMapTable)table1;
BOOL result = YES;
NSMapEnumerator enumerator;
GSIMapNode n1;
enumerator = GSIMapEnumeratorForMap(t1);
if (GSObjCClass(table2) == concreteClass)
{
GSIMapTable t2 = (GSIMapTable)table2;
while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0)
{
GSIMapNode n2;
n2 = GSIMapNodeForKey(t2, n1->key);
if (n2 == 0)
{
result = NO;
}
else
{
void *v1 = n1->value.ptr;
void *v2 = n2->value.ptr;
result = (c1->legacy
? c1->cb.old.k.isEqual(c1, v1, v2)
: pointerFunctionsEqual(&c1->cb.pf.v, v2, v2));
}
if (result == NO)
{
break;
}
}
}
else
{
while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0)
{
void *k1 = n1->key.ptr;
void *v1 = n1->value.ptr;
void *v2 = NSMapGet(table2, k1);
result = (c1->legacy
? c1->cb.old.k.isEqual(c1, v1, v2)
: pointerFunctionsEqual(&c1->cb.pf.v, v1, v2));
if (result == NO)
{
break;
}
}
}
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return result;
}
else else
{ {
NSMapEnumerator enumerator = GSIMapEnumeratorForMap((GSIMapTable)t1); BOOL result = YES;
GSIMapNode n; NSMapEnumerator enumerator;
void *k1;
void *v1;
NSPointerFunctions *pf;
BOOL (*isEqualFunction)(const void *item1, const void *item2,
NSUInteger (*size)(const void *item));
NSUInteger (*sizeFunction)(const void *item);
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0) /* Get functions needed for comparison.
{ */
if (GSIMapNodeForKey(t2, n->key) == 0) pf = [table1 valuePointerFunctions];
{ isEqualFunction = [pf isEqualFunction];
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator); sizeFunction = [pf sizeFunction];
return NO; if (isEqualFunction == 0) isEqualFunction = equalPointers;
}
} enumerator = NSEnumerateMapTable(table1);
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator); while (NSNextMapEnumeratorPair(&enumerator, &k1, &v1) == YES)
return YES; {
void *v2 = NSMapGet(table2, k1);
if ((*isEqualFunction)(v1, v2, sizeFunction) == NO)
{
result = NO;
break;
}
}
NSEndMapTableEnumeration(&enumerator);
return result;
} }
} }
@ -915,51 +1002,28 @@ const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks =
valuePointerFunctions: (NSPointerFunctions*)valueFunctions valuePointerFunctions: (NSPointerFunctions*)valueFunctions
capacity: (NSUInteger)initialCapacity capacity: (NSUInteger)initialCapacity
{ {
if (keyFunctions == nil) static NSConcretePointerFunctions *defaultFunctions = nil;
if (defaultFunctions == nil)
{ {
keyFunctions = [NSPointerFunctions pointerFunctionsWithOptions: 0]; defaultFunctions
} = [[NSConcretePointerFunctions alloc] initWithOptions: 0];
if (valueFunctions == nil)
{
valueFunctions = [NSPointerFunctions pointerFunctionsWithOptions: 0];
} }
legacy = NO; legacy = NO;
if ([keyFunctions class] == [NSConcretePointerFunctions class])
if (![keyFunctions isKindOfClass: [NSConcretePointerFunctions class]])
{ {
memcpy(&self->cb.pf.k, &((NSConcretePointerFunctions*)keyFunctions)->_x, keyFunctions = defaultFunctions;
sizeof(self->cb.pf.k));
} }
else memcpy(&self->cb.pf.k, &((NSConcretePointerFunctions*)keyFunctions)->_x,
sizeof(self->cb.pf.k));
if (![valueFunctions isKindOfClass: [NSConcretePointerFunctions class]])
{ {
self->cb.pf.k.acquireFunction = [keyFunctions acquireFunction]; valueFunctions = defaultFunctions;
self->cb.pf.k.descriptionFunction = [keyFunctions descriptionFunction];
self->cb.pf.k.hashFunction = [keyFunctions hashFunction];
self->cb.pf.k.isEqualFunction = [keyFunctions isEqualFunction];
self->cb.pf.k.relinquishFunction = [keyFunctions relinquishFunction];
self->cb.pf.k.sizeFunction = [keyFunctions sizeFunction];
self->cb.pf.k.usesStrongWriteBarrier
= [keyFunctions usesStrongWriteBarrier];
self->cb.pf.k.usesWeakReadAndWriteBarriers
= [keyFunctions usesWeakReadAndWriteBarriers];
}
if ([valueFunctions class] == [NSConcretePointerFunctions class])
{
memcpy(&self->cb.pf.v, &((NSConcretePointerFunctions*)valueFunctions)->_x,
sizeof(self->cb.pf.v));
}
else
{
self->cb.pf.v.acquireFunction = [valueFunctions acquireFunction];
self->cb.pf.v.descriptionFunction = [valueFunctions descriptionFunction];
self->cb.pf.v.hashFunction = [valueFunctions hashFunction];
self->cb.pf.v.isEqualFunction = [valueFunctions isEqualFunction];
self->cb.pf.v.relinquishFunction = [valueFunctions relinquishFunction];
self->cb.pf.v.sizeFunction = [valueFunctions sizeFunction];
self->cb.pf.v.usesStrongWriteBarrier
= [valueFunctions usesStrongWriteBarrier];
self->cb.pf.v.usesWeakReadAndWriteBarriers
= [valueFunctions usesWeakReadAndWriteBarriers];
} }
memcpy(&self->cb.pf.v, &((NSConcretePointerFunctions*)valueFunctions)->_x,
sizeof(self->cb.pf.v));
#if GC_WITH_GC #if GC_WITH_GC
if (self->cb.pf.k.usesWeakReadAndWriteBarriers) if (self->cb.pf.k.usesWeakReadAndWriteBarriers)
@ -991,7 +1055,7 @@ const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks =
- (BOOL) isEqual: (id)other - (BOOL) isEqual: (id)other
{ {
return (BOOL)(uintptr_t)[self subclassResponsibility: _cmd]; return NSCompareMapTables(self, other);
} }
- (NSEnumerator*) keyEnumerator - (NSEnumerator*) keyEnumerator

View file

@ -46,11 +46,8 @@ typedef struct
NSUInteger (*sizeFunction)(const void *item); NSUInteger (*sizeFunction)(const void *item);
BOOL shouldCopyIn; NSPointerFunctionsOptions options;
BOOL usesStrongWriteBarrier;
BOOL usesWeakReadAndWriteBarriers;
} PFInfo; } PFInfo;
/* Declare the concrete pointer functions class as a wrapper around /* Declare the concrete pointer functions class as a wrapper around
@ -73,9 +70,10 @@ static inline void
pointerFunctionsAcquire(PFInfo *PF, void **dst, void *src) pointerFunctionsAcquire(PFInfo *PF, void **dst, void *src)
{ {
if (PF->acquireFunction != 0) if (PF->acquireFunction != 0)
src = (*PF->acquireFunction)(src, PF->sizeFunction, PF->shouldCopyIn); src = (*PF->acquireFunction)(src, PF->sizeFunction,
PF->options & NSPointerFunctionsCopyIn ? YES : NO);
#if GSWITHGC #if GSWITHGC
if (PF->usesWeakReadAndWriteBarriers) if (PF->options & NSPointerFunctionsZeroingWeakMemory)
GSAssignZeroingWeakPointer(dst, src); GSAssignZeroingWeakPointer(dst, src);
else else
#endif #endif
@ -125,7 +123,7 @@ pointerFunctionsRelinquish(PFInfo *PF, void **itemptr)
{ {
if (PF->relinquishFunction != 0) if (PF->relinquishFunction != 0)
(*PF->relinquishFunction)(*itemptr, PF->sizeFunction); (*PF->relinquishFunction)(*itemptr, PF->sizeFunction);
if (PF->usesWeakReadAndWriteBarriers) if (PF->options & NSPointerFunctionsZeroingWeakMemory)
GSAssignZeroingWeakPointer(itemptr, (void*)0); GSAssignZeroingWeakPointer(itemptr, (void*)0);
else else
*itemptr = 0; *itemptr = 0;
@ -138,11 +136,12 @@ pointerFunctionsReplace(PFInfo *PF, void **dst, void *src)
if (src != *dst) if (src != *dst)
{ {
if (PF->acquireFunction != 0) if (PF->acquireFunction != 0)
src = (*PF->acquireFunction)(src, PF->sizeFunction, PF->shouldCopyIn); src = (*PF->acquireFunction)(src, PF->sizeFunction,
PF->options & NSPointerFunctionsCopyIn ? YES : NO);
if (PF->relinquishFunction != 0) if (PF->relinquishFunction != 0)
(*PF->relinquishFunction)(*dst, PF->sizeFunction); (*PF->relinquishFunction)(*dst, PF->sizeFunction);
#if GSWITHGC #if GSWITHGC
if (PF->usesWeakReadAndWriteBarriers) if (PF->options & NSPointerFunctionsZeroingWeakMemory)
GSAssignZeroingWeakPointer(dst, src); GSAssignZeroingWeakPointer(dst, src);
else else
#endif #endif

View file

@ -187,6 +187,8 @@ relinquishRetainedMemory(const void *item,
- (id) initWithOptions: (NSPointerFunctionsOptions)options - (id) initWithOptions: (NSPointerFunctionsOptions)options
{ {
_x.options = options;
/* First we look at the memory management options to see which function /* First we look at the memory management options to see which function
* should be used to relinquish contents of a container with these * should be used to relinquish contents of a container with these
* options. * options.
@ -194,7 +196,6 @@ relinquishRetainedMemory(const void *item,
if (options & NSPointerFunctionsZeroingWeakMemory) if (options & NSPointerFunctionsZeroingWeakMemory)
{ {
_x.relinquishFunction = 0; _x.relinquishFunction = 0;
_x.usesWeakReadAndWriteBarriers = YES;
} }
else if (options & NSPointerFunctionsOpaqueMemory) else if (options & NSPointerFunctionsOpaqueMemory)
{ {
@ -210,19 +211,9 @@ relinquishRetainedMemory(const void *item,
} }
else else
{ {
/* Only retained pointers need the array memory to be scanned,
* so for these we set the usesStrongWriteBarrier flag to tell
* containers to allocate scanned memory.
*/
_x.usesStrongWriteBarrier = YES;
_x.relinquishFunction = relinquishRetainedMemory; _x.relinquishFunction = relinquishRetainedMemory;
} }
if (options & NSPointerFunctionsCopyIn)
{
_x.shouldCopyIn = YES;
}
/* Now we look at the personality options to determine other functions. /* Now we look at the personality options to determine other functions.
*/ */
if (options & NSPointerFunctionsOpaquePersonality) if (options & NSPointerFunctionsOpaquePersonality)
@ -336,12 +327,20 @@ relinquishRetainedMemory(const void *item,
- (void) setUsesStrongWriteBarrier: (BOOL)flag - (void) setUsesStrongWriteBarrier: (BOOL)flag
{ {
_x.usesStrongWriteBarrier = flag; _x.options &=
~(NSPointerFunctionsZeroingWeakMemory
|NSPointerFunctionsOpaqueMemory
|NSPointerFunctionsMallocMemory
|NSPointerFunctionsMachVirtualMemory);
} }
- (void) setUsesWeakReadAndWriteBarriers: (BOOL)flag - (void) setUsesWeakReadAndWriteBarriers: (BOOL)flag
{ {
_x.usesWeakReadAndWriteBarriers = flag; _x.options |= NSPointerFunctionsZeroingWeakMemory;
_x.options &=
~(NSPointerFunctionsOpaqueMemory
|NSPointerFunctionsMallocMemory
|NSPointerFunctionsMachVirtualMemory);
} }
- (NSUInteger (*)(const void *item)) sizeFunction - (NSUInteger (*)(const void *item)) sizeFunction
@ -351,12 +350,20 @@ relinquishRetainedMemory(const void *item,
- (BOOL) usesStrongWriteBarrier - (BOOL) usesStrongWriteBarrier
{ {
return _x.usesStrongWriteBarrier; if ((_x.options &
(NSPointerFunctionsZeroingWeakMemory
|NSPointerFunctionsOpaqueMemory
|NSPointerFunctionsMallocMemory
|NSPointerFunctionsMachVirtualMemory)) == NSPointerFunctionsStrongMemory)
return YES;
return NO;
} }
- (BOOL) usesWeakReadAndWriteBarriers - (BOOL) usesWeakReadAndWriteBarriers
{ {
return _x.usesStrongWriteBarrier; if (_x.options & NSPointerFunctionsZeroingWeakMemory)
return YES;
return NO;
} }
@end @end

View file

@ -160,15 +160,13 @@ static Class concreteClass = 0;
- (BOOL) isEqual: (id)other - (BOOL) isEqual: (id)other
{ {
if (other == self) return YES;
if (other == nil) return NO;
if ([other isKindOfClass: abstractClass] == NO) return NO; if ([other isKindOfClass: abstractClass] == NO) return NO;
return [self isEqualToHashTable: other]; return NSCompareHashTables(self, other);
} }
- (BOOL) isEqualToHashTable: (NSHashTable*)other - (BOOL) isEqualToHashTable: (NSHashTable*)other
{ {
return (BOOL)(uintptr_t)[self subclassResponsibility: _cmd]; return NSCompareHashTables(self, other);
} }
- (BOOL) isSubsetOfHashTable: (NSHashTable*)other - (BOOL) isSubsetOfHashTable: (NSHashTable*)other

View file

@ -166,7 +166,8 @@ static Class concreteClass = 0;
- (BOOL) isEqual: (id)other - (BOOL) isEqual: (id)other
{ {
return (BOOL)(uintptr_t)[self subclassResponsibility: _cmd]; if ([other isKindOfClass: abstractClass] == NO) return NO;
return NSCompareMapTables(self, other);
} }
- (NSEnumerator*) keyEnumerator - (NSEnumerator*) keyEnumerator

View file

@ -269,7 +269,7 @@ static Class concreteClass = Nil;
c->_capacity = c->_count; c->_capacity = c->_count;
c->_grow_factor = c->_capacity/2; c->_grow_factor = c->_capacity/2;
#if GS_WITH_GC #if GS_WITH_GC
if (_pf.usesWeakReadAndWriteBarriers) if (_pf.options & NSPointerFunctionsZeroingWeakMemory)
{ {
c->_contents = NSAllocateCollectable(sizeof(id) * _count, 0); c->_contents = NSAllocateCollectable(sizeof(id) * _count, 0);
} }
@ -350,7 +350,7 @@ static Class concreteClass = Nil;
if (_count > 0) if (_count > 0)
{ {
#if GS_WITH_GC #if GS_WITH_GC
if (_pf.usesWeakReadAndWriteBarriers) if (_pf.options & NSPointerFunctionsZeroingWeakMemory)
{ {
_contents = NSAllocateCollectable(sizeof(id) * _count, 0); _contents = NSAllocateCollectable(sizeof(id) * _count, 0);
} }
@ -387,23 +387,18 @@ static Class concreteClass = Nil;
- (id) initWithPointerFunctions: (NSPointerFunctions*)functions - (id) initWithPointerFunctions: (NSPointerFunctions*)functions
{ {
if ([functions class] == [NSConcretePointerFunctions class]) if (![functions isKindOfClass: [NSConcretePointerFunctions class]])
{ {
memcpy(&_pf, &((NSConcretePointerFunctions*)functions)->_x, sizeof(_pf)); static NSConcretePointerFunctions *defaultFunctions = nil;
}
else if (defaultFunctions == nil)
{ {
_pf.acquireFunction = [functions acquireFunction]; defaultFunctions
_pf.descriptionFunction = [functions descriptionFunction]; = [[NSConcretePointerFunctions alloc] initWithOptions: 0];
_pf.hashFunction = [functions hashFunction]; }
_pf.isEqualFunction = [functions isEqualFunction]; functions = defaultFunctions;
_pf.relinquishFunction = [functions relinquishFunction];
_pf.sizeFunction = [functions sizeFunction];
_pf.usesStrongWriteBarrier
= [functions usesStrongWriteBarrier];
_pf.usesWeakReadAndWriteBarriers
= [functions usesWeakReadAndWriteBarriers];
} }
memcpy(&_pf, &((NSConcretePointerFunctions*)functions)->_x, sizeof(_pf));
return self; return self;
} }
@ -516,7 +511,7 @@ static Class concreteClass = Nil;
#if GS_WITH_GC #if GS_WITH_GC
ptr = (void**)NSZoneMalloc([self zone], size); ptr = (void**)NSZoneMalloc([self zone], size);
#else #else
if (_pf.usesWeakReadAndWriteBarriers) if (_pf.options & NSPointerFunctionsZeroingWeakMemory)
{ {
ptr = (void**)NSAllocateCollectable(size, 0); ptr = (void**)NSAllocateCollectable(size, 0);
} }
@ -531,7 +526,7 @@ static Class concreteClass = Nil;
#if GS_WITH_GC #if GS_WITH_GC
ptr = (void**)NSZoneRealloc([self zone], _contents, size); ptr = (void**)NSZoneRealloc([self zone], _contents, size);
#else #else
if (_pf.usesWeakReadAndWriteBarriers) if (_pf.options & NSPointerFunctionsZeroingWeakMemory)
{ {
ptr = (void**)NSReallocateCollectable( ptr = (void**)NSReallocateCollectable(
_contents, size, 0); _contents, size, 0);