summaryrefslogtreecommitdiff
path: root/rts/sm/Scav.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2008-11-19 14:37:02 +0000
committerSimon Marlow <marlowsd@gmail.com>2008-11-19 14:37:02 +0000
commitb15b4a179922b1d9fe34c33ee15a25d515d56367 (patch)
tree5059d2738d9c01dc4c52bf22d27d8e18233e9aec /rts/sm/Scav.c
parentdb12b8eaab53788cf29c589beca82511e48249e4 (diff)
downloadhaskell-b15b4a179922b1d9fe34c33ee15a25d515d56367.tar.gz
Small refactoring, and add comments
I discovered a new invariant while experimenting (blackholing is not optional when using parallel GC), so documented it.
Diffstat (limited to 'rts/sm/Scav.c')
-rw-r--r--rts/sm/Scav.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
index 24f19c93e1..d396b9f7f6 100644
--- a/rts/sm/Scav.c
+++ b/rts/sm/Scav.c
@@ -1680,24 +1680,34 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
// 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
+ // overwrite the updatee with an IND. In parallel GC, this
+ // could even be happening concurrently, so we can't check for
+ // the IND. Fortunately if we assume that blackholing is
+ // happening (either lazy or eager), then we can be sure that
+ // 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;
- i = ((StgUpdateFrame *)p)->updatee->header.info;
+ updatee = ((StgUpdateFrame *)p)->updatee;
+ i = updatee->header.info;
if (!IS_FORWARDING_PTR(i)) {
- type = get_itbl(((StgUpdateFrame *)p)->updatee)->type;
+ type = get_itbl(updatee)->type;
if (type == IND) {
- ((StgUpdateFrame *)p)->updatee->header.info =
- (StgInfoTable *)&stg_IND_PERM_info;
+ updatee->header.info = &stg_IND_PERM_info;
} else if (type == IND_OLDGEN) {
- ((StgUpdateFrame *)p)->updatee->header.info =
- (StgInfoTable *)&stg_IND_OLDGEN_PERM_info;
+ updatee->header.info = &stg_IND_OLDGEN_PERM_info;
}
- evacuate(&((StgUpdateFrame *)p)->updatee);
- p += sizeofW(StgUpdateFrame);
- continue;
}
+ evacuate(&((StgUpdateFrame *)p)->updatee);
+ ASSERT(GET_CLOSURE_TAG(((StgUpdateFrame *)p)->updatee) == 0);
+ p += sizeofW(StgUpdateFrame);
+ continue;
}
// small bitmap (< 32 entries, or 64 on a 64-bit machine)