[project @ 2001-11-21 10:09:15 by simonmar]
authorsimonmar <unknown>
Wed, 21 Nov 2001 10:09:16 +0000 (10:09 +0000)
committersimonmar <unknown>
Wed, 21 Nov 2001 10:09:16 +0000 (10:09 +0000)
Turn the weighted reference count in a StablePtr into a simple counter
in the stable ptr table.  We never made use of the weighted count, and
it caused problems when making many StablePtrs to the same object.

In the future we could remove the reference counting altogether and
just make a new StablePtr each time, rather than attempting to use an
existing one.  This would save on the hash table lookup at creation
time.

ghc/includes/Stable.h
ghc/rts/Stable.c

index 9c1bfea..241f42b 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Stable.h,v 1.9 2001/10/23 11:28:02 simonmar Exp $
+ * $Id: Stable.h,v 1.10 2001/11/21 10:09:15 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2000
  *
@@ -14,9 +14,6 @@
  *
  * ----------------------------------------------------------------------------*/
 
-#define STABLEPTR_WEIGHT_MASK   ((StgWord)0xff << ((sizeof(StgWord)-1) * BITS_PER_BYTE))
-#define STABLEPTR_WEIGHT_SHIFT  (BITS_IN(StgWord) - 8)
-
 /* -----------------------------------------------------------------------------
    External C Interface
    -------------------------------------------------------------------------- */
@@ -33,7 +30,7 @@ extern StgStablePtr   getStablePtr(StgPtr p);
 typedef struct { 
   StgPtr  addr;                        /* Haskell object, free list, or NULL */
   StgPtr  old;                 /* old Haskell object, used during GC */
-  StgWord weight;              /* used for reference counting */
+  StgWord ref;                 /* used for reference counting */
   StgClosure *sn_obj;          /* the StableName object (or NULL) */
 } snEntry;
 
@@ -45,29 +42,27 @@ extern DLL_IMPORT_RTS unsigned int SPT_size;
 extern inline StgPtr
 deRefStablePtr(StgStablePtr sp)
 {
-  ASSERT(stable_ptr_table[stgCast(StgWord,sp) & ~STABLEPTR_WEIGHT_MASK].weight > 0);
-  return stable_ptr_table[stgCast(StgWord,sp) & ~STABLEPTR_WEIGHT_MASK].addr;
+    ASSERT(stable_ptr_table[(StgWord)sp].ref > 0);
+    return stable_ptr_table[(StgWord)sp].addr;
 }
-
+    
 extern inline void
 freeStablePtr(StgStablePtr sp)
 {
-  StgWord sn = stgCast(StgWord,sp) & ~STABLEPTR_WEIGHT_MASK;
-  
-  ASSERT(sn < SPT_size
-        && stable_ptr_table[sn].addr != NULL
-        && stable_ptr_table[sn].weight > 0);
-  
-  stable_ptr_table[sn].weight += 
-      1 << ((((StgWord)sp & STABLEPTR_WEIGHT_MASK) >> STABLEPTR_WEIGHT_SHIFT) - 1);
+    StgWord sn = (StgWord)sp;
+    
+    ASSERT(sn < SPT_size
+          && stable_ptr_table[sn].addr != NULL
+          && stable_ptr_table[sn].ref > 0);
+    
+    stable_ptr_table[sn].ref --;
 }
 
 extern inline StgStablePtr
 splitStablePtr(StgStablePtr sp)
 {
-  /* doesn't need access to the stable pointer table */
-  StgWord weight = (stgCast(StgWord,sp) & STABLEPTR_WEIGHT_MASK) / 2;
-  return stgCast(StgStablePtr,(stgCast(StgWord,sp) & ~STABLEPTR_WEIGHT_MASK) + weight);
+    stable_ptr_table[(StgWord)sp].ref ++;
+    return sp;
 }
 
 /* No deRefStableName, because the existence of a stable name doesn't
index 52876bd..f73b5ea 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Stable.c,v 1.17 2001/08/14 13:40:09 sewardj Exp $
+ * $Id: Stable.c,v 1.18 2001/11/21 10:09:16 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -96,6 +96,9 @@ unsigned int SPT_size;
  * call to lookupStableName on a given object will return the same
  * stable name.
  *
+ * OLD COMMENTS about reference counting follow.  The reference count
+ * in a stable name entry is now just a counter.
+ *
  * Reference counting
  * ------------------
  * A plain stable name entry has a zero reference count, which means
@@ -134,7 +137,7 @@ initFreeList(snEntry *table, nat n, snEntry *free)
   for (p = table + n - 1; p >= table; p--) {
     p->addr   = (P_)free;
     p->old    = NULL;
-    p->weight = 0;
+    p->ref    = 0;
     p->sn_obj = NULL;
     free = p;
   }
@@ -196,7 +199,7 @@ lookupStableName(StgPtr p)
   } else {
     sn = stable_ptr_free - stable_ptr_table;
     (P_)stable_ptr_free  = stable_ptr_free->addr;
-    stable_ptr_table[sn].weight = 0;
+    stable_ptr_table[sn].ref = 0;
     stable_ptr_table[sn].addr = p;
     stable_ptr_table[sn].sn_obj = NULL;
     /* IF_DEBUG(stable,fprintf(stderr,"new stable name %d at
@@ -214,7 +217,7 @@ freeStableName(snEntry *sn)
 {
   ASSERT(sn->sn_obj == NULL);
   if (sn->addr != NULL) {
-    removeHashTable(addrToStableHash, (W_)sn->addr, NULL);
+      removeHashTable(addrToStableHash, (W_)sn->addr, NULL);
   }
   sn->addr = (P_)stable_ptr_free;
   stable_ptr_free = sn;
@@ -223,26 +226,11 @@ freeStableName(snEntry *sn)
 StgStablePtr
 getStablePtr(StgPtr p)
 {
-  StgWord sn = lookupStableName(p);
-  StgWord weight, n;
-  weight = stable_ptr_table[sn].weight;
-  if (weight == 0) {
-    weight = (StgWord)1 << (BITS_IN(StgWord)-1);
-    stable_ptr_table[sn].weight = weight;
-    return (StgStablePtr)(sn + (BITS_IN(StgWord) << STABLEPTR_WEIGHT_SHIFT));
-  } 
-  else if (weight == 1) {
-    barf("getStablePtr: too light");
-  } 
-  else {
-    weight /= 2;
-    /* find log2(weight) */
-    for (n = 0; weight != 1; n++) {
-      weight >>= 1;
-    }
-    stable_ptr_table[sn].weight -= 1 << n;
-    return (StgStablePtr)(sn + ((n+1) << STABLEPTR_WEIGHT_SHIFT));
-  }
+  StgWord sn;
+
+  sn = lookupStableName(p);
+  stable_ptr_table[sn].ref++;
+  return (StgStablePtr)(sn);
 }
 
 void
@@ -277,7 +265,7 @@ enlargeStablePtrTable(void)
 /* -----------------------------------------------------------------------------
  * Treat stable pointers as roots for the garbage collector.
  *
- * A stable pointer is any stable name entry with a weight > 0.  We'll
+ * A stable pointer is any stable name entry with a ref > 0.  We'll
  * take the opportunity to zero the "keep" flags at the same time.
  * -------------------------------------------------------------------------- */
 
@@ -304,8 +292,8 @@ markStablePtrTable(evac_fn evac)
            // the hash table later.
            p->old = p->addr;
 
-           // if the weight is non-zero, treat addr as a root
-           if (p->weight != 0) {
+           // if the ref is non-zero, treat addr as a root
+           if (p->ref != 0) {
                evac((StgClosure **)&p->addr);
            }
        }
@@ -346,7 +334,7 @@ threadStablePtrTable( evac_fn evac )
  *
  * A dead entry has:
  *
- *          - a weight of zero (i.e. 2^32)
+ *          - a zero reference count
  *          - a dead sn_obj
  *
  * Both of these conditions must be true in order to re-use the stable
@@ -378,7 +366,7 @@ gcStablePtrTable( void )
        if (q && (q < (P_)stable_ptr_table || q >= (P_)end_stable_ptr_table)) {
 
            // StableNames only:
-           if (p->weight == 0) {
+           if (p->ref == 0) {
                if (p->sn_obj == NULL) {
                    // StableName object is dead
                    freeStableName(p);
@@ -388,7 +376,7 @@ gcStablePtrTable( void )
                    
                } else {
                    (StgClosure *)p->addr = isAlive((StgClosure *)p->addr);
-                   IF_DEBUG(stable, fprintf(stderr,"Stable name %d still alive at %p, weight %d\n", p - stable_ptr_table, p->addr, p->weight));
+                   IF_DEBUG(stable, fprintf(stderr,"Stable name %d still alive at %p, ref %d\n", p - stable_ptr_table, p->addr, p->ref));
                }
            }
        }