[project @ 2001-07-22 03:28:25 by chak]
[ghc-hetmet.git] / ghc / rts / Stable.c
index d0d64dd..cc0e0b3 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Stable.c,v 1.10 2000/02/29 19:59:38 sof Exp $
+ * $Id: Stable.c,v 1.14 2001/07/13 13:41:42 rrt Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -66,7 +66,6 @@
   deRefStablePtr# :: StablePtr# a -> State# RealWorld -> 
         (# State# RealWorld, a #)
   \end{verbatim}
-  There is also a C procedure @FreeStablePtr@ which frees a stable pointer.
 
   There may be additional functions on the C side to allow evaluation,
   application, etc of a stable pointer.
@@ -107,7 +106,7 @@ unsigned int SPT_size;
  *
  * A stable pointer has a weighted reference count N attached to it
  * (actually in its upper 5 bits), which represents the weight
- * 2^N.  The stable name entry keeps a 32-bit reference count, which
+ * 2^(N-1).  The stable name entry keeps a 32-bit reference count, which
  * represents any weight between 1 and 2^32 (represented as zero).
  * When the weight is 2^32, the stable name table owns "all" of the
  * stable pointers to this object, and the entry can be garbage
@@ -163,11 +162,11 @@ removeIndirections(StgClosure* p)
 {
   StgClosure* q = p;
 
-  while (q->header.info->type == IND ||
-         q->header.info->type == IND_STATIC ||
-         q->header.info->type == IND_OLDGEN ||
-         q->header.info->type == IND_PERM ||
-         q->header.info->type == IND_OLDGEN_PERM ) {
+  while (get_itbl(q)->type == IND ||
+         get_itbl(q)->type == IND_STATIC ||
+         get_itbl(q)->type == IND_OLDGEN ||
+         get_itbl(q)->type == IND_PERM ||
+         get_itbl(q)->type == IND_OLDGEN_PERM ) {
       q = ((StgInd *)q)->indirectee;
   }
   return q;
@@ -225,12 +224,12 @@ StgStablePtr
 getStablePtr(StgPtr p)
 {
   StgWord sn = lookupStableName(p);
-  StgWord weight, weight_2;
+  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)-1) << STABLEPTR_WEIGHT_SHIFT));
+    return (StgStablePtr)(sn + (BITS_IN(StgWord) << STABLEPTR_WEIGHT_SHIFT));
   } 
   else if (weight == 1) {
     barf("getStablePtr: too light");
@@ -238,11 +237,11 @@ getStablePtr(StgPtr p)
   else {
     weight /= 2;
     /* find log2(weight) */
-    for (weight_2 = 1; weight != 1; weight_2++) {
+    for (n = 0; weight != 1; n++) {
       weight >>= 1;
     }
-    stable_ptr_table[sn].weight -= 2^weight_2;
-    return (StgStablePtr)(sn + (weight_2 << STABLEPTR_WEIGHT_SHIFT));
+    stable_ptr_table[sn].weight -= 1 << n;
+    return (StgStablePtr)(sn + ((n+1) << STABLEPTR_WEIGHT_SHIFT));
   }
 }
 
@@ -322,7 +321,7 @@ markStablePtrTable(rtsBool full)
          }
          (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));
+       IF_DEBUG(stable, fprintf(stderr,"Stable ptr %d still alive at %p, weight %u\n", p - stable_ptr_table, new, p->weight));
       }
     }
   }