Commit 10b81c59 authored by simonm's avatar simonm
Browse files

[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.
parent 250cd3d0
/* ----------------------------------------------------------------------------
* $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.
......
/* -----------------------------------------------------------------------------
* $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.
......
/* -----------------------------------------------------------------------------
* $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_
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment