/* ----------------------------------------------------------------------------
- * $Id: Closures.h,v 1.9 1999/02/19 18:26:04 sewardj Exp $
+ * $Id: Closures.h,v 1.10 1999/02/26 17:46:04 simonm Exp $
*
* (c) The GHC Team, 1998-1999
*
struct _StgWeak *link;
} StgWeak;
+typedef struct _StgDeadWeak { /* Weak v */
+ StgHeader header;
+ struct _StgWeak *link;
+} StgDeadWeak;
+
/* Dynamic stack frames - these have a liveness mask in the object
* itself, rather than in the info table. Useful for generic heap
* check code.
/* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.44 1999/02/26 13:36:12 simonm Exp $
+ * $Id: GC.c,v 1.45 1999/02/26 17:46:08 simonm Exp $
*
* (c) The GHC Team 1998-1999
*
w = (StgWeak *)((StgEvacuated *)w)->evacuee;
*last_w = w;
}
+
+ /* There might be a DEAD_WEAK on the list if finalizeWeak# was
+ * called on a live weak pointer object. Just remove it.
+ */
+ if (w->header.info == &DEAD_WEAK_info) {
+ next_w = ((StgDeadWeak *)w)->link;
+ *last_w = next_w;
+ continue;
+ }
+
ASSERT(get_itbl(w)->type == WEAK);
/* Now, check whether the key is reachable.
/* -----------------------------------------------------------------------------
- * $Id: PrimOps.hc,v 1.17 1999/02/26 12:46:48 simonm Exp $
+ * $Id: PrimOps.hc,v 1.18 1999/02/26 17:46:09 simonm Exp $
*
* (c) The GHC Team, 1998-1999
*
{
/* R1.p = weak ptr
*/
- StgWeak *w;
+ StgDeadWeak *w;
+ StgClosure *f;
FB_
TICK_RET_UNBOXED_TUP(0);
- w = (StgWeak *)R1.p;
+ w = (StgDeadWeak *)R1.p;
/* already dead? */
if (w->header.info == &DEAD_WEAK_info) {
/* kill it */
w->header.info = &DEAD_WEAK_info;
+ f = ((StgWeak *)w)->finalizer;
+ w->link = ((StgWeak *)w)->link;
/* return the finalizer */
- if (w->finalizer == &NO_FINALIZER_closure) {
+ if (f == &NO_FINALIZER_closure) {
RET_NP(0,&NO_FINALIZER_closure);
} else {
- RET_NP(1,w->finalizer);
+ RET_NP(1,f);
}
FE_
}