summaryrefslogtreecommitdiff
path: root/rts/sm/MarkWeak.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-12-08 09:48:22 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-12-08 09:48:22 +0000
commit852154bd9501f491b5499013e90922686850c833 (patch)
treeb0c3b29ceb0a241a9d57ba569a58d5787bbe82a2 /rts/sm/MarkWeak.c
parent4207605cc8e035e05f651334ef1be90b098d305d (diff)
downloadhaskell-852154bd9501f491b5499013e90922686850c833.tar.gz
simplify weak pointer processing
Diffstat (limited to 'rts/sm/MarkWeak.c')
-rw-r--r--rts/sm/MarkWeak.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c
index 9d8e8c01a9..7b7187c94d 100644
--- a/rts/sm/MarkWeak.c
+++ b/rts/sm/MarkWeak.c
@@ -127,14 +127,8 @@ traverseWeakPtrList(void)
continue;
}
- info = w->header.info;
- if (IS_FORWARDING_PTR(info)) {
- next_w = (StgWeak *)UN_FORWARDING_PTR(info);
- *last_w = next_w;
- continue;
- }
-
- switch (INFO_PTR_TO_STRUCT(info)->type) {
+ info = get_itbl(w);
+ switch (info->type) {
case WEAK:
/* Now, check whether the key is reachable.
@@ -386,21 +380,17 @@ traverseBlackholeQueue (void)
}
/* -----------------------------------------------------------------------------
- After GC, the live weak pointer list may have forwarding pointers
- on it, because a weak pointer object was evacuated after being
- moved to the live weak pointer list. We remove those forwarding
- pointers here.
-
- Also, we don't consider weak pointer objects to be reachable, but
- we must nevertheless consider them to be "live" and retain them.
- Therefore any weak pointer objects which haven't as yet been
- evacuated need to be evacuated now.
+ Evacuate every weak pointer object on the weak_ptr_list, and update
+ the link fields.
+
+ ToDo: with a lot of weak pointers, this will be expensive. We
+ should have a per-GC weak pointer list, just like threads.
-------------------------------------------------------------------------- */
void
markWeakPtrList ( void )
{
- StgWeak *w, **last_w, *tmp;
+ StgWeak *w, **last_w;
last_w = &weak_ptr_list;
for (w = weak_ptr_list; w; w = w->link) {
@@ -408,10 +398,13 @@ markWeakPtrList ( void )
ASSERT(IS_FORWARDING_PTR(w->header.info)
|| w->header.info == &stg_DEAD_WEAK_info
|| get_itbl(w)->type == WEAK);
- tmp = w;
- evacuate((StgClosure **)&tmp);
- *last_w = w;
- last_w = &(w->link);
+ evacuate((StgClosure **)last_w);
+ w = *last_w;
+ if (w->header.info == &stg_DEAD_WEAK_info) {
+ last_w = &(((StgDeadWeak*)w)->link);
+ } else {
+ last_w = &(w->link);
+ }
}
}