X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FHash.c;h=1083b8a7ccef51871cef56dae6a650498c935d48;hb=5cb4bb13a817c44cdc4369c7f82949d9490d69a0;hp=ba0746f4085056dc1502d1f405813847f194dbf6;hpb=18ea22a1d98fc9d5a12c69ed140053300fc887d5;p=ghc-hetmet.git diff --git a/ghc/rts/Hash.c b/ghc/rts/Hash.c index ba0746f..1083b8a 100644 --- a/ghc/rts/Hash.c +++ b/ghc/rts/Hash.c @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------- - * $Id: Hash.c,v 1.7 2001/11/26 13:06:49 simonmar Exp $ + * $Id: Hash.c,v 1.10 2003/03/25 17:58:47 sof Exp $ * * (c) The AQUA Project, Glasgow University, 1995-1998 * (c) The GHC Team, 1999 @@ -13,7 +13,9 @@ #include "Rts.h" #include "Hash.h" #include "RtsUtils.h" -#include "Arena.h" + +#include +#include #define HSEGSIZE 1024 /* Size of a single hash table segment */ /* Also the minimum size of a hash table */ @@ -47,7 +49,6 @@ struct hashtable { HashList **dir[HDIRSIZE]; /* Directory of segments */ HashFunction *hash; /* hash function */ CompareFunction *compare; /* key comparison function */ - Arena *arena; }; /* ----------------------------------------------------------------------------- @@ -121,6 +122,7 @@ allocSegment(HashTable *table, int segment) "allocSegment"); } + /* ----------------------------------------------------------------------------- * Expand the larger hash table by one bucket, and split one bucket * from the smaller table into two parts. Only the bucket referenced @@ -203,6 +205,39 @@ lookupHashTable(HashTable *table, StgWord key) return NULL; } +/* ----------------------------------------------------------------------------- + * We allocate the hashlist cells in large chunks to cut down on malloc + * overhead. Although we keep a free list of hashlist cells, we make + * no effort to actually return the space to the malloc arena. + * -------------------------------------------------------------------------- */ + +static HashList *freeList = NULL; + +static HashList * +allocHashList(void) +{ + HashList *hl, *p; + + if ((hl = freeList) != NULL) { + freeList = hl->next; + } else { + hl = stgMallocBytes(HCHUNK * sizeof(HashList), "allocHashList"); + + freeList = hl + 1; + for (p = freeList; p < hl + HCHUNK - 1; p++) + p->next = p + 1; + p->next = NULL; + } + return hl; +} + +static void +freeHashList(HashList *hl) +{ + hl->next = freeList; + freeList = hl; +} + void insertHashTable(HashTable *table, StgWord key, void *data) { @@ -222,7 +257,7 @@ insertHashTable(HashTable *table, StgWord key, void *data) segment = bucket / HSEGSIZE; index = bucket % HSEGSIZE; - hl = arenaAlloc(table->arena, sizeof(struct hashlist)); + hl = allocHashList(); hl->key = key; hl->data = data; @@ -250,6 +285,7 @@ removeHashTable(HashTable *table, StgWord key, void *data) table->dir[segment][index] = hl->next; else prev->next = hl->next; + freeHashList(hl); table->kcount--; return hl->data; } @@ -268,7 +304,7 @@ removeHashTable(HashTable *table, StgWord key, void *data) * -------------------------------------------------------------------------- */ void -freeHashTable( HashTable *table, void (*freeDataFun)(void *) ) +freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) { long segment; long index; @@ -278,24 +314,22 @@ freeHashTable( HashTable *table, void (*freeDataFun)(void *) ) /* The last bucket with something in it is table->max + table->split - 1 */ segment = (table->max + table->split - 1) / HSEGSIZE; index = (table->max + table->split - 1) % HSEGSIZE; - + while (segment >= 0) { - if (freeDataFun != NULL) { - while (index >= 0) { - for (hl = table->dir[segment][index]; hl != NULL; hl = next) { - next = hl->next; + while (index >= 0) { + for (hl = table->dir[segment][index]; hl != NULL; hl = next) { + next = hl->next; + if (freeDataFun != NULL) (*freeDataFun)(hl->data); - } - index--; + freeHashList(hl); } + index--; } - free(table->dir[segment]); + stgFree(table->dir[segment]); segment--; index = HSEGSIZE - 1; } - - arenaFree(table->arena); - free(table); + stgFree(table); } /* ----------------------------------------------------------------------------- @@ -311,8 +345,6 @@ allocHashTable_(HashFunction *hash, CompareFunction *compare) table = stgMallocBytes(sizeof(HashTable),"allocHashTable"); - table->arena = newArena(); - allocSegment(table, 0); for (hb = table->dir[0]; hb < table->dir[0] + HSEGSIZE; hb++)