From: Simon Marlow Date: Fri, 19 Mar 2010 11:21:27 +0000 (+0000) Subject: slight improvement to scavenging of update frames when a collision has occurred X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=f7d332b49c893d22c9a583e65b196189b016031c;p=ghc-hetmet.git slight improvement to scavenging of update frames when a collision has occurred --- diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c index 1b671a0..29a6995 100644 --- a/rts/sm/Scav.c +++ b/rts/sm/Scav.c @@ -1575,11 +1575,13 @@ scavenge_stack(StgPtr p, StgPtr stack_end) // threadPaused(). We could traverse the whole stack again // before GC, but that seems like overkill. // - // Scavenging this update frame as normal would be disastrous; - // the updatee would end up pointing to the value. So we turn - // the indirection into an IND_PERM, so that evacuate will - // copy the indirection into the old generation instead of - // discarding it. + // So, if the frame points to an indirection, it will get + // shorted out when we evacuate. If this happens, we have no + // closure to update any more. In the past we solved this by + // replacing the IND with an IND_PERM, but a better solution + // is to replace the update frame with a frame that no longer + // does the update and just uses the value already computed by + // the other thread, so that is what we now do. // // Note [upd-black-hole] // One slight hiccup is that the THUNK_SELECTOR machinery can @@ -1590,22 +1592,16 @@ scavenge_stack(StgPtr p, StgPtr stack_end) // the updatee is never a THUNK_SELECTOR and we're ok. // NB. this is a new invariant: blackholing is not optional. { - nat type; - const StgInfoTable *i; - StgClosure *updatee; - - updatee = ((StgUpdateFrame *)p)->updatee; - i = updatee->header.info; - if (!IS_FORWARDING_PTR(i)) { - type = get_itbl(updatee)->type; - if (type == IND) { - updatee->header.info = &stg_IND_PERM_info; - } else if (type == IND_OLDGEN) { - updatee->header.info = &stg_IND_OLDGEN_PERM_info; - } + StgClosure *v; + StgUpdateFrame *frame = (StgUpdateFrame *)p; + + evacuate(&frame->updatee); + v = frame->updatee; + if (GET_CLOSURE_TAG(v) != 0 || + (get_itbl(v)->type != BLACKHOLE && + get_itbl(v)->type != CAF_BLACKHOLE)) { + frame->header.info = (const StgInfoTable*)&stg_gc_unpt_r1_info; } - evacuate(&((StgUpdateFrame *)p)->updatee); - ASSERT(GET_CLOSURE_TAG(((StgUpdateFrame *)p)->updatee) == 0); p += sizeofW(StgUpdateFrame); continue; }