Commit 4d3ce736 authored by simonmar's avatar simonmar
Browse files

[project @ 2005-02-11 14:01:30 by simonmar]

Careful with mutable list entries that point to THUNKs: the thunk
might be updated, and the resulting IND_OLDGEN will be on the mutable
list twice.

We previously avoided this problem by having an extra MUT_CONS object
on the mutable list pointing to the THUNK, so that we could tell the
difference between the entry on the mutable list that used to be the
THUNK, and the new entry for the IND_OLDGEN.

We don't have MUT_CONS any more (this was part of the cleanup from
separating the mutable list from the heap).  So, now, when scavenging
an IND_OLDGEN on the mutable list, we check whether it is pointing to
an already-evacuated object.  This is a bit crude, but at least it is
a localised hack.
parent a186d6f7
...@@ -1415,8 +1415,6 @@ mark_root(StgClosure **root) ...@@ -1415,8 +1415,6 @@ mark_root(StgClosure **root)
STATIC_INLINE void STATIC_INLINE void
upd_evacuee(StgClosure *p, StgClosure *dest) 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) // not true: (ToDo: perhaps it should be)
// ASSERT(Bdescr((P_)dest)->flags & BF_EVACUATED); // ASSERT(Bdescr((P_)dest)->flags & BF_EVACUATED);
SET_INFO(p, &stg_EVACUATED_info); SET_INFO(p, &stg_EVACUATED_info);
...@@ -1677,6 +1675,9 @@ loop: ...@@ -1677,6 +1675,9 @@ loop:
return q; return q;
} }
/* Object is not already evacuated. */
ASSERT((bd->flags & BF_EVACUATED) == 0);
stp = bd->step->to; stp = bd->step->to;
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -3452,11 +3453,21 @@ scavenge_one(StgPtr p) ...@@ -3452,11 +3453,21 @@ scavenge_one(StgPtr p)
case IND_OLDGEN: case IND_OLDGEN:
case IND_OLDGEN_PERM: case IND_OLDGEN_PERM:
case IND_STATIC: case IND_STATIC:
/* Try to pull the indirectee into this generation, so we can {
* remove the indirection from the mutable list. /* Careful here: a THUNK can be on the mutable list because
*/ * it contains pointers to young gen objects. If such a thunk
((StgInd *)p)->indirectee = evacuate(((StgInd *)p)->indirectee); * 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 0 && defined(DEBUG)
if (RtsFlags.DebugFlags.gc) if (RtsFlags.DebugFlags.gc)
/* Debugging code to print out the size of the thing we just /* Debugging code to print out the size of the thing we just
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment