/* -----------------------------------------------------------------------------
- * $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
*
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.
*
* 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
{
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;
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");
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));
}
}
}
(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));
}
}
}