mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
iPerformance and GC improvements
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13726 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5651fe7dbb
commit
ecbcc202a1
15 changed files with 167 additions and 114 deletions
26
ChangeLog
26
ChangeLog
|
@ -1,3 +1,29 @@
|
|||
2002-05-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/gnustep/base/GSIMap.h:
|
||||
* Headers/gnustep/base/NSHashTable.h:
|
||||
* Headers/gnustep/base/NSMapTable.h:
|
||||
* Source/GSArray.m:
|
||||
* Source/GSSet.m:
|
||||
* Source/GSTcpPort.m:
|
||||
* Source/NSBundle.m:
|
||||
* Source/NSConnection.m:
|
||||
* Source/NSData.m:
|
||||
* Source/NSHashTable.m:
|
||||
* Source/NSMapTable.m:
|
||||
* Source/NSObject.m:
|
||||
* Source/NSRunLoop.m:
|
||||
Applied patches by James Knight, to improve memory efficiency and
|
||||
insertion.deletion speed to hash and map tables. Also fixes for
|
||||
some GC problems.
|
||||
Fixed minor problem in patch, and added code to call functions to
|
||||
clean up after hash and map enumerations. Modified cleanup function
|
||||
to clear enumerator ... for memory release on GC system.
|
||||
*WARNING* This introduces a binary incompatibility in that the size
|
||||
of the map table and hash table enumeration types has grown.
|
||||
If you have binaries which use the NSEnumerateHashTable() or the
|
||||
NSEnumeratemapTable() functions, you need to rebuild them.
|
||||
|
||||
2002-05-27 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/GSMime.h: Tidy up and add convenience methods.
|
||||
|
|
|
@ -132,6 +132,15 @@
|
|||
*/
|
||||
#include <base/GSUnion.h>
|
||||
|
||||
|
||||
#if (GSI_MAP_KTYPES) & GSUNION_OBJ
|
||||
#define GSI_MAP_CLEAR_KEY(node) node->key.obj = nil
|
||||
#elif (GSI_MAP_KTYPES) & GSUNION_PTR
|
||||
#define GSI_MAP_CLEAR_KEY(node) node->key.ptr = 0
|
||||
#else
|
||||
#define GSI_MAP_CLEAR_KEY(node)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there is no bitmask defined to supply the types that
|
||||
* may be used as values in the map, default to permitting all types.
|
||||
|
@ -172,6 +181,14 @@
|
|||
*/
|
||||
#include <base/GSUnion.h>
|
||||
|
||||
#if (GSI_MAP_VTYPES) & GSUNION_OBJ
|
||||
#define GSI_MAP_CLEAR_VAL(node) node->value.obj = nil
|
||||
#elif (GSI_MAP_VTYPES) & GSUNION_PTR
|
||||
#define GSI_MAP_CLEAR_VAL(node) node->value.ptr = 0
|
||||
#else
|
||||
#define GSI_MAP_CLEAR_VAL(node)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _GSIMapTable GSIMapTable_t;
|
||||
typedef struct _GSIMapBucket GSIMapBucket_t;
|
||||
|
@ -183,7 +200,6 @@ typedef GSIMapNode_t *GSIMapNode;
|
|||
|
||||
struct _GSIMapNode {
|
||||
GSIMapNode nextInBucket; /* Linked list of bucket. */
|
||||
GSIMapNode nextInMap; /* For enumerating. */
|
||||
GSIMapKey key;
|
||||
#if GSI_MAP_HAS_VALUE
|
||||
GSIMapVal value;
|
||||
|
@ -198,7 +214,6 @@ struct _GSIMapBucket {
|
|||
struct _GSIMapTable {
|
||||
NSZone *zone;
|
||||
size_t nodeCount; /* Number of nodes in map. */
|
||||
GSIMapNode firstNode; /* List for enumerating. */
|
||||
size_t bucketCount; /* Number of buckets in map. */
|
||||
GSIMapBucket buckets; /* Array of buckets. */
|
||||
GSIMapNode freeNodes; /* List of unused nodes. */
|
||||
|
@ -215,6 +230,7 @@ typedef GSI_MAP_ENUMERATOR GSIMapEnumerator_t;
|
|||
struct _GSIMapEnumerator {
|
||||
GSIMapTable map; /* the map being enumerated. */
|
||||
GSIMapNode node; /* The next node to use. */
|
||||
size_t bucket; /* The next bucket to use. */
|
||||
};
|
||||
typedef struct _GSIMapEnumerator GSIMapEnumerator_t;
|
||||
#endif
|
||||
|
@ -260,33 +276,6 @@ GSIMapUnlinkNodeFromBucket(GSIMapBucket bucket, GSIMapNode node)
|
|||
node->nextInBucket = 0;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
GSIMapLinkNodeIntoMap(GSIMapTable map, GSIMapNode node)
|
||||
{
|
||||
node->nextInMap = map->firstNode;
|
||||
map->firstNode = node;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
GSIMapUnlinkNodeFromMap(GSIMapTable map, GSIMapNode node)
|
||||
{
|
||||
if (node == map->firstNode)
|
||||
{
|
||||
map->firstNode = node->nextInMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSIMapNode tmp = map->firstNode;
|
||||
|
||||
while (tmp->nextInMap != node)
|
||||
{
|
||||
tmp = tmp->nextInMap;
|
||||
}
|
||||
tmp->nextInMap = node->nextInMap;
|
||||
}
|
||||
node->nextInMap = 0;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
GSIMapAddNodeToBucket(GSIMapBucket bucket, GSIMapNode node)
|
||||
{
|
||||
|
@ -301,7 +290,6 @@ GSIMapAddNodeToMap(GSIMapTable map, GSIMapNode node)
|
|||
|
||||
bucket = GSIMapBucketForKey(map, node->key);
|
||||
GSIMapAddNodeToBucket(bucket, node);
|
||||
GSIMapLinkNodeIntoMap(map, node);
|
||||
map->nodeCount++;
|
||||
}
|
||||
|
||||
|
@ -316,7 +304,6 @@ static INLINE void
|
|||
GSIMapRemoveNodeFromMap(GSIMapTable map, GSIMapBucket bkt, GSIMapNode node)
|
||||
{
|
||||
map->nodeCount--;
|
||||
GSIMapUnlinkNodeFromMap(map, node);
|
||||
GSIMapRemoveNodeFromBucket(bkt, node);
|
||||
}
|
||||
|
||||
|
@ -394,10 +381,10 @@ GSIMapMoreNodes(GSIMapTable map, unsigned required)
|
|||
if (newNodes)
|
||||
{
|
||||
map->nodeChunks[map->chunkCount++] = newNodes;
|
||||
newNodes[--chunkCount].nextInMap = map->freeNodes;
|
||||
newNodes[--chunkCount].nextInBucket = map->freeNodes;
|
||||
while (chunkCount--)
|
||||
{
|
||||
newNodes[chunkCount].nextInMap = &newNodes[chunkCount+1];
|
||||
newNodes[chunkCount].nextInBucket = &newNodes[chunkCount+1];
|
||||
}
|
||||
map->freeNodes = newNodes;
|
||||
}
|
||||
|
@ -420,11 +407,10 @@ GSIMapNewNode(GSIMapTable map, GSIMapKey key, GSIMapVal value)
|
|||
}
|
||||
}
|
||||
|
||||
map->freeNodes = node->nextInMap;
|
||||
map->freeNodes = node->nextInBucket;
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
node->nextInBucket = 0;
|
||||
node->nextInMap = 0;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -444,10 +430,9 @@ GSIMapNewNode(GSIMapTable map, GSIMapKey key)
|
|||
}
|
||||
}
|
||||
|
||||
map->freeNodes = node->nextInMap;
|
||||
map->freeNodes = node->nextInBucket;
|
||||
node->key = key;
|
||||
node->nextInBucket = 0;
|
||||
node->nextInMap = 0;
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
|
@ -456,10 +441,13 @@ static INLINE void
|
|||
GSIMapFreeNode(GSIMapTable map, GSIMapNode node)
|
||||
{
|
||||
GSI_MAP_RELEASE_KEY(map, node->key);
|
||||
GSI_MAP_CLEAR_KEY(node);
|
||||
#if GSI_MAP_HAS_VALUE
|
||||
GSI_MAP_RELEASE_VAL(map, node->value);
|
||||
GSI_MAP_CLEAR_VAL(node);
|
||||
#endif
|
||||
node->nextInMap = map->freeNodes;
|
||||
|
||||
node->nextInBucket = map->freeNodes;
|
||||
map->freeNodes = node;
|
||||
}
|
||||
|
||||
|
@ -592,7 +580,8 @@ GSIMapEnumeratorForMap(GSIMapTable map)
|
|||
GSIMapEnumerator_t enumerator;
|
||||
|
||||
enumerator.map = map;
|
||||
enumerator.node = map->firstNode;
|
||||
enumerator.node = 0;
|
||||
enumerator.bucket = 0;
|
||||
|
||||
return enumerator;
|
||||
}
|
||||
|
@ -601,11 +590,16 @@ static INLINE GSIMapNode
|
|||
GSIMapEnumeratorNextNode(GSIMapEnumerator enumerator)
|
||||
{
|
||||
GSIMapNode node;
|
||||
|
||||
int bucketCount = ((GSIMapTable)enumerator->map)->bucketCount;
|
||||
node = enumerator->node;
|
||||
|
||||
while(!node && enumerator->bucket < bucketCount)
|
||||
{
|
||||
node = (((GSIMapTable)enumerator->map)->buckets[enumerator->bucket]).firstNode;
|
||||
enumerator->bucket++;
|
||||
}
|
||||
if (node != 0)
|
||||
enumerator->node = node->nextInMap;
|
||||
enumerator->node = node->nextInBucket;
|
||||
|
||||
/* Send back NODE. */
|
||||
return node;
|
||||
|
@ -680,17 +674,13 @@ static INLINE void
|
|||
GSIMapRemoveKey(GSIMapTable map, GSIMapKey key)
|
||||
{
|
||||
GSIMapBucket bucket = GSIMapBucketForKey(map, key);
|
||||
|
||||
if (bucket != 0)
|
||||
GSIMapNode node;
|
||||
|
||||
node = GSIMapNodeForKeyInBucket(map, bucket, key);
|
||||
if (node != 0)
|
||||
{
|
||||
GSIMapNode node;
|
||||
|
||||
node = GSIMapNodeForKeyInBucket(map, bucket, key);
|
||||
if (node != 0)
|
||||
{
|
||||
GSIMapRemoveNodeFromMap(map, bucket, node);
|
||||
GSIMapFreeNode(map, node);
|
||||
}
|
||||
GSIMapRemoveNodeFromMap(map, bucket, node);
|
||||
GSIMapFreeNode(map, node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,35 +691,36 @@ GSIMapCleanMap(GSIMapTable map)
|
|||
{
|
||||
GSIMapBucket bucket = map->buckets;
|
||||
int i;
|
||||
GSIMapNode start = map->firstNode;
|
||||
GSIMapNode node = start;
|
||||
unsigned int end = map->nodeCount - 1;
|
||||
|
||||
GSIMapNode startNode = 0;
|
||||
GSIMapNode prevNode = 0;
|
||||
GSIMapNode node;
|
||||
|
||||
map->nodeCount = 0;
|
||||
map->firstNode = 0;
|
||||
for (i = 0; i < map->bucketCount; i++)
|
||||
{
|
||||
node = bucket->firstNode;
|
||||
if(prevNode)
|
||||
prevNode->nextInBucket = node;
|
||||
else
|
||||
startNode = node;
|
||||
while(node != 0)
|
||||
{
|
||||
GSI_MAP_RELEASE_KEY(map, node->key);
|
||||
|
||||
#if GSI_MAP_HAS_VALUE
|
||||
GSI_MAP_RELEASE_VAL(map, node->value);
|
||||
#endif
|
||||
prevNode = node;
|
||||
node = node->nextInBucket;
|
||||
}
|
||||
bucket->nodeCount = 0;
|
||||
bucket->firstNode = 0;
|
||||
bucket++;
|
||||
}
|
||||
for (i = 0; i < end; i++)
|
||||
{
|
||||
GSI_MAP_RELEASE_KEY(map, node->key);
|
||||
#if GSI_MAP_HAS_VALUE
|
||||
GSI_MAP_RELEASE_VAL(map, node->value);
|
||||
#endif
|
||||
node->nextInBucket = 0;
|
||||
node = node->nextInMap;
|
||||
}
|
||||
GSI_MAP_RELEASE_KEY(map, node->key);
|
||||
#if GSI_MAP_HAS_VALUE
|
||||
GSI_MAP_RELEASE_VAL(map, node->value);
|
||||
#endif
|
||||
node->nextInBucket = 0;
|
||||
node->nextInMap = map->freeNodes;
|
||||
map->freeNodes = start;
|
||||
}
|
||||
|
||||
prevNode->nextInBucket = map->freeNodes;
|
||||
map->freeNodes = startNode;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
|
@ -740,7 +731,6 @@ GSIMapEmptyMap(GSIMapTable map)
|
|||
#ifdef GSI_MAP_NOCLEAN
|
||||
if (GSI_MAP_NOCLEAN)
|
||||
{
|
||||
map->firstNode = 0;
|
||||
map->nodeCount = 0;
|
||||
}
|
||||
else
|
||||
|
@ -776,7 +766,6 @@ GSIMapInitWithZoneAndCapacity(GSIMapTable map, NSZone *zone, size_t capacity)
|
|||
map->zone = zone;
|
||||
map->nodeCount = 0;
|
||||
map->bucketCount = 0;
|
||||
map->firstNode = 0;
|
||||
map->buckets = 0;
|
||||
map->nodeChunks = 0;
|
||||
map->freeNodes = 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef void* NSHashTable;
|
|||
* Type for enumerating.
|
||||
* NB. layout *must* correspond to that used by the GSIMap code.
|
||||
*/
|
||||
typedef struct { void *map; void *node; } NSHashEnumerator;
|
||||
typedef struct { void *map; void *node; size_t bucket; } NSHashEnumerator;
|
||||
|
||||
/** Callback functions. <br />*/
|
||||
typedef struct _NSHashTableCallBacks
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef void *NSMapTable;
|
|||
* Type for enumerating.
|
||||
* NB. layout *must* correspond to that used by the GSIMap code.
|
||||
*/
|
||||
typedef struct { void *map; void *node; } NSMapEnumerator;
|
||||
typedef struct { void *map; void *node; size_t bucket; } NSMapEnumerator;
|
||||
|
||||
/* Callback functions for a key. */
|
||||
typedef struct _NSMapTableKeyCallBacks
|
||||
|
|
|
@ -3029,7 +3029,7 @@ static NSCharacterSet *tokenSet = nil;
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience method to set the content of the document aslong with
|
||||
* Convenience method to set the content of the document along with
|
||||
* creating a content-type header for it.
|
||||
*/
|
||||
- (BOOL) setContent: (id)newContent
|
||||
|
|
|
@ -464,6 +464,7 @@ static SEL eqSel;
|
|||
}
|
||||
_count--;
|
||||
RELEASE(_contents_array[_count]);
|
||||
_contents_array[_count] = 0;
|
||||
}
|
||||
|
||||
- (void) removeObject: (id)anObject
|
||||
|
@ -504,6 +505,7 @@ static SEL eqSel;
|
|||
_contents_array[pos-1] = _contents_array[pos];
|
||||
}
|
||||
_count--;
|
||||
_contents_array[_count] = 0;
|
||||
RELEASE(obj);
|
||||
}
|
||||
}
|
||||
|
@ -533,6 +535,7 @@ static SEL eqSel;
|
|||
_contents_array[index] = _contents_array[index+1];
|
||||
index++;
|
||||
}
|
||||
_contents_array[_count] = 0;
|
||||
RELEASE(obj); /* Adjust array BEFORE releasing object. */
|
||||
}
|
||||
|
||||
|
@ -560,6 +563,7 @@ static SEL eqSel;
|
|||
_contents_array[pos-1] = _contents_array[pos];
|
||||
}
|
||||
_count--;
|
||||
_contents_array[_count] = 0;
|
||||
RELEASE(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,12 @@ static Class mutableSetClass;
|
|||
{
|
||||
if (map.nodeCount > 0)
|
||||
{
|
||||
return map.firstNode->key.obj;
|
||||
GSIMapBucket bucket = map.buckets;
|
||||
while(1)
|
||||
if(bucket->firstNode)
|
||||
return bucket->firstNode->key.obj;
|
||||
else
|
||||
bucket++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1285,9 +1285,12 @@ static Class tcpPortClass;
|
|||
h->myLock = [NSRecursiveLock new];
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&hEnum);
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&mEnum);
|
||||
}
|
||||
NSEndMapTableEnumeration(&pEnum);
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
|
@ -1656,6 +1659,7 @@ static Class tcpPortClass;
|
|||
fds[(*count)++] = sock;
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&me);
|
||||
DO_UNLOCK(myLock);
|
||||
}
|
||||
|
||||
|
@ -1675,9 +1679,11 @@ static Class tcpPortClass;
|
|||
if ([handle recvPort] == recvPort)
|
||||
{
|
||||
DO_UNLOCK(myLock);
|
||||
NSEndMapTableEnumeration(&me);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&me);
|
||||
if (handle == nil)
|
||||
{
|
||||
int opt = 1;
|
||||
|
|
|
@ -517,13 +517,15 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
|||
while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle))
|
||||
{
|
||||
if (bundle->_bundleType == NSBUNDLE_FRAMEWORK)
|
||||
continue;
|
||||
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ([array indexOfObjectIdenticalTo: bundle] == NSNotFound)
|
||||
{
|
||||
[array addObject: bundle];
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerate);
|
||||
}
|
||||
[load_lock unlock];
|
||||
return array;
|
||||
|
@ -546,6 +548,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
|||
[array addObject: bundle];
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerate);
|
||||
[load_lock unlock];
|
||||
return array;
|
||||
}
|
||||
|
|
|
@ -292,6 +292,7 @@ existingConnection(NSPort *receivePort, NSPort *sendPort)
|
|||
break;
|
||||
}
|
||||
}
|
||||
NSEndHashTableEnumeration(&enumerator);
|
||||
F_UNLOCK(connection_table_gate);
|
||||
return c;
|
||||
}
|
||||
|
@ -381,6 +382,7 @@ static BOOL multi_threaded = NO;
|
|||
c->_refGate = [NSRecursiveLock new];
|
||||
}
|
||||
}
|
||||
NSEndHashTableEnumeration(&enumerator);
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
|
@ -2067,6 +2069,7 @@ static void retEncoder (DOContext *ctxt)
|
|||
count++;
|
||||
}
|
||||
}
|
||||
NSEndHashTableEnumeration(&enumerator);
|
||||
M_UNLOCK(connection_table_gate);
|
||||
|
||||
return count;
|
||||
|
|
|
@ -977,7 +977,7 @@ failure:
|
|||
#if GS_WITH_GC == 0
|
||||
*(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len);
|
||||
#else
|
||||
*(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len);
|
||||
*(char**)data = (char*)NSZoneMalloc(GSAtomicMallocZone(), len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1044,7 @@ failure:
|
|||
#if GS_WITH_GC == 0
|
||||
*(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len);
|
||||
#else
|
||||
*(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len);
|
||||
*(char**)data = (char*)NSZoneMalloc(GSAtomicMallocZone(), len);
|
||||
#endif
|
||||
[self deserializeDataAt: *(char**)data
|
||||
ofObjCType: type
|
||||
|
@ -2096,7 +2096,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
|
|||
#if GS_WITH_GC == 0
|
||||
*(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len+1);
|
||||
#else
|
||||
*(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len+1);
|
||||
*(char**)data = (char*)NSZoneMalloc(GSAtomicMallocZone(), len+1);
|
||||
#endif
|
||||
}
|
||||
getBytes(*(void**)data, bytes, len, length, cursor);
|
||||
|
@ -2160,7 +2160,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
|
|||
#if GS_WITH_GC == 0
|
||||
*(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len);
|
||||
#else
|
||||
*(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len);
|
||||
*(char**)data = (char*)NSZoneMalloc(GSAtomicMallocZone(), len);
|
||||
#endif
|
||||
[self deserializeDataAt: *(char**)data
|
||||
ofObjCType: type
|
||||
|
|
|
@ -122,15 +122,14 @@ NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
|
|||
}
|
||||
else
|
||||
{
|
||||
GSIMapNode n = t1->firstNode;
|
||||
|
||||
while (n != 0)
|
||||
{
|
||||
NSHashEnumerator enumerator = GSIMapEnumeratorForMap((GSIMapTable)t1);
|
||||
GSIMapNode n;
|
||||
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
{
|
||||
if (GSIMapNodeForKey(t2, n->key) == 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
n = n->nextInMap;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
@ -144,7 +143,8 @@ NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone)
|
|||
{
|
||||
GSIMapTable t;
|
||||
GSIMapNode n;
|
||||
|
||||
NSHashEnumerator enumerator;
|
||||
|
||||
if (table == 0)
|
||||
{
|
||||
NSWarnFLog(@"Nul table argument supplied");
|
||||
|
@ -154,11 +154,10 @@ NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone)
|
|||
t = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
||||
GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount);
|
||||
t->extra = ((GSIMapTable)table)->extra;
|
||||
n = ((GSIMapTable)table)->firstNode;
|
||||
while (n != 0)
|
||||
enumerator = GSIMapEnumeratorForMap((GSIMapTable)table);
|
||||
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
{
|
||||
GSIMapAddKey(t, n->key);
|
||||
n = n->nextInMap;
|
||||
}
|
||||
|
||||
return (NSHashTable*)t;
|
||||
|
@ -225,7 +224,7 @@ NSCreateHashTableWithZone(
|
|||
|
||||
/**
|
||||
* Function to be called when finished with the enumerator.
|
||||
* Not required in GNUstep ... just provided for MacOS-X compatibility.
|
||||
* This permits memory used by the enumerator to be released.
|
||||
*/
|
||||
void
|
||||
NSEndHashTableEnumeration(NSHashEnumerator *enumerator)
|
||||
|
@ -233,7 +232,11 @@ NSEndHashTableEnumeration(NSHashEnumerator *enumerator)
|
|||
if (enumerator == 0)
|
||||
{
|
||||
NSWarnFLog(@"Nul enumerator argument supplied");
|
||||
return;
|
||||
}
|
||||
#if GS_WITH_GC
|
||||
memset(enumerator, 0, sizeof(*enumerator));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +248,7 @@ NSEnumerateHashTable(NSHashTable *table)
|
|||
{
|
||||
if (table == 0)
|
||||
{
|
||||
NSHashEnumerator v = { 0, 0 };
|
||||
NSHashEnumerator v = { 0, 0, 0 };
|
||||
|
||||
NSWarnFLog(@"Nul table argument supplied");
|
||||
return v;
|
||||
|
|
|
@ -99,6 +99,7 @@ NSAllMapTableKeys(NSMapTable *table)
|
|||
{
|
||||
[keyArray addObject: key];
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
return keyArray;
|
||||
}
|
||||
|
||||
|
@ -131,6 +132,7 @@ NSAllMapTableValues(NSMapTable *table)
|
|||
{
|
||||
[valueArray addObject: value];
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
return valueArray;
|
||||
}
|
||||
|
||||
|
@ -169,16 +171,15 @@ NSCompareMapTables(NSMapTable *table1, NSMapTable *table2)
|
|||
}
|
||||
else
|
||||
{
|
||||
GSIMapNode n = t1->firstNode;
|
||||
|
||||
while (n != 0)
|
||||
{
|
||||
if (GSIMapNodeForKey(t2, n->key) == 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
n = n->nextInMap;
|
||||
}
|
||||
NSMapEnumerator enumerator = GSIMapEnumeratorForMap((GSIMapTable)t1);
|
||||
GSIMapNode n;
|
||||
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
{
|
||||
if (GSIMapNodeForKey(t2, n->key) == 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +192,8 @@ NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone)
|
|||
{
|
||||
GSIMapTable t;
|
||||
GSIMapNode n;
|
||||
|
||||
NSMapEnumerator enumerator;
|
||||
|
||||
if (table == 0)
|
||||
{
|
||||
NSWarnFLog(@"Nul table argument supplied");
|
||||
|
@ -202,11 +204,10 @@ NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone)
|
|||
GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount);
|
||||
t->extra.k = ((GSIMapTable)table)->extra.k;
|
||||
t->extra.v = ((GSIMapTable)table)->extra.v;
|
||||
n = ((GSIMapTable)table)->firstNode;
|
||||
while (n != 0)
|
||||
enumerator = GSIMapEnumeratorForMap((GSIMapTable)table);
|
||||
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
{
|
||||
GSIMapAddPair(t, n->key, n->value);
|
||||
n = n->nextInMap;
|
||||
}
|
||||
|
||||
return (NSMapTable*)t;
|
||||
|
@ -284,7 +285,7 @@ NSCreateMapTableWithZone(
|
|||
|
||||
/**
|
||||
* Function to be called when finished with the enumerator.
|
||||
* Not required in GNUstep ... just provided for MacOS-X compatibility.
|
||||
* This permits memory used by the enumerator to be released!
|
||||
*/
|
||||
void
|
||||
NSEndMapTableEnumeration(NSMapEnumerator *enumerator)
|
||||
|
@ -292,7 +293,11 @@ NSEndMapTableEnumeration(NSMapEnumerator *enumerator)
|
|||
if (enumerator == 0)
|
||||
{
|
||||
NSWarnFLog(@"Nul enumerator argument supplied");
|
||||
return;
|
||||
}
|
||||
#if GS_WITH_GC
|
||||
memset(enumerator, 0, sizeof(*enumerator));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -608,6 +613,7 @@ NSStringFromMapTable(NSMapTable *table)
|
|||
(t->extra.k.describe)(table, key),
|
||||
(t->extra.v.describe)(table, value)];
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,11 @@
|
|||
extern BOOL __objc_responds_to(id, SEL);
|
||||
#endif
|
||||
|
||||
#if GS_WITH_GC == 0
|
||||
@class _FastMallocBuffer;
|
||||
static Class fastMallocClass;
|
||||
static unsigned fastMallocOffset;
|
||||
#endif
|
||||
|
||||
static Class NSConstantStringClass;
|
||||
|
||||
|
@ -726,15 +728,13 @@ static BOOL double_release_check_enabled = NO;
|
|||
autorelease_class = [NSAutoreleasePool class];
|
||||
autorelease_sel = @selector(addObject:);
|
||||
autorelease_imp = [autorelease_class methodForSelector: autorelease_sel];
|
||||
fastMallocClass = [_FastMallocBuffer class];
|
||||
#if GS_WITH_GC == 0
|
||||
fastMallocClass = [_FastMallocBuffer class];
|
||||
#if !defined(REFCNT_LOCAL)
|
||||
GSIMapInitWithZoneAndCapacity(&retain_counts,
|
||||
NSDefaultMallocZone(), 1024);
|
||||
#endif
|
||||
fastMallocOffset = fastMallocClass->instance_size % ALIGN;
|
||||
#else
|
||||
fastMallocOffset = 0;
|
||||
#endif
|
||||
NSConstantStringClass = [NSString constantStringClass];
|
||||
GSBuildStrings();
|
||||
|
@ -1584,11 +1584,13 @@ static BOOL double_release_check_enabled = NO;
|
|||
/*
|
||||
* Stuff for temporary memory management.
|
||||
*/
|
||||
#if GS_WITH_GC == 0
|
||||
@interface _FastMallocBuffer : NSObject
|
||||
@end
|
||||
|
||||
@implementation _FastMallocBuffer
|
||||
@end
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Function for giving us the fastest possible allocation of memory to
|
||||
|
@ -1597,12 +1599,16 @@ static BOOL double_release_check_enabled = NO;
|
|||
void *
|
||||
_fastMallocBuffer(unsigned size)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
return GC_malloc(size);
|
||||
#else
|
||||
_FastMallocBuffer *o;
|
||||
|
||||
o = (_FastMallocBuffer*)NSAllocateObject(fastMallocClass,
|
||||
size + fastMallocOffset, NSDefaultMallocZone());
|
||||
(*autorelease_imp)(autorelease_class, autorelease_sel, o);
|
||||
return ((void*)&o[1])+fastMallocOffset;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1382,6 +1382,7 @@ if (0) {
|
|||
}
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
|
||||
/*
|
||||
* Finally, fire the requests.
|
||||
|
@ -2115,6 +2116,7 @@ if (0) {
|
|||
}
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
}
|
||||
|
||||
- (void) configureAsServer
|
||||
|
|
Loading…
Reference in a new issue