From 256a006fc9ae215926e5a0645b85d86cd683701d Mon Sep 17 00:00:00 2001 From: simonmar Date: Fri, 19 Apr 2002 10:25:00 +0000 Subject: [PATCH] [project @ 2002-04-19 10:25:00 by simonmar] - traverse_weak_ptr_list(): Deal with EVACUATED objects on the weak pointer list. - mark_weak_ptr_list(): add an assertion. --- ghc/rts/GC.c | 63 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 8dbe589..563392c 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: GC.c,v 1.133 2002/04/13 05:16:25 sof Exp $ + * $Id: GC.c,v 1.134 2002/04/19 10:25:00 simonmar Exp $ * * (c) The GHC Team 1998-1999 * @@ -1104,31 +1104,41 @@ traverse_weak_ptr_list(void) continue; } - ASSERT(get_itbl(w)->type == WEAK); - - /* Now, check whether the key is reachable. - */ - new = isAlive(w->key); - if (new != NULL) { - w->key = new; - // evacuate the value and finalizer - w->value = evacuate(w->value); - w->finalizer = evacuate(w->finalizer); - // remove this weak ptr from the old_weak_ptr list - *last_w = w->link; - // and put it on the new weak ptr list - next_w = w->link; - w->link = weak_ptr_list; - weak_ptr_list = w; - flag = rtsTrue; - IF_DEBUG(weak, belch("Weak pointer still alive at %p -> %p", - w, w->key)); - continue; - } - else { - last_w = &(w->link); - next_w = w->link; + switch (get_itbl(w)->type) { + + case EVACUATED: + next_w = (StgWeak *)((StgEvacuated *)w)->evacuee; + *last_w = next_w; continue; + + case WEAK: + /* Now, check whether the key is reachable. + */ + new = isAlive(w->key); + if (new != NULL) { + w->key = new; + // evacuate the value and finalizer + w->value = evacuate(w->value); + w->finalizer = evacuate(w->finalizer); + // remove this weak ptr from the old_weak_ptr list + *last_w = w->link; + // and put it on the new weak ptr list + next_w = w->link; + w->link = weak_ptr_list; + weak_ptr_list = w; + flag = rtsTrue; + IF_DEBUG(weak, belch("Weak pointer still alive at %p -> %p", + w, w->key)); + continue; + } + else { + last_w = &(w->link); + next_w = w->link; + continue; + } + + default: + barf("traverse_weak_ptr_list: not WEAK"); } } @@ -1241,6 +1251,9 @@ mark_weak_ptr_list ( StgWeak **list ) last_w = list; for (w = *list; w; w = w->link) { + // w might be WEAK, EVACUATED, or DEAD_WEAK (actually CON_STATIC) here + ASSERT(w->header.info == &stg_DEAD_WEAK_info + || get_itbl(w)->type == WEAK || get_itbl(w)->type == EVACUATED); (StgClosure *)w = evacuate((StgClosure *)w); *last_w = w; last_w = &(w->link); -- 1.7.10.4