X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FMarkWeak.c;h=7b7187c94d58e10392ec52c71fd18e41386b4691;hb=8ae8c865716e0ee03383ddfae58ab778ce527412;hp=2f5964f5299049ee84d8504f4988e19de12763bc;hpb=5270423a6afe69f1dc57e5e5a474812182718d40;p=ghc-hetmet.git diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c index 2f5964f..7b7187c 100644 --- a/rts/sm/MarkWeak.c +++ b/rts/sm/MarkWeak.c @@ -83,8 +83,8 @@ StgTSO *resurrected_threads; // List of blocked threads found to have pending throwTos StgTSO *exception_threads; -static void resurrectUnreachableThreads (step *stp); -static rtsBool tidyThreadList (step *stp); +static void resurrectUnreachableThreads (generation *gen); +static rtsBool tidyThreadList (generation *gen); void initWeakForGC(void) @@ -113,7 +113,7 @@ traverseWeakPtrList(void) /* doesn't matter where we evacuate values/finalizers to, since * these pointers are treated as roots (iff the keys are alive). */ - gct->evac_step = 0; + gct->evac_gen = 0; last_w = &old_weak_ptr_list; for (w = old_weak_ptr_list; w != NULL; w = next_w) { @@ -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. @@ -191,19 +185,18 @@ traverseWeakPtrList(void) * become garbage, we wake them up and administer an exception. */ { - nat g, s, n; + nat g; // Traverse thread lists for generations we collected... - for (n = 0; n < n_capabilities; n++) { - if (tidyThreadList(&nurseries[n])) { - flag = rtsTrue; - } - } +// ToDo when we have one gen per capability: +// for (n = 0; n < n_capabilities; n++) { +// if (tidyThreadList(&nurseries[n])) { +// flag = rtsTrue; +// } +// } for (g = 0; g <= N; g++) { - for (s = 0; s < generations[g].n_steps; s++) { - if (tidyThreadList(&generations[g].steps[s])) { - flag = rtsTrue; - } + if (tidyThreadList(&generations[g])) { + flag = rtsTrue; } } @@ -214,15 +207,9 @@ traverseWeakPtrList(void) /* And resurrect any threads which were about to become garbage. */ { - nat g, s, n; - - for (n = 0; n < n_capabilities; n++) { - resurrectUnreachableThreads(&nurseries[n]); - } + nat g; for (g = 0; g <= N; g++) { - for (s = 0; s < generations[g].n_steps; s++) { - resurrectUnreachableThreads(&generations[g].steps[s]); - } + resurrectUnreachableThreads(&generations[g]); } } @@ -251,11 +238,11 @@ traverseWeakPtrList(void) } } - static void resurrectUnreachableThreads (step *stp) + static void resurrectUnreachableThreads (generation *gen) { StgTSO *t, *tmp, *next; - for (t = stp->old_threads; t != END_TSO_QUEUE; t = next) { + for (t = gen->old_threads; t != END_TSO_QUEUE; t = next) { next = t->global_link; // ThreadFinished and ThreadComplete: we have to keep @@ -275,14 +262,14 @@ traverseWeakPtrList(void) } } -static rtsBool tidyThreadList (step *stp) +static rtsBool tidyThreadList (generation *gen) { StgTSO *t, *tmp, *next, **prev; rtsBool flag = rtsFalse; - prev = &stp->old_threads; + prev = &gen->old_threads; - for (t = stp->old_threads; t != END_TSO_QUEUE; t = next) { + for (t = gen->old_threads; t != END_TSO_QUEUE; t = next) { tmp = (StgTSO *)isAlive((StgClosure *)t); @@ -339,10 +326,10 @@ static rtsBool tidyThreadList (step *stp) *prev = next; // move this thread onto the correct threads list. - step *new_step; - new_step = Bdescr((P_)t)->step; - t->global_link = new_step->threads; - new_step->threads = t; + generation *new_gen; + new_gen = Bdescr((P_)t)->gen; + t->global_link = new_gen->threads; + new_gen->threads = t; } } @@ -393,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) { @@ -415,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); + } } }