[project @ 2000-01-13 14:33:57 by hwloidl]
[ghc-hetmet.git] / ghc / rts / Stable.c
index a429920..2d280a4 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Stable.c,v 1.6 1999/08/04 10:04:31 simonmar Exp $
+ * $Id: Stable.c,v 1.9 1999/10/26 17:15:39 sewardj Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -199,7 +199,6 @@ getStablePtr(StgPtr p)
 {
   StgWord sn = lookupStableName(p);
   StgWord weight, weight_2;
-
   weight = stable_ptr_table[sn].weight;
   if (weight == 0) {
     weight = (StgWord)1 << (BITS_IN(StgWord)-1);
@@ -231,7 +230,11 @@ enlargeStablePtrTable(void)
     stable_ptr_table = stgMallocWords(SPT_size * sizeof(snEntry), 
                                      "initStablePtrTable");
     
-    initFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL);
+    /* 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 {
@@ -269,9 +272,10 @@ markStablePtrTable(rtsBool full)
 
   end_stable_ptr_table = &stable_ptr_table[SPT_size];
 
-  /* Mark all the stable *pointers* (not stable names) 
+  /* Mark all the stable *pointers* (not stable names).
+   * _starting_ at index 1; index 0 is unused.
    */
-  for (p = stable_ptr_table; p < end_stable_ptr_table; p++) {
+  for (p = stable_ptr_table+1; p < end_stable_ptr_table; p++) {
     q = p->addr;
     /* internal pointers or NULL are free slots 
      */
@@ -285,8 +289,10 @@ markStablePtrTable(rtsBool full)
          (StgClosure *)p->addr = new;
        } else if ((P_)new != q) {
          removeHashTable(addrToStableHash, (W_)q, NULL);
-         insertHashTable(addrToStableHash, (W_)new, 
-                         (void *)(p - stable_ptr_table));
+         if (!lookupHashTable(addrToStableHash, (W_)new)) {
+           insertHashTable(addrToStableHash, (W_)new, 
+                           (void *)(p - stable_ptr_table));
+         }
          (StgClosure *)p->addr = new;
        }
        IF_DEBUG(stable, fprintf(stderr,"Stable ptr %d still alive at %p, weight %d\n", p - stable_ptr_table, new, p->weight));
@@ -326,7 +332,8 @@ gcStablePtrTable(rtsBool full)
 
   end_stable_ptr_table = &stable_ptr_table[SPT_size];
 
-  for (p = stable_ptr_table; p < end_stable_ptr_table; p++) {
+  /* NOTE: _starting_ at index 1; index 0 is unused. */
+  for (p = stable_ptr_table + 1; p < end_stable_ptr_table; p++) {
 
     /* Update the pointer to the StableName object, if there is one */
     if (p->sn_obj != NULL) {