From: simonm Date: Fri, 26 Feb 1999 17:46:09 +0000 (+0000) Subject: [project @ 1999-02-26 17:46:04 by simonm] X-Git-Tag: Approximately_9120_patches~6501 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=10b81c59c3dc8e66f1a61e58edcac5b12fd39922;p=ghc-hetmet.git [project @ 1999-02-26 17:46:04 by simonm] Fix a bug in weak pointer support: if finalize is called on a weak pointer, then a DEAD_WEAK object could appear on the weak pointer list. To avoid needing to double-link this list, add a link field to DEAD_WEAK objects, and remove them from the list at garbage collection time. --- diff --git a/ghc/includes/Closures.h b/ghc/includes/Closures.h index 23446c4..76aeecc 100644 --- a/ghc/includes/Closures.h +++ b/ghc/includes/Closures.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * $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 * @@ -265,6 +265,11 @@ typedef struct _StgWeak { /* Weak v */ 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. diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 71048a1..64108c9 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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 * @@ -758,6 +758,16 @@ traverse_weak_ptr_list(void) 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. diff --git a/ghc/rts/PrimOps.hc b/ghc/rts/PrimOps.hc index 33e2d23..37af75f 100644 --- a/ghc/rts/PrimOps.hc +++ b/ghc/rts/PrimOps.hc @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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 * @@ -348,10 +348,11 @@ FN_(finalizzeWeakzh_fast) { /* 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) { @@ -360,12 +361,14 @@ FN_(finalizzeWeakzh_fast) /* 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_ }