Merge pull request #84 from gnustep/weak-table

Rework some of the weak handling for NS{Map,Hash}Table.

@Richard, feel free to revert this and to provide a cleaner solution. I am no expert here, but part of this code looks correct and part just like a workaround for a deeper problem.
This commit is contained in:
Fred Kiefer 2019-12-07 10:55:52 +01:00 committed by GitHub
commit 01e7ea8372
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 35 deletions

View file

@ -450,7 +450,7 @@ GSIMapAddNodeToMap(GSIMapTable map, GSIMapNode node)
{
GSIMapBucket bucket;
bucket = GSIMapBucketForKey(map, node->key);
bucket = GSIMapBucketForKey(map, GSI_MAP_READ_KEY(map, &node->key));
GSIMapAddNodeToBucket(bucket, node);
map->nodeCount++;
}
@ -543,7 +543,7 @@ GSIMapRemangleBuckets(GSIMapTable map,
GSIMapBucket bkt;
GSIMapRemoveNodeFromBucket(old_buckets, node);
bkt = GSIMapPickBucket(GSI_MAP_HASH(map, node->key),
bkt = GSIMapPickBucket(GSI_MAP_HASH(map, GSI_MAP_READ_KEY(map, &node->key)),
new_buckets, new_bucketCount);
GSIMapAddNodeToBucket(bkt, node);
}
@ -561,7 +561,7 @@ GSIMapRemangleBuckets(GSIMapTable map,
GSIMapBucket bkt;
GSIMapRemoveNodeFromBucket(old_buckets, node);
bkt = GSIMapPickBucket(GSI_MAP_HASH(map, node->key),
bkt = GSIMapPickBucket(GSI_MAP_HASH(map, GSI_MAP_READ_KEY(map, &node->key)),
new_buckets, new_bucketCount);
GSIMapAddNodeToBucket(bkt, node);
}

View file

@ -75,7 +75,9 @@ typedef GSIMapNode_t *GSIMapNode;
#define GSI_MAP_KTYPES GSUNION_PTR | GSUNION_OBJ
#define GSI_MAP_TABLE_T NSConcreteHashTable
#define GSI_MAP_TABLE_S instanceSize
#define IS_WEAK(M) \
M->cb.pf.options & (NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsWeakMemory)
#define GSI_MAP_HASH(M, X)\
(M->legacy ? M->cb.old.hash(M, X.ptr) \
: pointerFunctionsHash(&M->cb.pf, X.ptr))
@ -84,13 +86,13 @@ typedef GSIMapNode_t *GSIMapNode;
: pointerFunctionsEqual(&M->cb.pf, X.ptr, Y.ptr))
#define GSI_MAP_RELEASE_KEY(M, X)\
(M->legacy ? M->cb.old.release(M, X.ptr) \
: pointerFunctionsRelinquish(&M->cb.pf, &X.ptr))
: IS_WEAK(M) ? nil : pointerFunctionsRelinquish(&M->cb.pf, &X.ptr))
#define GSI_MAP_RETAIN_KEY(M, X)\
(M->legacy ? M->cb.old.retain(M, X.ptr) \
: pointerFunctionsAcquire(&M->cb.pf, &X.ptr, X.ptr))
: IS_WEAK(M) ? nil : pointerFunctionsAcquire(&M->cb.pf, &X.ptr, X.ptr))
#define GSI_MAP_ZEROED(M)\
(M->legacy ? 0 \
: ((M->cb.pf.options & NSPointerFunctionsZeroingWeakMemory) ? YES : NO))
: (IS_WEAK(M) ? YES : NO))
#define GSI_MAP_WRITE_KEY(M, addr, x) \
if (M->legacy) \
@ -100,9 +102,6 @@ typedef GSIMapNode_t *GSIMapNode;
#define GSI_MAP_READ_KEY(M,addr) \
(M->legacy ? *(addr) :\
(typeof(*addr))pointerFunctionsRead(&M->cb.pf, (void**)addr))
#define GSI_MAP_ZEROED(M)\
(M->legacy ? 0 \
: ((M->cb.pf.options & NSPointerFunctionsZeroingWeakMemory) ? YES : NO))
#define GSI_MAP_ENUMERATOR NSHashEnumerator
@ -628,7 +627,13 @@ NSNextHashEnumeratorItem(NSHashEnumerator *enumerator)
}
else
{
return n->key.ptr;
NSConcreteHashTable *map = enumerator->map;
GSIMapKey k = GSI_MAP_READ_KEY(map, &n->key);
if (k.ptr == NULL)
{
return NSNextHashEnumeratorItem(enumerator);
}
return k.ptr;
}
}
else if (enumerator->node != 0) // Got an enumerator object

View file

@ -81,6 +81,10 @@ typedef GSIMapNode_t *GSIMapNode;
#define GSI_MAP_KTYPES GSUNION_PTR | GSUNION_OBJ
#define GSI_MAP_VTYPES GSUNION_PTR | GSUNION_OBJ
#define IS_WEAK_KEY(M) \
M->cb.pf.k.options & (NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsWeakMemory)
#define IS_WEAK_VALUE(M) \
M->cb.pf.v.options & (NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsWeakMemory)
#define GSI_MAP_HASH(M, X)\
(M->legacy ? M->cb.old.k.hash(M, X.ptr) \
: pointerFunctionsHash(&M->cb.pf.k, X.ptr))
@ -89,16 +93,16 @@ typedef GSIMapNode_t *GSIMapNode;
: pointerFunctionsEqual(&M->cb.pf.k, X.ptr, Y.ptr))
#define GSI_MAP_RELEASE_KEY(M, X)\
(M->legacy ? M->cb.old.k.release(M, X.ptr) \
: pointerFunctionsRelinquish(&M->cb.pf.k, &X.ptr))
: IS_WEAK_KEY(M) ? nil : pointerFunctionsRelinquish(&M->cb.pf.k, &X.ptr))
#define GSI_MAP_RETAIN_KEY(M, X)\
(M->legacy ? M->cb.old.k.retain(M, X.ptr) \
: pointerFunctionsAcquire(&M->cb.pf.k, &X.ptr, X.ptr))
: IS_WEAK_KEY(M) ? nil : pointerFunctionsAcquire(&M->cb.pf.k, &X.ptr, X.ptr))
#define GSI_MAP_RELEASE_VAL(M, X)\
(M->legacy ? M->cb.old.v.release(M, X.ptr) \
: pointerFunctionsRelinquish(&M->cb.pf.v, &X.ptr))
: IS_WEAK_VALUE(M) ? nil : pointerFunctionsRelinquish(&M->cb.pf.v, &X.ptr))
#define GSI_MAP_RETAIN_VAL(M, X)\
(M->legacy ? M->cb.old.v.retain(M, X.ptr) \
: pointerFunctionsAcquire(&M->cb.pf.v, &X.ptr, X.ptr))
: IS_WEAK_VALUE(M) ? nil : pointerFunctionsAcquire(&M->cb.pf.v, &X.ptr, X.ptr))
/* 2013-05-25 Here are the macros originally added for GC/ARC ...
* but they caused map table entries to be doubly retained :-(
@ -120,12 +124,12 @@ typedef GSIMapNode_t *GSIMapNode;
if (M->legacy) \
*(addr) = x;\
else\
*(id*)(addr) = (x).obj;
(IS_WEAK_KEY(M) ? pointerFunctionsAssign(&M->cb.pf.k, (void**)addr, (x).obj) : (*(id*)(addr) = (x).obj));
#define GSI_MAP_WRITE_VAL(M, addr, x) \
if (M->legacy) \
*(addr) = x;\
else\
*(id*)(addr) = (x).obj;
(IS_WEAK_VALUE(M) ? pointerFunctionsAssign(&M->cb.pf.v, (void**)addr, (x).obj) : (*(id*)(addr) = (x).obj));
#define GSI_MAP_READ_KEY(M,addr) \
(M->legacy ? *(addr)\
: (typeof(*addr))pointerFunctionsRead(&M->cb.pf.k, (void**)addr))
@ -134,8 +138,7 @@ typedef GSIMapNode_t *GSIMapNode;
: (typeof(*addr))pointerFunctionsRead(&M->cb.pf.v, (void**)addr))
#define GSI_MAP_ZEROED(M)\
(M->legacy ? 0\
: (((M->cb.pf.k.options | M->cb.pf.v.options)\
& NSPointerFunctionsZeroingWeakMemory) ? YES : NO))
: (IS_WEAK_KEY(M) || IS_WEAK_VALUE(M)) ? YES : NO)
#define GSI_MAP_ENUMERATOR NSMapEnumerator
@ -879,23 +882,17 @@ NSNextMapEnumeratorPair(NSMapEnumerator *enumerator,
}
else
{
if (key != 0)
NSConcreteMapTable *map = enumerator->map;
GSIMapKey k = GSI_MAP_READ_KEY(map, &n->key);
GSIMapVal v = GSI_MAP_READ_VALUE(map, &n->value);
if (k.ptr == NULL || v.ptr == NULL)
{
*key = n->key.ptr;
}
else
{
NSWarnFLog(@"Null key return address");
return NSNextMapEnumeratorPair(enumerator, key, value);
}
if (value != 0)
{
*value = n->value.ptr;
}
else
{
NSWarnFLog(@"Null value return address");
}
*key = k.ptr;
*value = v.ptr;
return YES;
}
}
@ -1332,7 +1329,7 @@ const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks =
if (node)
{
return node->value.obj;
return GSI_MAP_READ_VALUE(self, &node->value).obj;
}
}
return nil;
@ -1384,7 +1381,7 @@ const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks =
node = GSIMapNodeForKey(self, (GSIMapKey)aKey);
if (node)
{
if (node->value.obj != anObject)
if (GSI_MAP_READ_VALUE(self, &node->value).obj != anObject)
{
GSI_MAP_RELEASE_VAL(self, node->value);
node->value.obj = anObject;