Skip to content

Commit

Permalink
[project @ 1999-02-26 17:46:04 by simonm]
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
simonm committed Feb 26, 1999
1 parent 250cd3d commit 10b81c5
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
7 changes: 6 additions & 1 deletion 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 * (c) The GHC Team, 1998-1999
* *
Expand Down Expand Up @@ -265,6 +265,11 @@ typedef struct _StgWeak { /* Weak v */
struct _StgWeak *link; struct _StgWeak *link;
} StgWeak; } StgWeak;


typedef struct _StgDeadWeak { /* Weak v */
StgHeader header;
struct _StgWeak *link;
} StgDeadWeak;

/* Dynamic stack frames - these have a liveness mask in the object /* Dynamic stack frames - these have a liveness mask in the object
* itself, rather than in the info table. Useful for generic heap * itself, rather than in the info table. Useful for generic heap
* check code. * check code.
Expand Down
12 changes: 11 additions & 1 deletion 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 * (c) The GHC Team 1998-1999
* *
Expand Down Expand Up @@ -758,6 +758,16 @@ traverse_weak_ptr_list(void)
w = (StgWeak *)((StgEvacuated *)w)->evacuee; w = (StgWeak *)((StgEvacuated *)w)->evacuee;
*last_w = w; *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); ASSERT(get_itbl(w)->type == WEAK);


/* Now, check whether the key is reachable. /* Now, check whether the key is reachable.
Expand Down
13 changes: 8 additions & 5 deletions 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 * (c) The GHC Team, 1998-1999
* *
Expand Down Expand Up @@ -348,10 +348,11 @@ FN_(finalizzeWeakzh_fast)
{ {
/* R1.p = weak ptr /* R1.p = weak ptr
*/ */
StgWeak *w; StgDeadWeak *w;
StgClosure *f;
FB_ FB_
TICK_RET_UNBOXED_TUP(0); TICK_RET_UNBOXED_TUP(0);
w = (StgWeak *)R1.p; w = (StgDeadWeak *)R1.p;


/* already dead? */ /* already dead? */
if (w->header.info == &DEAD_WEAK_info) { if (w->header.info == &DEAD_WEAK_info) {
Expand All @@ -360,12 +361,14 @@ FN_(finalizzeWeakzh_fast)


/* kill it */ /* kill it */
w->header.info = &DEAD_WEAK_info; w->header.info = &DEAD_WEAK_info;
f = ((StgWeak *)w)->finalizer;
w->link = ((StgWeak *)w)->link;


/* return the finalizer */ /* return the finalizer */
if (w->finalizer == &NO_FINALIZER_closure) { if (f == &NO_FINALIZER_closure) {
RET_NP(0,&NO_FINALIZER_closure); RET_NP(0,&NO_FINALIZER_closure);
} else { } else {
RET_NP(1,w->finalizer); RET_NP(1,f);
} }
FE_ FE_
} }
Expand Down

0 comments on commit 10b81c5

Please sign in to comment.