summaryrefslogtreecommitdiff
path: root/rts/sm/Scav.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-03-19 15:34:13 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-03-19 15:34:13 +0000
commit78f5cf9c5421ede69133e48823302375871e52c4 (patch)
tree286bfb92c0e20c4dba69379fe1b836c2cbaa000c /rts/sm/Scav.c
parentf7d332b49c893d22c9a583e65b196189b016031c (diff)
downloadhaskell-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/Scav.c')
-rw-r--r--rts/sm/Scav.c36
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;
}