/* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.6 1999/01/13 17:25:39 simonm Exp $
+ * $Id: GC.c,v 1.8 1999/01/14 11:11:29 simonm Exp $
*
* Two-space garbage collector
*
/* run through all the generations/steps and tidy up
*/
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+
+ if (g <= N) {
+ generations[g].collections++; /* for stats */
+ }
+
for (s = 0; s < generations[g].n_steps; s++) {
bdescr *next;
step = &generations[g].steps[s];
/* for generations we collected... */
if (g <= N) {
- generations[g].collections++; /* for stats */
collected += step->n_blocks * BLOCK_SIZE_W; /* for stats */
/* free old memory and shift to-space into from-space for all
* with the evacuation, just update the source address with
* a pointer to the (evacuated) constructor field.
*/
- if (IS_USER_PTR(q) && Bdescr((P_)q)->evacuated) {
- return q;
+ if (IS_USER_PTR(q)) {
+ bdescr *bd = Bdescr((P_)q);
+ if (bd->evacuated) {
+ if (bd->gen->no < evac_gen) {
+ failed_to_evac = rtsTrue;
+ }
+ return q;
+ }
}
/* otherwise, carry on and evacuate this constructor field,
{
StgInd *ind = (StgInd *)p;
ind->indirectee = evacuate(ind->indirectee);
+
+ /* might fail to evacuate it, in which case we have to pop it
+ * back on the mutable list (and take it off the
+ * scavenged_static list because the static link and mut link
+ * pointers are one and the same).
+ */
+ if (failed_to_evac) {
+ failed_to_evac = rtsFalse;
+ scavenged_static_objects = STATIC_LINK(info,p);
+ ((StgMutClosure *)ind)->mut_link = oldest_gen->mut_list;
+ oldest_gen->mut_list = (StgMutClosure *)ind;
+ }
break;
}
barf("scavenge_static");
}
+ ASSERT(failed_to_evac == rtsFalse);
+
/* get the next static object from the list. Remeber, there might
* be more stuff on this list now that we've done some evacuating!
* (static_objects is a global)