[project @ 1999-01-14 14:35:04 by simonm]
[ghc-hetmet.git] / ghc / rts / GC.c
index 0a434b1..741c466 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $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
  *
@@ -386,6 +386,11 @@ void GarbageCollect(void (*get_roots)(void))
   /* 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];
@@ -399,7 +404,6 @@ void GarbageCollect(void (*get_roots)(void))
       /* 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
@@ -951,8 +955,14 @@ loop:
           * 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,
@@ -1735,6 +1745,18 @@ scavenge_static(void)
       {
        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;
       }
       
@@ -1759,6 +1781,8 @@ scavenge_static(void)
       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)