From 6ff4beae14211e6078b2845f52b2220d72a52228 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 25 Sep 2007 13:26:00 +0000 Subject: [PATCH] fix to previous fix to THUNK_SELECTOR machinery It turns out I didn't get it quite right in the case of compacting collection. This should make it work again. --- rts/sm/Evac.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c index ad577af..a0c2ae7 100644 --- a/rts/sm/Evac.c +++ b/rts/sm/Evac.c @@ -713,18 +713,29 @@ selector_chain: info_ptr = p->header.info; field = get_itbl(p)->layout.selector_offset; - // If the THUNK_SELECTOR is in to-space or in a generation that we - // are not collecting, then bail out early. We won't be able to - // save any space in any case, and updating with an indirection is - // trickier in an old gen. bd = Bdescr((StgPtr)p); - if (HEAP_ALLOCED(p) && - ((bd->gen_no > N) - || (bd->flags & BF_EVACUATED) - || ((bd->flags & BF_COMPACTED) && - is_marked((P_)p,bd)))) { - unchain_thunk_selectors(prev_thunk_selector, (StgClosure *)p); - return (StgClosure *)p; + if (HEAP_ALLOCED(p)) { + // If the THUNK_SELECTOR is in to-space or in a generation that we + // are not collecting, then bale out early. We won't be able to + // save any space in any case, and updating with an indirection is + // trickier in a non-collected gen: we would have to update the + // mutable list. + if ((bd->gen_no > N) || (bd->flags & BF_EVACUATED)) { + unchain_thunk_selectors(prev_thunk_selector, (StgClosure *)p); + return (StgClosure *)p; + } + // we don't update THUNK_SELECTORS in the compacted + // generation, because compaction does not remove the INDs + // that result, this causes confusion later + // (scavenge_mark_stack doesn't deal with IND). BEWARE! This + // bit is very tricky to get right. If you make changes + // around here, test by compiling stage 3 with +RTS -c -RTS. + if (bd->flags & BF_COMPACTED) { + // must call evacuate() to mark this closure if evac==rtsTrue + if (evac) p = (StgSelector *)evacuate((StgClosure *)p); + unchain_thunk_selectors(prev_thunk_selector, (StgClosure *)p); + return (StgClosure *)p; + } } // BLACKHOLE the selector thunk, since it is now under evaluation. @@ -818,14 +829,6 @@ selector_loop: { StgClosure *val; - // we don't update THUNK_SELECTORS in the compacted - // generation, because compaction does not remove the INDs - // that result, this causes confusion later - // (scavenge_mark_stack doesn't deal with IND). - if (Bdescr((P_)selectee)->flags && BF_COMPACTED) { - goto bale_out; - } - // recursively evaluate this selector. We don't want to // recurse indefinitely, so we impose a depth bound. if (thunk_selector_depth >= MAX_THUNK_SELECTOR_DEPTH) { -- 1.7.10.4