X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStable.c;h=a4db5cd749de174afa28a9a89b2b8d8d35fe8ed0;hb=0dbbf1932d550293986af6244202cb735b2cd966;hp=818f0f09b5a22e64429bf7245e4cb4e7455c1bf0;hpb=a141bd3ba4a1adbace30ac6c625ff9defca62b07;p=ghc-hetmet.git diff --git a/ghc/rts/Stable.c b/ghc/rts/Stable.c index 818f0f0..a4db5cd 100644 --- a/ghc/rts/Stable.c +++ b/ghc/rts/Stable.c @@ -80,7 +80,9 @@ static snEntry *stable_ptr_free = NULL; static unsigned int SPT_size = 0; +#ifdef THREADED_RTS static Mutex stable_mutex; +#endif /* This hash table maps Haskell objects to stable names, so that every * call to lookupStableName on a given object will return the same @@ -137,13 +139,23 @@ initFreeList(snEntry *table, nat n, snEntry *free) void initStablePtrTable(void) { - // Nothing to do: - // the table will be allocated the first time makeStablePtr is - // called, and we want the table to persist through multiple inits. - // - // Also, getStablePtr is now called from __attribute__((constructor)) - // functions, so initialising things here wouldn't work anyway. + if (SPT_size > 0) + return; + + SPT_size = INIT_SPT_SIZE; + stable_ptr_table = stgMallocBytes(SPT_size * sizeof(snEntry), + "initStablePtrTable"); + + /* we don't use index 0 in the stable name table, because that + * would conflict with the hash table lookup operations which + * return NULL if an entry isn't found in the hash table. + */ + initFreeList(stable_ptr_table+1,INIT_SPT_SIZE-1,NULL); + addrToStableHash = allocHashTable(); + +#ifdef THREADED_RTS initMutex(&stable_mutex); +#endif } /* @@ -188,7 +200,6 @@ lookupStableName_(StgPtr p) if (sn != 0) { ASSERT(stable_ptr_table[sn].addr == p); IF_DEBUG(stable,debugBelch("cached stable name %ld at %p\n",sn,p)); - RELEASE_LOCK(&stable_mutex); return sn; } else { sn = stable_ptr_free - stable_ptr_table; @@ -209,6 +220,8 @@ StgWord lookupStableName(StgPtr p) { StgWord res; + + initStablePtrTable(); ACQUIRE_LOCK(&stable_mutex); res = lookupStableName_(p); RELEASE_LOCK(&stable_mutex); @@ -231,6 +244,7 @@ getStablePtr(StgPtr p) { StgWord sn; + initStablePtrTable(); ACQUIRE_LOCK(&stable_mutex); sn = lookupStableName_(p); stable_ptr_table[sn].ref++; @@ -243,6 +257,7 @@ freeStablePtr(StgStablePtr sp) { snEntry *sn; + initStablePtrTable(); ACQUIRE_LOCK(&stable_mutex); sn = &stable_ptr_table[(StgWord)sp]; @@ -265,30 +280,15 @@ void enlargeStablePtrTable(void) { nat old_SPT_size = SPT_size; - - if (SPT_size == 0) { - // 1st time - SPT_size = INIT_SPT_SIZE; - stable_ptr_table = stgMallocBytes(SPT_size * sizeof(snEntry), - "enlargeStablePtrTable"); - - /* we don't use index 0 in the stable name table, because that - * would conflict with the hash table lookup operations which - * return NULL if an entry isn't found in the hash table. - */ - initFreeList(stable_ptr_table+1,INIT_SPT_SIZE-1,NULL); - addrToStableHash = allocHashTable(); - } - else { + // 2nd and subsequent times - SPT_size *= 2; - stable_ptr_table = - stgReallocBytes(stable_ptr_table, + SPT_size *= 2; + stable_ptr_table = + stgReallocBytes(stable_ptr_table, SPT_size * sizeof(snEntry), "enlargeStablePtrTable"); - initFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); - } + initFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); } /* -----------------------------------------------------------------------------