X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FGC.c;h=a0f119f5ce5926b5255121f5d5db691b3e80858a;hb=25efe5a45ff5579172312ca14cfd89443ba931dc;hp=2b30d679f90a267ee0dec1f8f4fc2f25db661e27;hpb=b3f530814c15886a7a010ed871bb1f054a3918b3;p=ghc-hetmet.git diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 2b30d67..a0f119f 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: GC.c,v 1.149 2003/03/24 14:46:53 simonmar Exp $ + * $Id: GC.c,v 1.150 2003/03/24 15:33:25 simonmar Exp $ * * (c) The GHC Team 1998-2003 * @@ -2002,9 +2002,22 @@ eval_thunk_selector( nat field, StgSelector * p ) selector_loop: + // We don't want to end up in to-space, because this causes + // problems when the GC later tries to evacuate the result of + // eval_thunk_selector(). There are various ways this could + // happen: + // + // - following an IND_STATIC + // + // - when the old generation is compacted, the mark phase updates + // from-space pointers to be to-space pointers, and we can't + // reliably tell which we're following (eg. from an IND_STATIC). + // + // So we use the block-descriptor test to find out if we're in + // to-space. + // if (Bdescr((StgPtr)selectee)->flags & BF_EVACUATED) { - SET_INFO(p, info_ptr); - return NULL; + goto bale_out; } info = get_itbl(selectee); @@ -2021,12 +2034,15 @@ selector_loop: ASSERT(field < (StgWord32)(info->layout.payload.ptrs + info->layout.payload.nptrs)); + // ToDo: shouldn't we test whether this pointer is in + // to-space? return selectee->payload[field]; case IND: case IND_PERM: case IND_OLDGEN: case IND_OLDGEN_PERM: + case IND_STATIC: selectee = ((StgInd *)selectee)->indirectee; goto selector_loop; @@ -2036,11 +2052,6 @@ selector_loop: // leaks by evaluating this selector thunk anyhow. break; - case IND_STATIC: - // We can't easily tell whether the indirectee is into - // from or to-space, so just bail out here. - break; - case THUNK_SELECTOR: { StgClosure *val; @@ -2113,6 +2124,7 @@ selector_loop: (int)(info->type)); } +bale_out: // We didn't manage to evaluate this thunk; restore the old info pointer SET_INFO(p, info_ptr); return NULL;