diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-03-19 15:34:13 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-03-19 15:34:13 +0000 |
commit | 78f5cf9c5421ede69133e48823302375871e52c4 (patch) | |
tree | 286bfb92c0e20c4dba69379fe1b836c2cbaa000c /rts/sm | |
parent | f7d332b49c893d22c9a583e65b196189b016031c (diff) | |
download | haskell-78f5cf9c5421ede69133e48823302375871e52c4.tar.gz |
UNDO: slight improvement to scavenging ...
Accidnetally pushed this patch which, while it validates, isn't
correct.
rolling back:
Fri Mar 19 11:21:27 GMT 2010 Simon Marlow <marlowsd@gmail.com>
* slight improvement to scavenging of update frames when a collision has occurred
M ./rts/sm/Scav.c -19 +15
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/Scav.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c index 29a69950a3..1b671a097c 100644 --- a/rts/sm/Scav.c +++ b/rts/sm/Scav.c @@ -1575,13 +1575,11 @@ scavenge_stack(StgPtr p, StgPtr stack_end) // threadPaused(). We could traverse the whole stack again // before GC, but that seems like overkill. // - // 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. + // 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. // // Note [upd-black-hole] // One slight hiccup is that the THUNK_SELECTOR machinery can @@ -1592,16 +1590,22 @@ 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. { - 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; + 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; + } } + evacuate(&((StgUpdateFrame *)p)->updatee); + ASSERT(GET_CLOSURE_TAG(((StgUpdateFrame *)p)->updatee) == 0); p += sizeofW(StgUpdateFrame); continue; } |