X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FGC.c;h=1f67fd490e8bc278b5bd931e889c931df9b984f8;hb=abde5fdfcaa5f363d9cf8cf0a10aa281c40887fe;hp=883058234e181881c39554078a6fc094406a7f24;hpb=a186d6f72aa221772ffeccb99c6c538c4505b0d7;p=ghc-hetmet.git diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 8830582..1f67fd4 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1415,8 +1415,6 @@ mark_root(StgClosure **root) STATIC_INLINE void upd_evacuee(StgClosure *p, StgClosure *dest) { - // Source object must be in from-space: - ASSERT((Bdescr((P_)p)->flags & BF_EVACUATED) == 0); // not true: (ToDo: perhaps it should be) // ASSERT(Bdescr((P_)dest)->flags & BF_EVACUATED); SET_INFO(p, &stg_EVACUATED_info); @@ -1677,6 +1675,9 @@ loop: return q; } + /* Object is not already evacuated. */ + ASSERT((bd->flags & BF_EVACUATED) == 0); + stp = bd->step->to; } #ifdef DEBUG @@ -3452,11 +3453,21 @@ scavenge_one(StgPtr p) case IND_OLDGEN: case IND_OLDGEN_PERM: case IND_STATIC: - /* Try to pull the indirectee into this generation, so we can - * remove the indirection from the mutable list. - */ - ((StgInd *)p)->indirectee = evacuate(((StgInd *)p)->indirectee); - + { + /* Careful here: a THUNK can be on the mutable list because + * it contains pointers to young gen objects. If such a thunk + * is updated, the IND_OLDGEN will be added to the mutable + * list again, and we'll scavenge it twice. evacuate() + * doesn't check whether the object has already been + * evacuated, so we perform that check here. + */ + StgClosure *q = ((StgInd *)p)->indirectee; + if (HEAP_ALLOCED(q) && Bdescr((StgPtr)q)->flags & BF_EVACUATED) { + break; + } + ((StgInd *)p)->indirectee = evacuate(q); + } + #if 0 && defined(DEBUG) if (RtsFlags.DebugFlags.gc) /* Debugging code to print out the size of the thing we just @@ -3838,14 +3849,14 @@ revertCAFs( void ) { StgIndStatic *c; - for (c = (StgIndStatic *)caf_list; c != NULL; + for (c = (StgIndStatic *)revertible_caf_list; c != NULL; c = (StgIndStatic *)c->static_link) { SET_INFO(c, c->saved_info); c->saved_info = NULL; // could, but not necessary: c->static_link = NULL; } - caf_list = NULL; + revertible_caf_list = NULL; } void @@ -3858,6 +3869,11 @@ markCAFs( evac_fn evac ) { evac(&c->indirectee); } + for (c = (StgIndStatic *)revertible_caf_list; c != NULL; + c = (StgIndStatic *)c->static_link) + { + evac(&c->indirectee); + } } /* -----------------------------------------------------------------------------