diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-12-03 15:07:28 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-12-03 15:07:28 +0000 |
commit | 214b3663d5d7598c13643f9221e43d5a7735b47f (patch) | |
tree | de779bab8dbcf057eaf481e6b612b63881e246e9 /rts/sm/MarkWeak.c | |
parent | 7cb1d9274e84ee2fc2dd610aa4f7686586ca0357 (diff) | |
download | haskell-214b3663d5d7598c13643f9221e43d5a7735b47f.tar.gz |
GC refactoring, remove "steps"
The GC had a two-level structure, G generations each of T steps.
Steps are for aging within a generation, mostly to avoid premature
promotion.
Measurements show that more than 2 steps is almost never worthwhile,
and 1 step is usually worse than 2. In theory fractional steps are
possible, so the ideal number of steps is somewhere between 1 and 3.
GHC's default has always been 2.
We can implement 2 steps quite straightforwardly by having each block
point to the generation to which objects in that block should be
promoted, so blocks in the nursery point to generation 0, and blocks
in gen 0 point to gen 1, and so on.
This commit removes the explicit step structures, merging generations
with steps, thus simplifying a lot of code. Performance is
unaffected. The tunable number of steps is now gone, although it may
be replaced in the future by a way to tune the aging in generation 0.
Diffstat (limited to 'rts/sm/MarkWeak.c')
-rw-r--r-- | rts/sm/MarkWeak.c | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c index 2f5964f529..9d8e8c01a9 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) { @@ -191,19 +191,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 +213,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 +244,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 +268,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 +332,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; } } |