[project @ 1999-02-26 13:36:12 by simonm]
[ghc-hetmet.git] / ghc / rts / GC.c
1 /* -----------------------------------------------------------------------------
2  * $Id: GC.c,v 1.44 1999/02/26 13:36:12 simonm Exp $
3  *
4  * (c) The GHC Team 1998-1999
5  *
6  * Generational garbage collector
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "Rts.h"
11 #include "RtsFlags.h"
12 #include "RtsUtils.h"
13 #include "Storage.h"
14 #include "StoragePriv.h"
15 #include "Stats.h"
16 #include "Schedule.h"
17 #include "SchedAPI.h" /* for ReverCAFs prototype */
18 #include "Sanity.h"
19 #include "GC.h"
20 #include "BlockAlloc.h"
21 #include "Main.h"
22 #include "DebugProf.h"
23 #include "SchedAPI.h"
24 #include "Weak.h"
25 #include "StablePriv.h"
26
27 StgCAF* enteredCAFs;
28
29 /* STATIC OBJECT LIST.
30  *
31  * During GC:
32  * We maintain a linked list of static objects that are still live.
33  * The requirements for this list are:
34  *
35  *  - we need to scan the list while adding to it, in order to
36  *    scavenge all the static objects (in the same way that
37  *    breadth-first scavenging works for dynamic objects).
38  *
39  *  - we need to be able to tell whether an object is already on
40  *    the list, to break loops.
41  *
42  * Each static object has a "static link field", which we use for
43  * linking objects on to the list.  We use a stack-type list, consing
44  * objects on the front as they are added (this means that the
45  * scavenge phase is depth-first, not breadth-first, but that
46  * shouldn't matter).  
47  *
48  * A separate list is kept for objects that have been scavenged
49  * already - this is so that we can zero all the marks afterwards.
50  *
51  * An object is on the list if its static link field is non-zero; this
52  * means that we have to mark the end of the list with '1', not NULL.  
53  *
54  * Extra notes for generational GC:
55  *
56  * Each generation has a static object list associated with it.  When
57  * collecting generations up to N, we treat the static object lists
58  * from generations > N as roots.
59  *
60  * We build up a static object list while collecting generations 0..N,
61  * which is then appended to the static object list of generation N+1.
62  */
63 StgClosure* static_objects;           /* live static objects */
64 StgClosure* scavenged_static_objects; /* static objects scavenged so far */
65
66 /* N is the oldest generation being collected, where the generations
67  * are numbered starting at 0.  A major GC (indicated by the major_gc
68  * flag) is when we're collecting all generations.  We only attempt to
69  * deal with static objects and GC CAFs when doing a major GC.
70  */
71 static nat N;
72 static rtsBool major_gc;
73
74 /* Youngest generation that objects should be evacuated to in
75  * evacuate().  (Logically an argument to evacuate, but it's static
76  * a lot of the time so we optimise it into a global variable).
77  */
78 static nat evac_gen;
79
80 /* WEAK POINTERS
81  */
82 static StgWeak *old_weak_ptr_list; /* also pending finaliser list */
83 static rtsBool weak_done;       /* all done for this pass */
84
85 /* Flag indicating failure to evacuate an object to the desired
86  * generation.
87  */
88 static rtsBool failed_to_evac;
89
90 /* Old to-space (used for two-space collector only)
91  */
92 bdescr *old_to_space;
93
94 /* Data used for allocation area sizing.
95  */
96 lnat new_blocks;                /* blocks allocated during this GC */
97 lnat g0s0_pcnt_kept = 30;       /* percentage of g0s0 live at last minor GC */
98
99 /* -----------------------------------------------------------------------------
100    Static function declarations
101    -------------------------------------------------------------------------- */
102
103 static StgClosure * evacuate                ( StgClosure *q );
104 static void         zero_static_object_list ( StgClosure* first_static );
105 static void         zero_mutable_list       ( StgMutClosure *first );
106 static void         revert_dead_CAFs        ( void );
107
108 static rtsBool      traverse_weak_ptr_list  ( void );
109 static void         cleanup_weak_ptr_list   ( void );
110
111 static void         scavenge_stack          ( StgPtr p, StgPtr stack_end );
112 static void         scavenge_large          ( step *step );
113 static void         scavenge                ( step *step );
114 static void         scavenge_static         ( void );
115 static void         scavenge_mutable_list   ( generation *g );
116 static void         scavenge_mut_once_list  ( generation *g );
117
118 #ifdef DEBUG
119 static void         gcCAFs                  ( void );
120 #endif
121
122 /* -----------------------------------------------------------------------------
123    GarbageCollect
124
125    For garbage collecting generation N (and all younger generations):
126
127      - follow all pointers in the root set.  the root set includes all 
128        mutable objects in all steps in all generations.
129
130      - for each pointer, evacuate the object it points to into either
131        + to-space in the next higher step in that generation, if one exists,
132        + if the object's generation == N, then evacuate it to the next
133          generation if one exists, or else to-space in the current
134          generation.
135        + if the object's generation < N, then evacuate it to to-space
136          in the next generation.
137
138      - repeatedly scavenge to-space from each step in each generation
139        being collected until no more objects can be evacuated.
140       
141      - free from-space in each step, and set from-space = to-space.
142
143    -------------------------------------------------------------------------- */
144
145 void GarbageCollect(void (*get_roots)(void))
146 {
147   bdescr *bd;
148   step *step;
149   lnat live, allocated, collected = 0, copied = 0;
150   nat g, s;
151
152 #ifdef PROFILING
153   CostCentreStack *prev_CCS;
154 #endif
155
156   /* tell the stats department that we've started a GC */
157   stat_startGC();
158
159   /* attribute any costs to CCS_GC */
160 #ifdef PROFILING
161   prev_CCS = CCCS;
162   CCCS = CCS_GC;
163 #endif
164
165   /* We might have been called from Haskell land by _ccall_GC, in
166    * which case we need to call threadPaused() because the scheduler
167    * won't have done it.
168    */
169   if (CurrentTSO) { threadPaused(CurrentTSO); }
170
171   /* Approximate how much we allocated: number of blocks in the
172    * nursery + blocks allocated via allocate() - unused nusery blocks.
173    * This leaves a little slop at the end of each block, and doesn't
174    * take into account large objects (ToDo).
175    */
176   allocated = (nursery_blocks * BLOCK_SIZE_W) + allocated_bytes();
177   for ( bd = current_nursery->link; bd != NULL; bd = bd->link ) {
178     allocated -= BLOCK_SIZE_W;
179   }
180
181   /* Figure out which generation to collect
182    */
183   N = 0;
184   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
185     if (generations[g].steps[0].n_blocks >= generations[g].max_blocks) {
186       N = g;
187     }
188   }
189   major_gc = (N == RtsFlags.GcFlags.generations-1);
190
191   /* check stack sanity *before* GC (ToDo: check all threads) */
192   /*IF_DEBUG(sanity, checkTSO(MainTSO,0)); */
193   IF_DEBUG(sanity, checkFreeListSanity());
194
195   /* Initialise the static object lists
196    */
197   static_objects = END_OF_STATIC_LIST;
198   scavenged_static_objects = END_OF_STATIC_LIST;
199
200   /* zero the mutable list for the oldest generation (see comment by
201    * zero_mutable_list below).
202    */
203   if (major_gc) { 
204     zero_mutable_list(generations[RtsFlags.GcFlags.generations-1].mut_once_list);
205   }
206
207   /* Save the old to-space if we're doing a two-space collection
208    */
209   if (RtsFlags.GcFlags.generations == 1) {
210     old_to_space = g0s0->to_space;
211     g0s0->to_space = NULL;
212   }
213
214   /* Keep a count of how many new blocks we allocated during this GC
215    * (used for resizing the allocation area, later).
216    */
217   new_blocks = 0;
218
219   /* Initialise to-space in all the generations/steps that we're
220    * collecting.
221    */
222   for (g = 0; g <= N; g++) {
223     generations[g].mut_once_list = END_MUT_LIST;
224     generations[g].mut_list = END_MUT_LIST;
225
226     for (s = 0; s < generations[g].n_steps; s++) {
227
228       /* generation 0, step 0 doesn't need to-space */
229       if (g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1) { 
230         continue; 
231       }
232
233       /* Get a free block for to-space.  Extra blocks will be chained on
234        * as necessary.
235        */
236       bd = allocBlock();
237       step = &generations[g].steps[s];
238       ASSERT(step->gen->no == g);
239       ASSERT(step->hp ? Bdescr(step->hp)->step == step : rtsTrue);
240       bd->gen  = &generations[g];
241       bd->step = step;
242       bd->link = NULL;
243       bd->evacuated = 1;        /* it's a to-space block */
244       step->hp        = bd->start;
245       step->hpLim     = step->hp + BLOCK_SIZE_W;
246       step->hp_bd     = bd;
247       step->to_space  = bd;
248       step->to_blocks = 1;
249       step->scan      = bd->start;
250       step->scan_bd   = bd;
251       step->new_large_objects = NULL;
252       step->scavenged_large_objects = NULL;
253       new_blocks++;
254       /* mark the large objects as not evacuated yet */
255       for (bd = step->large_objects; bd; bd = bd->link) {
256         bd->evacuated = 0;
257       }
258     }
259   }
260
261   /* make sure the older generations have at least one block to
262    * allocate into (this makes things easier for copy(), see below.
263    */
264   for (g = N+1; g < RtsFlags.GcFlags.generations; g++) {
265     for (s = 0; s < generations[g].n_steps; s++) {
266       step = &generations[g].steps[s];
267       if (step->hp_bd == NULL) {
268         bd = allocBlock();
269         bd->gen = &generations[g];
270         bd->step = step;
271         bd->link = NULL;
272         bd->evacuated = 0;      /* *not* a to-space block */
273         step->hp = bd->start;
274         step->hpLim = step->hp + BLOCK_SIZE_W;
275         step->hp_bd = bd;
276         step->blocks = bd;
277         step->n_blocks = 1;
278         new_blocks++;
279       }
280       /* Set the scan pointer for older generations: remember we
281        * still have to scavenge objects that have been promoted. */
282       step->scan = step->hp;
283       step->scan_bd = step->hp_bd;
284       step->to_space = NULL;
285       step->to_blocks = 0;
286       step->new_large_objects = NULL;
287       step->scavenged_large_objects = NULL;
288     }
289   }
290
291   /* -----------------------------------------------------------------------
292    * follow all the roots that we know about:
293    *   - mutable lists from each generation > N
294    * we want to *scavenge* these roots, not evacuate them: they're not
295    * going to move in this GC.
296    * Also: do them in reverse generation order.  This is because we
297    * often want to promote objects that are pointed to by older
298    * generations early, so we don't have to repeatedly copy them.
299    * Doing the generations in reverse order ensures that we don't end
300    * up in the situation where we want to evac an object to gen 3 and
301    * it has already been evaced to gen 2.
302    */
303   { 
304     int st;
305     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
306       generations[g].saved_mut_list = generations[g].mut_list;
307       generations[g].mut_list = END_MUT_LIST;
308     }
309
310     /* Do the mut-once lists first */
311     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
312       scavenge_mut_once_list(&generations[g]);
313       evac_gen = g;
314       for (st = generations[g].n_steps-1; st >= 0; st--) {
315         scavenge(&generations[g].steps[st]);
316       }
317     }
318
319     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
320       scavenge_mutable_list(&generations[g]);
321       evac_gen = g;
322       for (st = generations[g].n_steps-1; st >= 0; st--) {
323         scavenge(&generations[g].steps[st]);
324       }
325     }
326   }
327
328   /* follow all the roots that the application knows about.
329    */
330   evac_gen = 0;
331   get_roots();
332
333   /* And don't forget to mark the TSO if we got here direct from
334    * Haskell! */
335   if (CurrentTSO) {
336     CurrentTSO = (StgTSO *)MarkRoot((StgClosure *)CurrentTSO);
337   }
338
339   /* Mark the weak pointer list, and prepare to detect dead weak
340    * pointers.
341    */
342   old_weak_ptr_list = weak_ptr_list;
343   weak_ptr_list = NULL;
344   weak_done = rtsFalse;
345
346   /* Mark the stable pointer table.
347    */
348   markStablePtrTable(major_gc);
349
350 #ifdef INTERPRETER
351   { 
352       /* ToDo: To fix the caf leak, we need to make the commented out
353        * parts of this code do something sensible - as described in 
354        * the CAF document.
355        */
356       extern void markHugsObjects(void);
357 #if 0
358       /* ToDo: This (undefined) function should contain the scavenge
359        * loop immediately below this block of code - but I'm not sure
360        * enough of the details to do this myself.
361        */
362       scavengeEverything();
363       /* revert dead CAFs and update enteredCAFs list */
364       revert_dead_CAFs();
365 #endif      
366       markHugsObjects();
367 #if 0
368       /* This will keep the CAFs and the attached BCOs alive 
369        * but the values will have been reverted
370        */
371       scavengeEverything();
372 #endif
373   }
374 #endif
375
376   /* -------------------------------------------------------------------------
377    * Repeatedly scavenge all the areas we know about until there's no
378    * more scavenging to be done.
379    */
380   { 
381     rtsBool flag;
382   loop:
383     flag = rtsFalse;
384
385     /* scavenge static objects */
386     if (major_gc && static_objects != END_OF_STATIC_LIST) {
387       scavenge_static();
388     }
389
390     /* When scavenging the older generations:  Objects may have been
391      * evacuated from generations <= N into older generations, and we
392      * need to scavenge these objects.  We're going to try to ensure that
393      * any evacuations that occur move the objects into at least the
394      * same generation as the object being scavenged, otherwise we
395      * have to create new entries on the mutable list for the older
396      * generation.
397      */
398
399     /* scavenge each step in generations 0..maxgen */
400     { 
401       int gen, st; 
402     loop2:
403       for (gen = RtsFlags.GcFlags.generations-1; gen >= 0; gen--) {
404         for (st = generations[gen].n_steps-1; st >= 0 ; st--) {
405           if (gen == 0 && st == 0 && RtsFlags.GcFlags.generations > 1) { 
406             continue; 
407           }
408           step = &generations[gen].steps[st];
409           evac_gen = gen;
410           if (step->hp_bd != step->scan_bd || step->scan < step->hp) {
411             scavenge(step);
412             flag = rtsTrue;
413             goto loop2;
414           }
415           if (step->new_large_objects != NULL) {
416             scavenge_large(step);
417             flag = rtsTrue;
418             goto loop2;
419           }
420         }
421       }
422     }
423     if (flag) { goto loop; }
424
425     /* must be last... */
426     if (traverse_weak_ptr_list()) { /* returns rtsTrue if evaced something */
427       goto loop;
428     }
429   }
430
431   /* Final traversal of the weak pointer list (see comment by
432    * cleanUpWeakPtrList below).
433    */
434   cleanup_weak_ptr_list();
435
436   /* Now see which stable names are still alive.
437    */
438   gcStablePtrTable(major_gc);
439
440   /* Set the maximum blocks for the oldest generation, based on twice
441    * the amount of live data now, adjusted to fit the maximum heap
442    * size if necessary.  
443    *
444    * This is an approximation, since in the worst case we'll need
445    * twice the amount of live data plus whatever space the other
446    * generations need.
447    */
448   if (RtsFlags.GcFlags.generations > 1) {
449     if (major_gc) {
450       oldest_gen->max_blocks = 
451         stg_max(oldest_gen->steps[0].to_blocks * RtsFlags.GcFlags.oldGenFactor,
452                 RtsFlags.GcFlags.minOldGenSize);
453       if (oldest_gen->max_blocks > RtsFlags.GcFlags.maxHeapSize / 2) {
454         oldest_gen->max_blocks = RtsFlags.GcFlags.maxHeapSize / 2;
455         if (((int)oldest_gen->max_blocks - 
456              (int)oldest_gen->steps[0].to_blocks) < 
457             (RtsFlags.GcFlags.pcFreeHeap *
458              RtsFlags.GcFlags.maxHeapSize / 200)) {
459           heapOverflow();
460         }
461       }
462     }
463   }
464
465   /* run through all the generations/steps and tidy up 
466    */
467   copied = new_blocks * BLOCK_SIZE_W;
468   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
469
470     if (g <= N) {
471       generations[g].collections++; /* for stats */
472     }
473
474     for (s = 0; s < generations[g].n_steps; s++) {
475       bdescr *next;
476       step = &generations[g].steps[s];
477
478       if (!(g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1)) {
479         /* Tidy the end of the to-space chains */
480         step->hp_bd->free = step->hp;
481         step->hp_bd->link = NULL;
482         /* stats information: how much we copied */
483         if (g <= N) {
484           copied -= step->hp_bd->start + BLOCK_SIZE_W -
485             step->hp_bd->free;
486         }
487       }
488
489       /* for generations we collected... */
490       if (g <= N) {
491
492         collected += step->n_blocks * BLOCK_SIZE_W; /* for stats */
493
494         /* free old memory and shift to-space into from-space for all
495          * the collected steps (except the allocation area).  These
496          * freed blocks will probaby be quickly recycled.
497          */
498         if (!(g == 0 && s == 0)) {
499           freeChain(step->blocks);
500           step->blocks = step->to_space;
501           step->n_blocks = step->to_blocks;
502           step->to_space = NULL;
503           step->to_blocks = 0;
504           for (bd = step->blocks; bd != NULL; bd = bd->link) {
505             bd->evacuated = 0;  /* now from-space */
506           }
507         }
508
509         /* LARGE OBJECTS.  The current live large objects are chained on
510          * scavenged_large, having been moved during garbage
511          * collection from large_objects.  Any objects left on
512          * large_objects list are therefore dead, so we free them here.
513          */
514         for (bd = step->large_objects; bd != NULL; bd = next) {
515           next = bd->link;
516           freeGroup(bd);
517           bd = next;
518         }
519         for (bd = step->scavenged_large_objects; bd != NULL; bd = bd->link) {
520           bd->evacuated = 0;
521         }
522         step->large_objects = step->scavenged_large_objects;
523
524         /* Set the maximum blocks for this generation, interpolating
525          * between the maximum size of the oldest and youngest
526          * generations.
527          *
528          * max_blocks =    oldgen_max_blocks * G
529          *                 ----------------------
530          *                      oldest_gen
531          */
532         if (g != 0) {
533 #if 0
534           generations[g].max_blocks = (oldest_gen->max_blocks * g)
535                / (RtsFlags.GcFlags.generations-1);
536 #endif
537           generations[g].max_blocks = oldest_gen->max_blocks;
538         }
539
540       /* for older generations... */
541       } else {
542         
543         /* For older generations, we need to append the
544          * scavenged_large_object list (i.e. large objects that have been
545          * promoted during this GC) to the large_object list for that step.
546          */
547         for (bd = step->scavenged_large_objects; bd; bd = next) {
548           next = bd->link;
549           bd->evacuated = 0;
550           dbl_link_onto(bd, &step->large_objects);
551         }
552
553         /* add the new blocks we promoted during this GC */
554         step->n_blocks += step->to_blocks;
555       }
556     }
557   }
558   
559   /* Guess the amount of live data for stats. */
560   live = calcLive();
561
562   /* Free the small objects allocated via allocate(), since this will
563    * all have been copied into G0S1 now.  
564    */
565   if (small_alloc_list != NULL) {
566     freeChain(small_alloc_list);
567   }
568   small_alloc_list = NULL;
569   alloc_blocks = 0;
570   alloc_Hp = NULL;
571   alloc_HpLim = NULL;
572   alloc_blocks_lim = RtsFlags.GcFlags.minAllocAreaSize;
573
574   /* Two-space collector:
575    * Free the old to-space, and estimate the amount of live data.
576    */
577   if (RtsFlags.GcFlags.generations == 1) {
578     nat blocks;
579     
580     if (old_to_space != NULL) {
581       freeChain(old_to_space);
582     }
583     for (bd = g0s0->to_space; bd != NULL; bd = bd->link) {
584       bd->evacuated = 0;        /* now from-space */
585     }
586
587     /* For a two-space collector, we need to resize the nursery. */
588     
589     /* set up a new nursery.  Allocate a nursery size based on a
590      * function of the amount of live data (currently a factor of 2,
591      * should be configurable (ToDo)).  Use the blocks from the old
592      * nursery if possible, freeing up any left over blocks.
593      *
594      * If we get near the maximum heap size, then adjust our nursery
595      * size accordingly.  If the nursery is the same size as the live
596      * data (L), then we need 3L bytes.  We can reduce the size of the
597      * nursery to bring the required memory down near 2L bytes.
598      * 
599      * A normal 2-space collector would need 4L bytes to give the same
600      * performance we get from 3L bytes, reducing to the same
601      * performance at 2L bytes.  
602      */
603     blocks = g0s0->to_blocks;
604
605     if ( blocks * RtsFlags.GcFlags.oldGenFactor * 2 > 
606          RtsFlags.GcFlags.maxHeapSize ) {
607       int adjusted_blocks;  /* signed on purpose */
608       int pc_free; 
609       
610       adjusted_blocks = (RtsFlags.GcFlags.maxHeapSize - 2 * blocks);
611       IF_DEBUG(gc, fprintf(stderr, "Near maximum heap size of 0x%x blocks, blocks = %d, adjusted to %d\n", RtsFlags.GcFlags.maxHeapSize, blocks, adjusted_blocks));
612       pc_free = adjusted_blocks * 100 / RtsFlags.GcFlags.maxHeapSize;
613       if (pc_free < RtsFlags.GcFlags.pcFreeHeap) /* might even be < 0 */ {
614         heapOverflow();
615       }
616       blocks = adjusted_blocks;
617       
618     } else {
619       blocks *= RtsFlags.GcFlags.oldGenFactor;
620       if (blocks < RtsFlags.GcFlags.minAllocAreaSize) {
621         blocks = RtsFlags.GcFlags.minAllocAreaSize;
622       }
623     }
624     resizeNursery(blocks);
625     
626   } else {
627     /* Generational collector:
628      * If the user has given us a suggested heap size, adjust our
629      * allocation area to make best use of the memory available.
630      */
631
632     if (RtsFlags.GcFlags.heapSizeSuggestion) {
633       int blocks;
634       nat needed = calcNeeded();        /* approx blocks needed at next GC */
635
636       /* Guess how much will be live in generation 0 step 0 next time.
637        * A good approximation is the obtained by finding the
638        * percentage of g0s0 that was live at the last minor GC.
639        */
640       if (N == 0) {
641         g0s0_pcnt_kept = (new_blocks * 100) / g0s0->n_blocks;
642       }
643
644       /* Estimate a size for the allocation area based on the
645        * information available.  We might end up going slightly under
646        * or over the suggested heap size, but we should be pretty
647        * close on average.
648        *
649        * Formula:            suggested - needed
650        *                ----------------------------
651        *                    1 + g0s0_pcnt_kept/100
652        *
653        * where 'needed' is the amount of memory needed at the next
654        * collection for collecting all steps except g0s0.
655        */
656       blocks = 
657         (((int)RtsFlags.GcFlags.heapSizeSuggestion - (int)needed) * 100) /
658         (100 + (int)g0s0_pcnt_kept);
659       
660       if (blocks < (int)RtsFlags.GcFlags.minAllocAreaSize) {
661         blocks = RtsFlags.GcFlags.minAllocAreaSize;
662       }
663       
664       resizeNursery((nat)blocks);
665     }
666   }
667
668   /* revert dead CAFs and update enteredCAFs list */
669   revert_dead_CAFs();
670   
671   /* mark the garbage collected CAFs as dead */
672 #ifdef DEBUG
673   if (major_gc) { gcCAFs(); }
674 #endif
675   
676   /* zero the scavenged static object list */
677   if (major_gc) {
678     zero_static_object_list(scavenged_static_objects);
679   }
680
681   /* Reset the nursery
682    */
683   for (bd = g0s0->blocks; bd; bd = bd->link) {
684     bd->free = bd->start;
685     ASSERT(bd->gen == g0);
686     ASSERT(bd->step == g0s0);
687     IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
688   }
689   current_nursery = g0s0->blocks;
690
691   /* start any pending finalizers */
692   scheduleFinalizers(old_weak_ptr_list);
693   
694   /* check sanity after GC */
695   IF_DEBUG(sanity, checkSanity(N));
696
697   /* extra GC trace info */
698   IF_DEBUG(gc, stat_describe_gens());
699
700 #ifdef DEBUG
701   /* symbol-table based profiling */
702   /*  heapCensus(to_space); */ /* ToDo */
703 #endif
704
705   /* restore enclosing cost centre */
706 #ifdef PROFILING
707   CCCS = prev_CCS;
708 #endif
709
710   /* check for memory leaks if sanity checking is on */
711   IF_DEBUG(sanity, memInventory());
712
713   /* ok, GC over: tell the stats department what happened. */
714   stat_endGC(allocated, collected, live, copied, N);
715 }
716
717 /* -----------------------------------------------------------------------------
718    Weak Pointers
719
720    traverse_weak_ptr_list is called possibly many times during garbage
721    collection.  It returns a flag indicating whether it did any work
722    (i.e. called evacuate on any live pointers).
723
724    Invariant: traverse_weak_ptr_list is called when the heap is in an
725    idempotent state.  That means that there are no pending
726    evacuate/scavenge operations.  This invariant helps the weak
727    pointer code decide which weak pointers are dead - if there are no
728    new live weak pointers, then all the currently unreachable ones are
729    dead.
730
731    For generational GC: we just don't try to finalize weak pointers in
732    older generations than the one we're collecting.  This could
733    probably be optimised by keeping per-generation lists of weak
734    pointers, but for a few weak pointers this scheme will work.
735    -------------------------------------------------------------------------- */
736
737 static rtsBool 
738 traverse_weak_ptr_list(void)
739 {
740   StgWeak *w, **last_w, *next_w;
741   StgClosure *new;
742   rtsBool flag = rtsFalse;
743
744   if (weak_done) { return rtsFalse; }
745
746   /* doesn't matter where we evacuate values/finalizers to, since
747    * these pointers are treated as roots (iff the keys are alive).
748    */
749   evac_gen = 0;
750
751   last_w = &old_weak_ptr_list;
752   for (w = old_weak_ptr_list; w; w = next_w) {
753
754     /* First, this weak pointer might have been evacuated.  If so,
755      * remove the forwarding pointer from the weak_ptr_list.
756      */
757     if (get_itbl(w)->type == EVACUATED) {
758       w = (StgWeak *)((StgEvacuated *)w)->evacuee;
759       *last_w = w;
760     }
761     ASSERT(get_itbl(w)->type == WEAK);
762
763     /* Now, check whether the key is reachable.
764      */
765     if ((new = isAlive(w->key))) {
766       w->key = new;
767       /* evacuate the value and finalizer */
768       w->value = evacuate(w->value);
769       w->finalizer = evacuate(w->finalizer);
770       /* remove this weak ptr from the old_weak_ptr list */
771       *last_w = w->link;
772       /* and put it on the new weak ptr list */
773       next_w  = w->link;
774       w->link = weak_ptr_list;
775       weak_ptr_list = w;
776       flag = rtsTrue;
777       IF_DEBUG(weak, fprintf(stderr,"Weak pointer still alive at %p -> %p\n", w, w->key));
778       continue;
779     }
780     else {
781       last_w = &(w->link);
782       next_w = w->link;
783       continue;
784     }
785   }
786   
787   /* If we didn't make any changes, then we can go round and kill all
788    * the dead weak pointers.  The old_weak_ptr list is used as a list
789    * of pending finalizers later on.
790    */
791   if (flag == rtsFalse) {
792     for (w = old_weak_ptr_list; w; w = w->link) {
793       w->value = evacuate(w->value);
794       w->finalizer = evacuate(w->finalizer);
795     }
796     weak_done = rtsTrue;
797   }
798
799   return rtsTrue;
800 }
801
802 /* -----------------------------------------------------------------------------
803    After GC, the live weak pointer list may have forwarding pointers
804    on it, because a weak pointer object was evacuated after being
805    moved to the live weak pointer list.  We remove those forwarding
806    pointers here.
807
808    Also, we don't consider weak pointer objects to be reachable, but
809    we must nevertheless consider them to be "live" and retain them.
810    Therefore any weak pointer objects which haven't as yet been
811    evacuated need to be evacuated now.
812    -------------------------------------------------------------------------- */
813
814 static void
815 cleanup_weak_ptr_list ( void )
816 {
817   StgWeak *w, **last_w;
818
819   last_w = &weak_ptr_list;
820   for (w = weak_ptr_list; w; w = w->link) {
821
822     if (get_itbl(w)->type == EVACUATED) {
823       w = (StgWeak *)((StgEvacuated *)w)->evacuee;
824       *last_w = w;
825     }
826
827     if (Bdescr((P_)w)->evacuated == 0) {
828       (StgClosure *)w = evacuate((StgClosure *)w);
829       *last_w = w;
830     }
831     last_w = &(w->link);
832   }
833 }
834
835 /* -----------------------------------------------------------------------------
836    isAlive determines whether the given closure is still alive (after
837    a garbage collection) or not.  It returns the new address of the
838    closure if it is alive, or NULL otherwise.
839    -------------------------------------------------------------------------- */
840
841 StgClosure *
842 isAlive(StgClosure *p)
843 {
844   StgInfoTable *info;
845
846   while (1) {
847
848     info = get_itbl(p);
849
850     /* ToDo: for static closures, check the static link field.
851      * Problem here is that we sometimes don't set the link field, eg.
852      * for static closures with an empty SRT or CONSTR_STATIC_NOCAFs.
853      */
854
855     /* ignore closures in generations that we're not collecting. */
856     if (LOOKS_LIKE_STATIC(p) || Bdescr((P_)p)->gen->no > N) {
857       return p;
858     }
859     
860     switch (info->type) {
861       
862     case IND:
863     case IND_STATIC:
864     case IND_PERM:
865     case IND_OLDGEN:            /* rely on compatible layout with StgInd */
866     case IND_OLDGEN_PERM:
867       /* follow indirections */
868       p = ((StgInd *)p)->indirectee;
869       continue;
870       
871     case EVACUATED:
872       /* alive! */
873       return ((StgEvacuated *)p)->evacuee;
874
875     default:
876       /* dead. */
877       return NULL;
878     }
879   }
880 }
881
882 StgClosure *
883 MarkRoot(StgClosure *root)
884 {
885   return evacuate(root);
886 }
887
888 static void addBlock(step *step)
889 {
890   bdescr *bd = allocBlock();
891   bd->gen = step->gen;
892   bd->step = step;
893
894   if (step->gen->no <= N) {
895     bd->evacuated = 1;
896   } else {
897     bd->evacuated = 0;
898   }
899
900   step->hp_bd->free = step->hp;
901   step->hp_bd->link = bd;
902   step->hp = bd->start;
903   step->hpLim = step->hp + BLOCK_SIZE_W;
904   step->hp_bd = bd;
905   step->to_blocks++;
906   new_blocks++;
907 }
908
909 static __inline__ void 
910 upd_evacuee(StgClosure *p, StgClosure *dest)
911 {
912   p->header.info = &EVACUATED_info;
913   ((StgEvacuated *)p)->evacuee = dest;
914 }
915
916 static __inline__ StgClosure *
917 copy(StgClosure *src, nat size, step *step)
918 {
919   P_ to, from, dest;
920
921   TICK_GC_WORDS_COPIED(size);
922   /* Find out where we're going, using the handy "to" pointer in 
923    * the step of the source object.  If it turns out we need to
924    * evacuate to an older generation, adjust it here (see comment
925    * by evacuate()).
926    */
927   if (step->gen->no < evac_gen) {
928 #ifdef NO_EAGER_PROMOTION    
929     failed_to_evac = rtsTrue;
930 #else
931     step = &generations[evac_gen].steps[0];
932 #endif
933   }
934
935   /* chain a new block onto the to-space for the destination step if
936    * necessary.
937    */
938   if (step->hp + size >= step->hpLim) {
939     addBlock(step);
940   }
941
942   for(to = step->hp, from = (P_)src; size>0; --size) {
943     *to++ = *from++;
944   }
945
946   dest = step->hp;
947   step->hp = to;
948   upd_evacuee(src,(StgClosure *)dest);
949   return (StgClosure *)dest;
950 }
951
952 /* Special version of copy() for when we only want to copy the info
953  * pointer of an object, but reserve some padding after it.  This is
954  * used to optimise evacuation of BLACKHOLEs.
955  */
956
957 static __inline__ StgClosure *
958 copyPart(StgClosure *src, nat size_to_reserve, nat size_to_copy, step *step)
959 {
960   P_ dest, to, from;
961
962   TICK_GC_WORDS_COPIED(size_to_copy);
963   if (step->gen->no < evac_gen) {
964 #ifdef NO_EAGER_PROMOTION    
965     failed_to_evac = rtsTrue;
966 #else
967     step = &generations[evac_gen].steps[0];
968 #endif
969   }
970
971   if (step->hp + size_to_reserve >= step->hpLim) {
972     addBlock(step);
973   }
974
975   for(to = step->hp, from = (P_)src; size_to_copy>0; --size_to_copy) {
976     *to++ = *from++;
977   }
978   
979   dest = step->hp;
980   step->hp += size_to_reserve;
981   upd_evacuee(src,(StgClosure *)dest);
982   return (StgClosure *)dest;
983 }
984
985 /* -----------------------------------------------------------------------------
986    Evacuate a large object
987
988    This just consists of removing the object from the (doubly-linked)
989    large_alloc_list, and linking it on to the (singly-linked)
990    new_large_objects list, from where it will be scavenged later.
991
992    Convention: bd->evacuated is /= 0 for a large object that has been
993    evacuated, or 0 otherwise.
994    -------------------------------------------------------------------------- */
995
996 static inline void
997 evacuate_large(StgPtr p, rtsBool mutable)
998 {
999   bdescr *bd = Bdescr(p);
1000   step *step;
1001
1002   /* should point to the beginning of the block */
1003   ASSERT(((W_)p & BLOCK_MASK) == 0);
1004   
1005   /* already evacuated? */
1006   if (bd->evacuated) { 
1007     /* Don't forget to set the failed_to_evac flag if we didn't get
1008      * the desired destination (see comments in evacuate()).
1009      */
1010     if (bd->gen->no < evac_gen) {
1011       failed_to_evac = rtsTrue;
1012       TICK_GC_FAILED_PROMOTION();
1013     }
1014     return;
1015   }
1016
1017   step = bd->step;
1018   /* remove from large_object list */
1019   if (bd->back) {
1020     bd->back->link = bd->link;
1021   } else { /* first object in the list */
1022     step->large_objects = bd->link;
1023   }
1024   if (bd->link) {
1025     bd->link->back = bd->back;
1026   }
1027   
1028   /* link it on to the evacuated large object list of the destination step
1029    */
1030   step = bd->step->to;
1031   if (step->gen->no < evac_gen) {
1032 #ifdef NO_EAGER_PROMOTION    
1033     failed_to_evac = rtsTrue;
1034 #else
1035     step = &generations[evac_gen].steps[0];
1036 #endif
1037   }
1038
1039   bd->step = step;
1040   bd->gen = step->gen;
1041   bd->link = step->new_large_objects;
1042   step->new_large_objects = bd;
1043   bd->evacuated = 1;
1044
1045   if (mutable) {
1046     recordMutable((StgMutClosure *)p);
1047   }
1048 }
1049
1050 /* -----------------------------------------------------------------------------
1051    Adding a MUT_CONS to an older generation.
1052
1053    This is necessary from time to time when we end up with an
1054    old-to-new generation pointer in a non-mutable object.  We defer
1055    the promotion until the next GC.
1056    -------------------------------------------------------------------------- */
1057
1058 static StgClosure *
1059 mkMutCons(StgClosure *ptr, generation *gen)
1060 {
1061   StgMutVar *q;
1062   step *step;
1063
1064   step = &gen->steps[0];
1065
1066   /* chain a new block onto the to-space for the destination step if
1067    * necessary.
1068    */
1069   if (step->hp + sizeofW(StgIndOldGen) >= step->hpLim) {
1070     addBlock(step);
1071   }
1072
1073   q = (StgMutVar *)step->hp;
1074   step->hp += sizeofW(StgMutVar);
1075
1076   SET_HDR(q,&MUT_CONS_info,CCS_GC);
1077   q->var = ptr;
1078   recordOldToNewPtrs((StgMutClosure *)q);
1079
1080   return (StgClosure *)q;
1081 }
1082
1083 /* -----------------------------------------------------------------------------
1084    Evacuate
1085
1086    This is called (eventually) for every live object in the system.
1087
1088    The caller to evacuate specifies a desired generation in the
1089    evac_gen global variable.  The following conditions apply to
1090    evacuating an object which resides in generation M when we're
1091    collecting up to generation N
1092
1093    if  M >= evac_gen 
1094            if  M > N     do nothing
1095            else          evac to step->to
1096
1097    if  M < evac_gen      evac to evac_gen, step 0
1098
1099    if the object is already evacuated, then we check which generation
1100    it now resides in.
1101
1102    if  M >= evac_gen     do nothing
1103    if  M <  evac_gen     set failed_to_evac flag to indicate that we
1104                          didn't manage to evacuate this object into evac_gen.
1105
1106    -------------------------------------------------------------------------- */
1107
1108
1109 static StgClosure *
1110 evacuate(StgClosure *q)
1111 {
1112   StgClosure *to;
1113   bdescr *bd = NULL;
1114   step *step;
1115   const StgInfoTable *info;
1116
1117 loop:
1118   if (!LOOKS_LIKE_STATIC(q)) {
1119     bd = Bdescr((P_)q);
1120     if (bd->gen->no > N) {
1121       /* Can't evacuate this object, because it's in a generation
1122        * older than the ones we're collecting.  Let's hope that it's
1123        * in evac_gen or older, or we will have to make an IND_OLDGEN object.
1124        */
1125       if (bd->gen->no < evac_gen) {
1126         /* nope */
1127         failed_to_evac = rtsTrue;
1128         TICK_GC_FAILED_PROMOTION();
1129       }
1130       return q;
1131     }
1132     step = bd->step->to;
1133   }
1134
1135   /* make sure the info pointer is into text space */
1136   ASSERT(q && (LOOKS_LIKE_GHC_INFO(GET_INFO(q))
1137                || IS_HUGS_CONSTR_INFO(GET_INFO(q))));
1138
1139   info = get_itbl(q);
1140   switch (info -> type) {
1141
1142   case BCO:
1143     return copy(q,bco_sizeW(stgCast(StgBCO*,q)),step);
1144
1145   case MUT_VAR:
1146     ASSERT(q->header.info != &MUT_CONS_info);
1147   case MVAR:
1148     to = copy(q,sizeW_fromITBL(info),step);
1149     recordMutable((StgMutClosure *)to);
1150     return to;
1151
1152   case FUN_1_0:
1153   case FUN_0_1:
1154   case CONSTR_1_0:
1155   case CONSTR_0_1:
1156     return copy(q,sizeofW(StgHeader)+1,step);
1157
1158   case THUNK_1_0:               /* here because of MIN_UPD_SIZE */
1159   case THUNK_0_1:
1160   case THUNK_1_1:
1161   case THUNK_0_2:
1162   case THUNK_2_0:
1163 #ifdef NO_PROMOTE_THUNKS
1164     if (bd->gen->no == 0 && 
1165         bd->step->no != 0 &&
1166         bd->step->no == bd->gen->n_steps-1) {
1167       step = bd->step;
1168     }
1169 #endif
1170     return copy(q,sizeofW(StgHeader)+2,step);
1171
1172   case FUN_1_1:
1173   case FUN_0_2:
1174   case FUN_2_0:
1175   case CONSTR_1_1:
1176   case CONSTR_0_2:
1177   case CONSTR_2_0:
1178     return copy(q,sizeofW(StgHeader)+2,step);
1179
1180   case FUN:
1181   case THUNK:
1182   case CONSTR:
1183   case IND_PERM:
1184   case IND_OLDGEN_PERM:
1185   case CAF_UNENTERED:
1186   case CAF_ENTERED:
1187   case WEAK:
1188   case FOREIGN:
1189   case STABLE_NAME:
1190     return copy(q,sizeW_fromITBL(info),step);
1191
1192   case CAF_BLACKHOLE:
1193   case BLACKHOLE:
1194     return copyPart(q,BLACKHOLE_sizeW(),sizeofW(StgHeader),step);
1195
1196   case BLACKHOLE_BQ:
1197     to = copy(q,BLACKHOLE_sizeW(),step); 
1198     recordMutable((StgMutClosure *)to);
1199     return to;
1200
1201   case THUNK_SELECTOR:
1202     {
1203       const StgInfoTable* selectee_info;
1204       StgClosure* selectee = ((StgSelector*)q)->selectee;
1205
1206     selector_loop:
1207       selectee_info = get_itbl(selectee);
1208       switch (selectee_info->type) {
1209       case CONSTR:
1210       case CONSTR_1_0:
1211       case CONSTR_0_1:
1212       case CONSTR_2_0:
1213       case CONSTR_1_1:
1214       case CONSTR_0_2:
1215       case CONSTR_STATIC:
1216         { 
1217           StgNat32 offset = info->layout.selector_offset;
1218
1219           /* check that the size is in range */
1220           ASSERT(offset < 
1221                  (StgNat32)(selectee_info->layout.payload.ptrs + 
1222                             selectee_info->layout.payload.nptrs));
1223
1224           /* perform the selection! */
1225           q = selectee->payload[offset];
1226
1227           /* if we're already in to-space, there's no need to continue
1228            * with the evacuation, just update the source address with
1229            * a pointer to the (evacuated) constructor field.
1230            */
1231           if (IS_USER_PTR(q)) {
1232             bdescr *bd = Bdescr((P_)q);
1233             if (bd->evacuated) {
1234               if (bd->gen->no < evac_gen) {
1235                 failed_to_evac = rtsTrue;
1236                 TICK_GC_FAILED_PROMOTION();
1237               }
1238               return q;
1239             }
1240           }
1241
1242           /* otherwise, carry on and evacuate this constructor field,
1243            * (but not the constructor itself)
1244            */
1245           goto loop;
1246         }
1247
1248       case IND:
1249       case IND_STATIC:
1250       case IND_PERM:
1251       case IND_OLDGEN:
1252       case IND_OLDGEN_PERM:
1253         selectee = stgCast(StgInd *,selectee)->indirectee;
1254         goto selector_loop;
1255
1256       case CAF_ENTERED:
1257         selectee = stgCast(StgCAF *,selectee)->value;
1258         goto selector_loop;
1259
1260       case EVACUATED:
1261         selectee = stgCast(StgEvacuated*,selectee)->evacuee;
1262         goto selector_loop;
1263
1264       case THUNK:
1265       case THUNK_1_0:
1266       case THUNK_0_1:
1267       case THUNK_2_0:
1268       case THUNK_1_1:
1269       case THUNK_0_2:
1270       case THUNK_STATIC:
1271       case THUNK_SELECTOR:
1272         /* aargh - do recursively???? */
1273       case CAF_UNENTERED:
1274       case CAF_BLACKHOLE:
1275       case BLACKHOLE:
1276       case BLACKHOLE_BQ:
1277         /* not evaluated yet */
1278         break;
1279
1280       default:
1281         barf("evacuate: THUNK_SELECTOR: strange selectee");
1282       }
1283     }
1284     return copy(q,THUNK_SELECTOR_sizeW(),step);
1285
1286   case IND:
1287   case IND_OLDGEN:
1288     /* follow chains of indirections, don't evacuate them */
1289     q = ((StgInd*)q)->indirectee;
1290     goto loop;
1291
1292     /* ToDo: optimise STATIC_LINK for known cases.
1293        - FUN_STATIC       : payload[0]
1294        - THUNK_STATIC     : payload[1]
1295        - IND_STATIC       : payload[1]
1296     */
1297   case THUNK_STATIC:
1298   case FUN_STATIC:
1299     if (info->srt_len == 0) {   /* small optimisation */
1300       return q;
1301     }
1302     /* fall through */
1303   case CONSTR_STATIC:
1304   case IND_STATIC:
1305     /* don't want to evacuate these, but we do want to follow pointers
1306      * from SRTs  - see scavenge_static.
1307      */
1308
1309     /* put the object on the static list, if necessary.
1310      */
1311     if (major_gc && STATIC_LINK(info,(StgClosure *)q) == NULL) {
1312       STATIC_LINK(info,(StgClosure *)q) = static_objects;
1313       static_objects = (StgClosure *)q;
1314     }
1315     /* fall through */
1316
1317   case CONSTR_INTLIKE:
1318   case CONSTR_CHARLIKE:
1319   case CONSTR_NOCAF_STATIC:
1320     /* no need to put these on the static linked list, they don't need
1321      * to be scavenged.
1322      */
1323     return q;
1324
1325   case RET_BCO:
1326   case RET_SMALL:
1327   case RET_VEC_SMALL:
1328   case RET_BIG:
1329   case RET_VEC_BIG:
1330   case RET_DYN:
1331   case UPDATE_FRAME:
1332   case STOP_FRAME:
1333   case CATCH_FRAME:
1334   case SEQ_FRAME:
1335     /* shouldn't see these */
1336     barf("evacuate: stack frame\n");
1337
1338   case AP_UPD:
1339   case PAP:
1340     /* these are special - the payload is a copy of a chunk of stack,
1341        tagging and all. */
1342     return copy(q,pap_sizeW(stgCast(StgPAP*,q)),step);
1343
1344   case EVACUATED:
1345     /* Already evacuated, just return the forwarding address.
1346      * HOWEVER: if the requested destination generation (evac_gen) is
1347      * older than the actual generation (because the object was
1348      * already evacuated to a younger generation) then we have to
1349      * set the failed_to_evac flag to indicate that we couldn't 
1350      * manage to promote the object to the desired generation.
1351      */
1352     if (evac_gen > 0) {         /* optimisation */
1353       StgClosure *p = ((StgEvacuated*)q)->evacuee;
1354       if (Bdescr((P_)p)->gen->no < evac_gen) {
1355         /*      fprintf(stderr,"evac failed!\n");*/
1356         failed_to_evac = rtsTrue;
1357         TICK_GC_FAILED_PROMOTION();
1358       }
1359     }
1360     return ((StgEvacuated*)q)->evacuee;
1361
1362   case ARR_WORDS:
1363     {
1364       nat size = arr_words_sizeW(stgCast(StgArrWords*,q)); 
1365
1366       if (size >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
1367         evacuate_large((P_)q, rtsFalse);
1368         return q;
1369       } else {
1370         /* just copy the block */
1371         return copy(q,size,step);
1372       }
1373     }
1374
1375   case MUT_ARR_PTRS:
1376   case MUT_ARR_PTRS_FROZEN:
1377     {
1378       nat size = mut_arr_ptrs_sizeW(stgCast(StgMutArrPtrs*,q)); 
1379
1380       if (size >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
1381         evacuate_large((P_)q, info->type == MUT_ARR_PTRS);
1382         to = q;
1383       } else {
1384         /* just copy the block */
1385         to = copy(q,size,step);
1386         if (info->type == MUT_ARR_PTRS) {
1387           recordMutable((StgMutClosure *)to);
1388         }
1389       }
1390       return to;
1391     }
1392
1393   case TSO:
1394     {
1395       StgTSO *tso = stgCast(StgTSO *,q);
1396       nat size = tso_sizeW(tso);
1397       int diff;
1398
1399       /* Large TSOs don't get moved, so no relocation is required.
1400        */
1401       if (size >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
1402         evacuate_large((P_)q, rtsTrue);
1403         return q;
1404
1405       /* To evacuate a small TSO, we need to relocate the update frame
1406        * list it contains.  
1407        */
1408       } else {
1409         StgTSO *new_tso = (StgTSO *)copy((StgClosure *)tso,tso_sizeW(tso),step);
1410
1411         diff = (StgPtr)new_tso - (StgPtr)tso; /* In *words* */
1412
1413         /* relocate the stack pointers... */
1414         new_tso->su = (StgUpdateFrame *) ((StgPtr)new_tso->su + diff);
1415         new_tso->sp = (StgPtr)new_tso->sp + diff;
1416         new_tso->splim = (StgPtr)new_tso->splim + diff;
1417         
1418         relocate_TSO(tso, new_tso);
1419
1420         recordMutable((StgMutClosure *)new_tso);
1421         return (StgClosure *)new_tso;
1422       }
1423     }
1424
1425   case BLOCKED_FETCH:
1426   case FETCH_ME:
1427     fprintf(stderr,"evacuate: unimplemented/strange closure type\n");
1428     return q;
1429
1430   default:
1431     barf("evacuate: strange closure type");
1432   }
1433
1434   barf("evacuate");
1435 }
1436
1437 /* -----------------------------------------------------------------------------
1438    relocate_TSO is called just after a TSO has been copied from src to
1439    dest.  It adjusts the update frame list for the new location.
1440    -------------------------------------------------------------------------- */
1441
1442 StgTSO *
1443 relocate_TSO(StgTSO *src, StgTSO *dest)
1444 {
1445   StgUpdateFrame *su;
1446   StgCatchFrame  *cf;
1447   StgSeqFrame    *sf;
1448   int diff;
1449
1450   diff = (StgPtr)dest->sp - (StgPtr)src->sp; /* In *words* */
1451
1452   su = dest->su;
1453
1454   while ((P_)su < dest->stack + dest->stack_size) {
1455     switch (get_itbl(su)->type) {
1456    
1457       /* GCC actually manages to common up these three cases! */
1458
1459     case UPDATE_FRAME:
1460       su->link = (StgUpdateFrame *) ((StgPtr)su->link + diff);
1461       su = su->link;
1462       continue;
1463
1464     case CATCH_FRAME:
1465       cf = (StgCatchFrame *)su;
1466       cf->link = (StgUpdateFrame *) ((StgPtr)cf->link + diff);
1467       su = cf->link;
1468       continue;
1469
1470     case SEQ_FRAME:
1471       sf = (StgSeqFrame *)su;
1472       sf->link = (StgUpdateFrame *) ((StgPtr)sf->link + diff);
1473       su = sf->link;
1474       continue;
1475
1476     case STOP_FRAME:
1477       /* all done! */
1478       break;
1479
1480     default:
1481       barf("relocate_TSO");
1482     }
1483     break;
1484   }
1485
1486   return dest;
1487 }
1488
1489 static inline void
1490 scavenge_srt(const StgInfoTable *info)
1491 {
1492   StgClosure **srt, **srt_end;
1493
1494   /* evacuate the SRT.  If srt_len is zero, then there isn't an
1495    * srt field in the info table.  That's ok, because we'll
1496    * never dereference it.
1497    */
1498   srt = stgCast(StgClosure **,info->srt);
1499   srt_end = srt + info->srt_len;
1500   for (; srt < srt_end; srt++) {
1501     evacuate(*srt);
1502   }
1503 }
1504
1505 /* -----------------------------------------------------------------------------
1506    Scavenge a given step until there are no more objects in this step
1507    to scavenge.
1508
1509    evac_gen is set by the caller to be either zero (for a step in a
1510    generation < N) or G where G is the generation of the step being
1511    scavenged.  
1512
1513    We sometimes temporarily change evac_gen back to zero if we're
1514    scavenging a mutable object where early promotion isn't such a good
1515    idea.  
1516    -------------------------------------------------------------------------- */
1517    
1518
1519 static void
1520 scavenge(step *step)
1521 {
1522   StgPtr p, q;
1523   const StgInfoTable *info;
1524   bdescr *bd;
1525   nat saved_evac_gen = evac_gen; /* used for temporarily changing evac_gen */
1526
1527   p = step->scan;
1528   bd = step->scan_bd;
1529
1530   failed_to_evac = rtsFalse;
1531
1532   /* scavenge phase - standard breadth-first scavenging of the
1533    * evacuated objects 
1534    */
1535
1536   while (bd != step->hp_bd || p < step->hp) {
1537
1538     /* If we're at the end of this block, move on to the next block */
1539     if (bd != step->hp_bd && p == bd->free) {
1540       bd = bd->link;
1541       p = bd->start;
1542       continue;
1543     }
1544
1545     q = p;                      /* save ptr to object */
1546
1547     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO((StgClosure *)p))
1548                  || IS_HUGS_CONSTR_INFO(GET_INFO((StgClosure *)p))));
1549
1550     info = get_itbl((StgClosure *)p);
1551     switch (info -> type) {
1552
1553     case BCO:
1554       {
1555         StgBCO* bco = stgCast(StgBCO*,p);
1556         nat i;
1557         for (i = 0; i < bco->n_ptrs; i++) {
1558           bcoConstCPtr(bco,i) = evacuate(bcoConstCPtr(bco,i));
1559         }
1560         p += bco_sizeW(bco);
1561         break;
1562       }
1563
1564     case MVAR:
1565       /* treat MVars specially, because we don't want to evacuate the
1566        * mut_link field in the middle of the closure.
1567        */
1568       { 
1569         StgMVar *mvar = ((StgMVar *)p);
1570         evac_gen = 0;
1571         (StgClosure *)mvar->head = evacuate((StgClosure *)mvar->head);
1572         (StgClosure *)mvar->tail = evacuate((StgClosure *)mvar->tail);
1573         (StgClosure *)mvar->value = evacuate((StgClosure *)mvar->value);
1574         p += sizeofW(StgMVar);
1575         evac_gen = saved_evac_gen;
1576         break;
1577       }
1578
1579     case THUNK_2_0:
1580     case FUN_2_0:
1581       scavenge_srt(info);
1582     case CONSTR_2_0:
1583       ((StgClosure *)p)->payload[1] = evacuate(((StgClosure *)p)->payload[1]);
1584       ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
1585       p += sizeofW(StgHeader) + 2;
1586       break;
1587
1588     case THUNK_1_0:
1589       scavenge_srt(info);
1590       ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
1591       p += sizeofW(StgHeader) + 2; /* MIN_UPD_SIZE */
1592       break;
1593
1594     case FUN_1_0:
1595       scavenge_srt(info);
1596     case CONSTR_1_0:
1597       ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
1598       p += sizeofW(StgHeader) + 1;
1599       break;
1600
1601     case THUNK_0_1:
1602       scavenge_srt(info);
1603       p += sizeofW(StgHeader) + 2; /* MIN_UPD_SIZE */
1604       break;
1605
1606     case FUN_0_1:
1607       scavenge_srt(info);
1608     case CONSTR_0_1:
1609       p += sizeofW(StgHeader) + 1;
1610       break;
1611
1612     case THUNK_0_2:
1613     case FUN_0_2:
1614       scavenge_srt(info);
1615     case CONSTR_0_2:
1616       p += sizeofW(StgHeader) + 2;
1617       break;
1618
1619     case THUNK_1_1:
1620     case FUN_1_1:
1621       scavenge_srt(info);
1622     case CONSTR_1_1:
1623       ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
1624       p += sizeofW(StgHeader) + 2;
1625       break;
1626
1627     case FUN:
1628     case THUNK:
1629       scavenge_srt(info);
1630       /* fall through */
1631
1632     case CONSTR:
1633     case WEAK:
1634     case FOREIGN:
1635     case STABLE_NAME:
1636     case IND_PERM:
1637     case IND_OLDGEN_PERM:
1638     case CAF_UNENTERED:
1639     case CAF_ENTERED:
1640       {
1641         StgPtr end;
1642
1643         end = (P_)((StgClosure *)p)->payload + info->layout.payload.ptrs;
1644         for (p = (P_)((StgClosure *)p)->payload; p < end; p++) {
1645           (StgClosure *)*p = evacuate((StgClosure *)*p);
1646         }
1647         p += info->layout.payload.nptrs;
1648         break;
1649       }
1650
1651     case MUT_VAR:
1652       /* ignore MUT_CONSs */
1653       if (((StgMutVar *)p)->header.info != &MUT_CONS_info) {
1654         evac_gen = 0;
1655         ((StgMutVar *)p)->var = evacuate(((StgMutVar *)p)->var);
1656         evac_gen = saved_evac_gen;
1657       }
1658       p += sizeofW(StgMutVar);
1659       break;
1660
1661     case CAF_BLACKHOLE:
1662     case BLACKHOLE:
1663         p += BLACKHOLE_sizeW();
1664         break;
1665
1666     case BLACKHOLE_BQ:
1667       { 
1668         StgBlockingQueue *bh = (StgBlockingQueue *)p;
1669         (StgClosure *)bh->blocking_queue = 
1670           evacuate((StgClosure *)bh->blocking_queue);
1671         if (failed_to_evac) {
1672           failed_to_evac = rtsFalse;
1673           recordMutable((StgMutClosure *)bh);
1674         }
1675         p += BLACKHOLE_sizeW();
1676         break;
1677       }
1678
1679     case THUNK_SELECTOR:
1680       { 
1681         StgSelector *s = (StgSelector *)p;
1682         s->selectee = evacuate(s->selectee);
1683         p += THUNK_SELECTOR_sizeW();
1684         break;
1685       }
1686
1687     case IND:
1688     case IND_OLDGEN:
1689       barf("scavenge:IND???\n");
1690
1691     case CONSTR_INTLIKE:
1692     case CONSTR_CHARLIKE:
1693     case CONSTR_STATIC:
1694     case CONSTR_NOCAF_STATIC:
1695     case THUNK_STATIC:
1696     case FUN_STATIC:
1697     case IND_STATIC:
1698       /* Shouldn't see a static object here. */
1699       barf("scavenge: STATIC object\n");
1700
1701     case RET_BCO:
1702     case RET_SMALL:
1703     case RET_VEC_SMALL:
1704     case RET_BIG:
1705     case RET_VEC_BIG:
1706     case RET_DYN:
1707     case UPDATE_FRAME:
1708     case STOP_FRAME:
1709     case CATCH_FRAME:
1710     case SEQ_FRAME:
1711       /* Shouldn't see stack frames here. */
1712       barf("scavenge: stack frame\n");
1713
1714     case AP_UPD: /* same as PAPs */
1715     case PAP:
1716       /* Treat a PAP just like a section of stack, not forgetting to
1717        * evacuate the function pointer too...
1718        */
1719       { 
1720         StgPAP* pap = stgCast(StgPAP*,p);
1721
1722         pap->fun = evacuate(pap->fun);
1723         scavenge_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
1724         p += pap_sizeW(pap);
1725         break;
1726       }
1727       
1728     case ARR_WORDS:
1729       /* nothing to follow */
1730       p += arr_words_sizeW(stgCast(StgArrWords*,p));
1731       break;
1732
1733     case MUT_ARR_PTRS:
1734       /* follow everything */
1735       {
1736         StgPtr next;
1737
1738         evac_gen = 0;           /* repeatedly mutable */
1739         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
1740         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
1741           (StgClosure *)*p = evacuate((StgClosure *)*p);
1742         }
1743         evac_gen = saved_evac_gen;
1744         break;
1745       }
1746
1747     case MUT_ARR_PTRS_FROZEN:
1748       /* follow everything */
1749       {
1750         StgPtr start = p, next;
1751
1752         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
1753         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
1754           (StgClosure *)*p = evacuate((StgClosure *)*p);
1755         }
1756         if (failed_to_evac) {
1757           /* we can do this easier... */
1758           recordMutable((StgMutClosure *)start);
1759           failed_to_evac = rtsFalse;
1760         }
1761         break;
1762       }
1763
1764     case TSO:
1765       { 
1766         StgTSO *tso;
1767         
1768         tso = (StgTSO *)p;
1769         evac_gen = 0;
1770         /* chase the link field for any TSOs on the same queue */
1771         (StgClosure *)tso->link = evacuate((StgClosure *)tso->link);
1772         /* scavenge this thread's stack */
1773         scavenge_stack(tso->sp, &(tso->stack[tso->stack_size]));
1774         evac_gen = saved_evac_gen;
1775         p += tso_sizeW(tso);
1776         break;
1777       }
1778
1779     case BLOCKED_FETCH:
1780     case FETCH_ME:
1781     case EVACUATED:
1782       barf("scavenge: unimplemented/strange closure type\n");
1783
1784     default:
1785       barf("scavenge");
1786     }
1787
1788     /* If we didn't manage to promote all the objects pointed to by
1789      * the current object, then we have to designate this object as
1790      * mutable (because it contains old-to-new generation pointers).
1791      */
1792     if (failed_to_evac) {
1793       mkMutCons((StgClosure *)q, &generations[evac_gen]);
1794       failed_to_evac = rtsFalse;
1795     }
1796   }
1797
1798   step->scan_bd = bd;
1799   step->scan = p;
1800 }    
1801
1802 /* -----------------------------------------------------------------------------
1803    Scavenge one object.
1804
1805    This is used for objects that are temporarily marked as mutable
1806    because they contain old-to-new generation pointers.  Only certain
1807    objects can have this property.
1808    -------------------------------------------------------------------------- */
1809 static rtsBool
1810 scavenge_one(StgClosure *p)
1811 {
1812   StgInfoTable *info;
1813   rtsBool no_luck;
1814
1815   ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
1816                || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
1817
1818   info = get_itbl(p);
1819
1820   switch (info -> type) {
1821
1822   case FUN:
1823   case FUN_1_0:                 /* hardly worth specialising these guys */
1824   case FUN_0_1:
1825   case FUN_1_1:
1826   case FUN_0_2:
1827   case FUN_2_0:
1828   case THUNK:
1829   case THUNK_1_0:
1830   case THUNK_0_1:
1831   case THUNK_1_1:
1832   case THUNK_0_2:
1833   case THUNK_2_0:
1834   case CONSTR:
1835   case CONSTR_1_0:
1836   case CONSTR_0_1:
1837   case CONSTR_1_1:
1838   case CONSTR_0_2:
1839   case CONSTR_2_0:
1840   case WEAK:
1841   case FOREIGN:
1842   case IND_PERM:
1843   case IND_OLDGEN_PERM:
1844   case CAF_UNENTERED:
1845   case CAF_ENTERED:
1846     {
1847       StgPtr q, end;
1848       
1849       end = (P_)p->payload + info->layout.payload.ptrs;
1850       for (q = (P_)p->payload; q < end; q++) {
1851         (StgClosure *)*q = evacuate((StgClosure *)*q);
1852       }
1853       break;
1854     }
1855
1856   case CAF_BLACKHOLE:
1857   case BLACKHOLE:
1858       break;
1859
1860   case THUNK_SELECTOR:
1861     { 
1862       StgSelector *s = (StgSelector *)p;
1863       s->selectee = evacuate(s->selectee);
1864       break;
1865     }
1866     
1867   case AP_UPD: /* same as PAPs */
1868   case PAP:
1869     /* Treat a PAP just like a section of stack, not forgetting to
1870      * evacuate the function pointer too...
1871      */
1872     { 
1873       StgPAP* pap = (StgPAP *)p;
1874       
1875       pap->fun = evacuate(pap->fun);
1876       scavenge_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
1877       break;
1878     }
1879
1880   case IND_OLDGEN:
1881     /* This might happen if for instance a MUT_CONS was pointing to a
1882      * THUNK which has since been updated.  The IND_OLDGEN will
1883      * be on the mutable list anyway, so we don't need to do anything
1884      * here.
1885      */
1886     break;
1887
1888   default:
1889     barf("scavenge_one: strange object");
1890   }    
1891
1892   no_luck = failed_to_evac;
1893   failed_to_evac = rtsFalse;
1894   return (no_luck);
1895 }
1896
1897
1898 /* -----------------------------------------------------------------------------
1899    Scavenging mutable lists.
1900
1901    We treat the mutable list of each generation > N (i.e. all the
1902    generations older than the one being collected) as roots.  We also
1903    remove non-mutable objects from the mutable list at this point.
1904    -------------------------------------------------------------------------- */
1905
1906 static void
1907 scavenge_mut_once_list(generation *gen)
1908 {
1909   StgInfoTable *info;
1910   StgMutClosure *p, *next, *new_list;
1911
1912   p = gen->mut_once_list;
1913   new_list = END_MUT_LIST;
1914   next = p->mut_link;
1915
1916   evac_gen = gen->no;
1917   failed_to_evac = rtsFalse;
1918
1919   for (; p != END_MUT_LIST; p = next, next = p->mut_link) {
1920
1921     /* make sure the info pointer is into text space */
1922     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
1923                  || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
1924     
1925     info = get_itbl(p);
1926     switch(info->type) {
1927       
1928     case IND_OLDGEN:
1929     case IND_OLDGEN_PERM:
1930     case IND_STATIC:
1931       /* Try to pull the indirectee into this generation, so we can
1932        * remove the indirection from the mutable list.  
1933        */
1934       ((StgIndOldGen *)p)->indirectee = 
1935         evacuate(((StgIndOldGen *)p)->indirectee);
1936       
1937 #if 0
1938       /* Debugging code to print out the size of the thing we just
1939        * promoted 
1940        */
1941       { 
1942         StgPtr start = gen->steps[0].scan;
1943         bdescr *start_bd = gen->steps[0].scan_bd;
1944         nat size = 0;
1945         scavenge(&gen->steps[0]);
1946         if (start_bd != gen->steps[0].scan_bd) {
1947           size += (P_)BLOCK_ROUND_UP(start) - start;
1948           start_bd = start_bd->link;
1949           while (start_bd != gen->steps[0].scan_bd) {
1950             size += BLOCK_SIZE_W;
1951             start_bd = start_bd->link;
1952           }
1953           size += gen->steps[0].scan -
1954             (P_)BLOCK_ROUND_DOWN(gen->steps[0].scan);
1955         } else {
1956           size = gen->steps[0].scan - start;
1957         }
1958         fprintf(stderr,"evac IND_OLDGEN: %d bytes\n", size * sizeof(W_));
1959       }
1960 #endif
1961
1962       /* failed_to_evac might happen if we've got more than two
1963        * generations, we're collecting only generation 0, the
1964        * indirection resides in generation 2 and the indirectee is
1965        * in generation 1.
1966        */
1967       if (failed_to_evac) {
1968         failed_to_evac = rtsFalse;
1969         p->mut_link = new_list;
1970         new_list = p;
1971       } else {
1972         /* the mut_link field of an IND_STATIC is overloaded as the
1973          * static link field too (it just so happens that we don't need
1974          * both at the same time), so we need to NULL it out when
1975          * removing this object from the mutable list because the static
1976          * link fields are all assumed to be NULL before doing a major
1977          * collection. 
1978          */
1979         p->mut_link = NULL;
1980       }
1981       continue;
1982       
1983     case MUT_VAR:
1984       /* MUT_CONS is a kind of MUT_VAR, except it that we try to remove
1985        * it from the mutable list if possible by promoting whatever it
1986        * points to.
1987        */
1988       ASSERT(p->header.info == &MUT_CONS_info);
1989       if (scavenge_one(((StgMutVar *)p)->var) == rtsTrue) {
1990         /* didn't manage to promote everything, so put the
1991          * MUT_CONS back on the list.
1992          */
1993         p->mut_link = new_list;
1994         new_list = p;
1995       } 
1996       continue;
1997       
1998     default:
1999       /* shouldn't have anything else on the mutables list */
2000       barf("scavenge_mut_once_list: strange object?");
2001     }
2002   }
2003
2004   gen->mut_once_list = new_list;
2005 }
2006
2007
2008 static void
2009 scavenge_mutable_list(generation *gen)
2010 {
2011   StgInfoTable *info;
2012   StgMutClosure *p, *next;
2013
2014   p = gen->saved_mut_list;
2015   next = p->mut_link;
2016
2017   evac_gen = 0;
2018   failed_to_evac = rtsFalse;
2019
2020   for (; p != END_MUT_LIST; p = next, next = p->mut_link) {
2021
2022     /* make sure the info pointer is into text space */
2023     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
2024                  || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
2025     
2026     info = get_itbl(p);
2027     switch(info->type) {
2028       
2029     case MUT_ARR_PTRS_FROZEN:
2030       /* remove this guy from the mutable list, but follow the ptrs
2031        * anyway (and make sure they get promoted to this gen).
2032        */
2033       {
2034         StgPtr end, q;
2035         
2036         end = (P_)p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2037         evac_gen = gen->no;
2038         for (q = (P_)((StgMutArrPtrs *)p)->payload; q < end; q++) {
2039           (StgClosure *)*q = evacuate((StgClosure *)*q);
2040         }
2041         evac_gen = 0;
2042
2043         if (failed_to_evac) {
2044           failed_to_evac = rtsFalse;
2045           p->mut_link = gen->mut_list;
2046           gen->mut_list = p;
2047         } 
2048         continue;
2049       }
2050
2051     case MUT_ARR_PTRS:
2052       /* follow everything */
2053       p->mut_link = gen->mut_list;
2054       gen->mut_list = p;
2055       {
2056         StgPtr end, q;
2057         
2058         end = (P_)p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2059         for (q = (P_)((StgMutArrPtrs *)p)->payload; q < end; q++) {
2060           (StgClosure *)*q = evacuate((StgClosure *)*q);
2061         }
2062         continue;
2063       }
2064       
2065     case MUT_VAR:
2066       /* MUT_CONS is a kind of MUT_VAR, except that we try to remove
2067        * it from the mutable list if possible by promoting whatever it
2068        * points to.
2069        */
2070       ASSERT(p->header.info != &MUT_CONS_info);
2071       ((StgMutVar *)p)->var = evacuate(((StgMutVar *)p)->var);
2072       p->mut_link = gen->mut_list;
2073       gen->mut_list = p;
2074       continue;
2075       
2076     case MVAR:
2077       {
2078         StgMVar *mvar = (StgMVar *)p;
2079         (StgClosure *)mvar->head = evacuate((StgClosure *)mvar->head);
2080         (StgClosure *)mvar->tail = evacuate((StgClosure *)mvar->tail);
2081         (StgClosure *)mvar->value = evacuate((StgClosure *)mvar->value);
2082         p->mut_link = gen->mut_list;
2083         gen->mut_list = p;
2084         continue;
2085       }
2086
2087     case TSO:
2088       /* follow ptrs and remove this from the mutable list */
2089       { 
2090         StgTSO *tso = (StgTSO *)p;
2091
2092         /* Don't bother scavenging if this thread is dead 
2093          */
2094         if (!(tso->whatNext == ThreadComplete ||
2095               tso->whatNext == ThreadKilled)) {
2096           /* Don't need to chase the link field for any TSOs on the
2097            * same queue. Just scavenge this thread's stack 
2098            */
2099           scavenge_stack(tso->sp, &(tso->stack[tso->stack_size]));
2100         }
2101
2102         /* Don't take this TSO off the mutable list - it might still
2103          * point to some younger objects (because we set evac_gen to 0
2104          * above). 
2105          */
2106         tso->mut_link = gen->mut_list;
2107         gen->mut_list = (StgMutClosure *)tso;
2108         continue;
2109       }
2110       
2111     case BLACKHOLE_BQ:
2112       { 
2113         StgBlockingQueue *bh = (StgBlockingQueue *)p;
2114         (StgClosure *)bh->blocking_queue = 
2115           evacuate((StgClosure *)bh->blocking_queue);
2116         p->mut_link = gen->mut_list;
2117         gen->mut_list = p;
2118         continue;
2119       }
2120
2121     default:
2122       /* shouldn't have anything else on the mutables list */
2123       barf("scavenge_mut_list: strange object?");
2124     }
2125   }
2126 }
2127
2128 static void
2129 scavenge_static(void)
2130 {
2131   StgClosure* p = static_objects;
2132   const StgInfoTable *info;
2133
2134   /* Always evacuate straight to the oldest generation for static
2135    * objects */
2136   evac_gen = oldest_gen->no;
2137
2138   /* keep going until we've scavenged all the objects on the linked
2139      list... */
2140   while (p != END_OF_STATIC_LIST) {
2141
2142     info = get_itbl(p);
2143
2144     /* make sure the info pointer is into text space */
2145     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
2146                  || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
2147     
2148     /* Take this object *off* the static_objects list,
2149      * and put it on the scavenged_static_objects list.
2150      */
2151     static_objects = STATIC_LINK(info,p);
2152     STATIC_LINK(info,p) = scavenged_static_objects;
2153     scavenged_static_objects = p;
2154     
2155     switch (info -> type) {
2156       
2157     case IND_STATIC:
2158       {
2159         StgInd *ind = (StgInd *)p;
2160         ind->indirectee = evacuate(ind->indirectee);
2161
2162         /* might fail to evacuate it, in which case we have to pop it
2163          * back on the mutable list (and take it off the
2164          * scavenged_static list because the static link and mut link
2165          * pointers are one and the same).
2166          */
2167         if (failed_to_evac) {
2168           failed_to_evac = rtsFalse;
2169           scavenged_static_objects = STATIC_LINK(info,p);
2170           ((StgMutClosure *)ind)->mut_link = oldest_gen->mut_once_list;
2171           oldest_gen->mut_once_list = (StgMutClosure *)ind;
2172         }
2173         break;
2174       }
2175       
2176     case THUNK_STATIC:
2177     case FUN_STATIC:
2178       scavenge_srt(info);
2179       /* fall through */
2180       
2181     case CONSTR_STATIC:
2182       { 
2183         StgPtr q, next;
2184         
2185         next = (P_)p->payload + info->layout.payload.ptrs;
2186         /* evacuate the pointers */
2187         for (q = (P_)p->payload; q < next; q++) {
2188           (StgClosure *)*q = evacuate((StgClosure *)*q);
2189         }
2190         break;
2191       }
2192       
2193     default:
2194       barf("scavenge_static");
2195     }
2196
2197     ASSERT(failed_to_evac == rtsFalse);
2198
2199     /* get the next static object from the list.  Remeber, there might
2200      * be more stuff on this list now that we've done some evacuating!
2201      * (static_objects is a global)
2202      */
2203     p = static_objects;
2204   }
2205 }
2206
2207 /* -----------------------------------------------------------------------------
2208    scavenge_stack walks over a section of stack and evacuates all the
2209    objects pointed to by it.  We can use the same code for walking
2210    PAPs, since these are just sections of copied stack.
2211    -------------------------------------------------------------------------- */
2212
2213 static void
2214 scavenge_stack(StgPtr p, StgPtr stack_end)
2215 {
2216   StgPtr q;
2217   const StgInfoTable* info;
2218   StgNat32 bitmap;
2219
2220   /* 
2221    * Each time around this loop, we are looking at a chunk of stack
2222    * that starts with either a pending argument section or an 
2223    * activation record. 
2224    */
2225
2226   while (p < stack_end) {
2227     q = *stgCast(StgPtr*,p);
2228
2229     /* If we've got a tag, skip over that many words on the stack */
2230     if (IS_ARG_TAG(stgCast(StgWord,q))) {
2231       p += ARG_SIZE(q);
2232       p++; continue;
2233     }
2234      
2235     /* Is q a pointer to a closure?
2236      */
2237     if (! LOOKS_LIKE_GHC_INFO(q)) {
2238
2239 #ifdef DEBUG
2240       if (LOOKS_LIKE_STATIC(q)) { /* Is it a static closure? */
2241         ASSERT(closure_STATIC(stgCast(StgClosure*,q)));
2242       } 
2243       /* otherwise, must be a pointer into the allocation space.
2244        */
2245 #endif
2246
2247       (StgClosure *)*p = evacuate((StgClosure *)q);
2248       p++; 
2249       continue;
2250     }
2251       
2252     /* 
2253      * Otherwise, q must be the info pointer of an activation
2254      * record.  All activation records have 'bitmap' style layout
2255      * info.
2256      */
2257     info  = get_itbl(stgCast(StgClosure*,p));
2258       
2259     switch (info->type) {
2260         
2261       /* Dynamic bitmap: the mask is stored on the stack */
2262     case RET_DYN:
2263       bitmap = stgCast(StgRetDyn*,p)->liveness;
2264       p      = &payloadWord(stgCast(StgRetDyn*,p),0);
2265       goto small_bitmap;
2266
2267       /* probably a slow-entry point return address: */
2268     case FUN:
2269     case FUN_STATIC:
2270       p++;
2271       goto follow_srt;
2272
2273       /* Specialised code for update frames, since they're so common.
2274        * We *know* the updatee points to a BLACKHOLE, CAF_BLACKHOLE,
2275        * or BLACKHOLE_BQ, so just inline the code to evacuate it here.  
2276        */
2277     case UPDATE_FRAME:
2278       {
2279         StgUpdateFrame *frame = (StgUpdateFrame *)p;
2280         StgClosure *to;
2281         StgClosureType type = get_itbl(frame->updatee)->type;
2282
2283         p += sizeofW(StgUpdateFrame);
2284         if (type == EVACUATED) {
2285           frame->updatee = evacuate(frame->updatee);
2286           continue;
2287         } else {
2288           bdescr *bd = Bdescr((P_)frame->updatee);
2289           step *step;
2290           if (bd->gen->no > N) { 
2291             if (bd->gen->no < evac_gen) {
2292               failed_to_evac = rtsTrue;
2293             }
2294             continue;
2295           }
2296
2297           /* Don't promote blackholes */
2298           step = bd->step;
2299           if (!(step->gen->no == 0 && 
2300                 step->no != 0 &&
2301                 step->no == step->gen->n_steps-1)) {
2302             step = step->to;
2303           }
2304
2305           switch (type) {
2306           case BLACKHOLE:
2307           case CAF_BLACKHOLE:
2308             to = copyPart(frame->updatee, BLACKHOLE_sizeW(), 
2309                           sizeofW(StgHeader), step);
2310             frame->updatee = to;
2311             continue;
2312           case BLACKHOLE_BQ:
2313             to = copy(frame->updatee, BLACKHOLE_sizeW(), step);
2314             frame->updatee = to;
2315             recordMutable((StgMutClosure *)to);
2316             continue;
2317           default:
2318             barf("scavenge_stack: UPDATE_FRAME updatee");
2319           }
2320         }
2321       }
2322
2323       /* small bitmap (< 32 entries, or 64 on a 64-bit machine) */
2324     case RET_BCO:
2325     case RET_SMALL:
2326     case RET_VEC_SMALL:
2327     case STOP_FRAME:
2328     case CATCH_FRAME:
2329     case SEQ_FRAME:
2330       bitmap = info->layout.bitmap;
2331       p++;
2332     small_bitmap:
2333       while (bitmap != 0) {
2334         if ((bitmap & 1) == 0) {
2335           (StgClosure *)*p = evacuate((StgClosure *)*p);
2336         }
2337         p++;
2338         bitmap = bitmap >> 1;
2339       }
2340       
2341     follow_srt:
2342       scavenge_srt(info);
2343       continue;
2344
2345       /* large bitmap (> 32 entries) */
2346     case RET_BIG:
2347     case RET_VEC_BIG:
2348       {
2349         StgPtr q;
2350         StgLargeBitmap *large_bitmap;
2351         nat i;
2352
2353         large_bitmap = info->layout.large_bitmap;
2354         p++;
2355
2356         for (i=0; i<large_bitmap->size; i++) {
2357           bitmap = large_bitmap->bitmap[i];
2358           q = p + sizeof(W_) * 8;
2359           while (bitmap != 0) {
2360             if ((bitmap & 1) == 0) {
2361               (StgClosure *)*p = evacuate((StgClosure *)*p);
2362             }
2363             p++;
2364             bitmap = bitmap >> 1;
2365           }
2366           if (i+1 < large_bitmap->size) {
2367             while (p < q) {
2368               (StgClosure *)*p = evacuate((StgClosure *)*p);
2369               p++;
2370             }
2371           }
2372         }
2373
2374         /* and don't forget to follow the SRT */
2375         goto follow_srt;
2376       }
2377
2378     default:
2379       barf("scavenge_stack: weird activation record found on stack.\n");
2380     }
2381   }
2382 }
2383
2384 /*-----------------------------------------------------------------------------
2385   scavenge the large object list.
2386
2387   evac_gen set by caller; similar games played with evac_gen as with
2388   scavenge() - see comment at the top of scavenge().  Most large
2389   objects are (repeatedly) mutable, so most of the time evac_gen will
2390   be zero.
2391   --------------------------------------------------------------------------- */
2392
2393 static void
2394 scavenge_large(step *step)
2395 {
2396   bdescr *bd;
2397   StgPtr p;
2398   const StgInfoTable* info;
2399   nat saved_evac_gen = evac_gen; /* used for temporarily changing evac_gen */
2400
2401   evac_gen = 0;                 /* most objects are mutable */
2402   bd = step->new_large_objects;
2403
2404   for (; bd != NULL; bd = step->new_large_objects) {
2405
2406     /* take this object *off* the large objects list and put it on
2407      * the scavenged large objects list.  This is so that we can
2408      * treat new_large_objects as a stack and push new objects on
2409      * the front when evacuating.
2410      */
2411     step->new_large_objects = bd->link;
2412     dbl_link_onto(bd, &step->scavenged_large_objects);
2413
2414     p = bd->start;
2415     info  = get_itbl(stgCast(StgClosure*,p));
2416
2417     switch (info->type) {
2418
2419     /* only certain objects can be "large"... */
2420
2421     case ARR_WORDS:
2422       /* nothing to follow */
2423       continue;
2424
2425     case MUT_ARR_PTRS:
2426       /* follow everything */
2427       {
2428         StgPtr next;
2429
2430         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2431         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2432           (StgClosure *)*p = evacuate((StgClosure *)*p);
2433         }
2434         continue;
2435       }
2436
2437     case MUT_ARR_PTRS_FROZEN:
2438       /* follow everything */
2439       {
2440         StgPtr start = p, next;
2441
2442         evac_gen = saved_evac_gen; /* not really mutable */
2443         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2444         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2445           (StgClosure *)*p = evacuate((StgClosure *)*p);
2446         }
2447         evac_gen = 0;
2448         if (failed_to_evac) {
2449           recordMutable((StgMutClosure *)start);
2450         }
2451         continue;
2452       }
2453
2454     case BCO:
2455       {
2456         StgBCO* bco = stgCast(StgBCO*,p);
2457         nat i;
2458         evac_gen = saved_evac_gen;
2459         for (i = 0; i < bco->n_ptrs; i++) {
2460           bcoConstCPtr(bco,i) = evacuate(bcoConstCPtr(bco,i));
2461         }
2462         evac_gen = 0;
2463         continue;
2464       }
2465
2466     case TSO:
2467       { 
2468         StgTSO *tso;
2469         
2470         tso = (StgTSO *)p;
2471         /* chase the link field for any TSOs on the same queue */
2472         (StgClosure *)tso->link = evacuate((StgClosure *)tso->link);
2473         /* scavenge this thread's stack */
2474         scavenge_stack(tso->sp, &(tso->stack[tso->stack_size]));
2475         continue;
2476       }
2477
2478     default:
2479       barf("scavenge_large: unknown/strange object");
2480     }
2481   }
2482 }
2483
2484 static void
2485 zero_static_object_list(StgClosure* first_static)
2486 {
2487   StgClosure* p;
2488   StgClosure* link;
2489   const StgInfoTable *info;
2490
2491   for (p = first_static; p != END_OF_STATIC_LIST; p = link) {
2492     info = get_itbl(p);
2493     link = STATIC_LINK(info, p);
2494     STATIC_LINK(info,p) = NULL;
2495   }
2496 }
2497
2498 /* This function is only needed because we share the mutable link
2499  * field with the static link field in an IND_STATIC, so we have to
2500  * zero the mut_link field before doing a major GC, which needs the
2501  * static link field.  
2502  *
2503  * It doesn't do any harm to zero all the mutable link fields on the
2504  * mutable list.
2505  */
2506 static void
2507 zero_mutable_list( StgMutClosure *first )
2508 {
2509   StgMutClosure *next, *c;
2510
2511   for (c = first; c != END_MUT_LIST; c = next) {
2512     next = c->mut_link;
2513     c->mut_link = NULL;
2514   }
2515 }
2516
2517 /* -----------------------------------------------------------------------------
2518    Reverting CAFs
2519    -------------------------------------------------------------------------- */
2520
2521 void RevertCAFs(void)
2522 {
2523   while (enteredCAFs != END_CAF_LIST) {
2524     StgCAF* caf = enteredCAFs;
2525     
2526     enteredCAFs = caf->link;
2527     ASSERT(get_itbl(caf)->type == CAF_ENTERED);
2528     SET_INFO(caf,&CAF_UNENTERED_info);
2529     caf->value = stgCast(StgClosure*,0xdeadbeef);
2530     caf->link  = stgCast(StgCAF*,0xdeadbeef);
2531   }
2532 }
2533
2534 void revert_dead_CAFs(void)
2535 {
2536     StgCAF* caf = enteredCAFs;
2537     enteredCAFs = END_CAF_LIST;
2538     while (caf != END_CAF_LIST) {
2539         StgCAF* next = caf->link;
2540
2541         switch(GET_INFO(caf)->type) {
2542         case EVACUATED:
2543             {
2544                 /* This object has been evacuated, it must be live. */
2545                 StgCAF* new = stgCast(StgCAF*,stgCast(StgEvacuated*,caf)->evacuee);
2546                 new->link = enteredCAFs;
2547                 enteredCAFs = new;
2548                 break;
2549             }
2550         case CAF_ENTERED:
2551             {
2552                 SET_INFO(caf,&CAF_UNENTERED_info);
2553                 caf->value = stgCast(StgClosure*,0xdeadbeef);
2554                 caf->link  = stgCast(StgCAF*,0xdeadbeef);
2555                 break;
2556             }
2557         default:
2558                 barf("revert_dead_CAFs: enteredCAFs list corrupted");
2559         } 
2560         caf = next;
2561     }
2562 }
2563
2564 /* -----------------------------------------------------------------------------
2565    Sanity code for CAF garbage collection.
2566
2567    With DEBUG turned on, we manage a CAF list in addition to the SRT
2568    mechanism.  After GC, we run down the CAF list and blackhole any
2569    CAFs which have been garbage collected.  This means we get an error
2570    whenever the program tries to enter a garbage collected CAF.
2571
2572    Any garbage collected CAFs are taken off the CAF list at the same
2573    time. 
2574    -------------------------------------------------------------------------- */
2575
2576 #ifdef DEBUG
2577 static void
2578 gcCAFs(void)
2579 {
2580   StgClosure*  p;
2581   StgClosure** pp;
2582   const StgInfoTable *info;
2583   nat i;
2584
2585   i = 0;
2586   p = caf_list;
2587   pp = &caf_list;
2588
2589   while (p != NULL) {
2590     
2591     info = get_itbl(p);
2592
2593     ASSERT(info->type == IND_STATIC);
2594
2595     if (STATIC_LINK(info,p) == NULL) {
2596       IF_DEBUG(gccafs, fprintf(stderr, "CAF gc'd at 0x%04x\n", (int)p));
2597       /* black hole it */
2598       SET_INFO(p,&BLACKHOLE_info);
2599       p = STATIC_LINK2(info,p);
2600       *pp = p;
2601     }
2602     else {
2603       pp = &STATIC_LINK2(info,p);
2604       p = *pp;
2605       i++;
2606     }
2607
2608   }
2609
2610   /*  fprintf(stderr, "%d CAFs live\n", i); */
2611 }
2612 #endif
2613
2614 /* -----------------------------------------------------------------------------
2615    Lazy black holing.
2616
2617    Whenever a thread returns to the scheduler after possibly doing
2618    some work, we have to run down the stack and black-hole all the
2619    closures referred to by update frames.
2620    -------------------------------------------------------------------------- */
2621
2622 static void
2623 threadLazyBlackHole(StgTSO *tso)
2624 {
2625   StgUpdateFrame *update_frame;
2626   StgBlockingQueue *bh;
2627   StgPtr stack_end;
2628
2629   stack_end = &tso->stack[tso->stack_size];
2630   update_frame = tso->su;
2631
2632   while (1) {
2633     switch (get_itbl(update_frame)->type) {
2634
2635     case CATCH_FRAME:
2636       update_frame = stgCast(StgCatchFrame*,update_frame)->link;
2637       break;
2638
2639     case UPDATE_FRAME:
2640       bh = (StgBlockingQueue *)update_frame->updatee;
2641
2642       /* if the thunk is already blackholed, it means we've also
2643        * already blackholed the rest of the thunks on this stack,
2644        * so we can stop early.
2645        *
2646        * The blackhole made for a CAF is a CAF_BLACKHOLE, so they
2647        * don't interfere with this optimisation.
2648        */
2649       if (bh->header.info == &BLACKHOLE_info) {
2650         return;
2651       }
2652
2653       if (bh->header.info != &BLACKHOLE_BQ_info &&
2654           bh->header.info != &CAF_BLACKHOLE_info) {
2655         SET_INFO(bh,&BLACKHOLE_info);
2656       }
2657
2658       update_frame = update_frame->link;
2659       break;
2660
2661     case SEQ_FRAME:
2662       update_frame = stgCast(StgSeqFrame*,update_frame)->link;
2663       break;
2664
2665     case STOP_FRAME:
2666       return;
2667     default:
2668       barf("threadPaused");
2669     }
2670   }
2671 }
2672
2673 /* -----------------------------------------------------------------------------
2674  * Stack squeezing
2675  *
2676  * Code largely pinched from old RTS, then hacked to bits.  We also do
2677  * lazy black holing here.
2678  *
2679  * -------------------------------------------------------------------------- */
2680
2681 static void
2682 threadSqueezeStack(StgTSO *tso)
2683 {
2684   lnat displacement = 0;
2685   StgUpdateFrame *frame;
2686   StgUpdateFrame *next_frame;                   /* Temporally next */
2687   StgUpdateFrame *prev_frame;                   /* Temporally previous */
2688   StgPtr bottom;
2689   rtsBool prev_was_update_frame;
2690   
2691   bottom = &(tso->stack[tso->stack_size]);
2692   frame  = tso->su;
2693
2694   /* There must be at least one frame, namely the STOP_FRAME.
2695    */
2696   ASSERT((P_)frame < bottom);
2697
2698   /* Walk down the stack, reversing the links between frames so that
2699    * we can walk back up as we squeeze from the bottom.  Note that
2700    * next_frame and prev_frame refer to next and previous as they were
2701    * added to the stack, rather than the way we see them in this
2702    * walk. (It makes the next loop less confusing.)  
2703    *
2704    * Stop if we find an update frame pointing to a black hole 
2705    * (see comment in threadLazyBlackHole()).
2706    */
2707   
2708   next_frame = NULL;
2709   while ((P_)frame < bottom - 1) {  /* bottom - 1 is the STOP_FRAME */
2710     prev_frame = frame->link;
2711     frame->link = next_frame;
2712     next_frame = frame;
2713     frame = prev_frame;
2714     if (get_itbl(frame)->type == UPDATE_FRAME
2715         && frame->updatee->header.info == &BLACKHOLE_info) {
2716         break;
2717     }
2718   }
2719
2720   /* Now, we're at the bottom.  Frame points to the lowest update
2721    * frame on the stack, and its link actually points to the frame
2722    * above. We have to walk back up the stack, squeezing out empty
2723    * update frames and turning the pointers back around on the way
2724    * back up.
2725    *
2726    * The bottom-most frame (the STOP_FRAME) has not been altered, and
2727    * we never want to eliminate it anyway.  Just walk one step up
2728    * before starting to squeeze. When you get to the topmost frame,
2729    * remember that there are still some words above it that might have
2730    * to be moved.  
2731    */
2732   
2733   prev_frame = frame;
2734   frame = next_frame;
2735
2736   prev_was_update_frame = (get_itbl(prev_frame)->type == UPDATE_FRAME);
2737
2738   /*
2739    * Loop through all of the frames (everything except the very
2740    * bottom).  Things are complicated by the fact that we have 
2741    * CATCH_FRAMEs and SEQ_FRAMEs interspersed with the update frames.
2742    * We can only squeeze when there are two consecutive UPDATE_FRAMEs.
2743    */
2744   while (frame != NULL) {
2745     StgPtr sp;
2746     StgPtr frame_bottom = (P_)frame + sizeofW(StgUpdateFrame);
2747     rtsBool is_update_frame;
2748     
2749     next_frame = frame->link;
2750     is_update_frame = (get_itbl(frame)->type == UPDATE_FRAME);
2751
2752     /* Check to see if 
2753      *   1. both the previous and current frame are update frames
2754      *   2. the current frame is empty
2755      */
2756     if (prev_was_update_frame && is_update_frame &&
2757         (P_)prev_frame == frame_bottom + displacement) {
2758       
2759       /* Now squeeze out the current frame */
2760       StgClosure *updatee_keep   = prev_frame->updatee;
2761       StgClosure *updatee_bypass = frame->updatee;
2762       
2763 #if 0 /* DEBUG */
2764       fprintf(stderr, "squeezing frame at %p\n", frame);
2765 #endif
2766
2767       /* Deal with blocking queues.  If both updatees have blocked
2768        * threads, then we should merge the queues into the update
2769        * frame that we're keeping.
2770        *
2771        * Alternatively, we could just wake them up: they'll just go
2772        * straight to sleep on the proper blackhole!  This is less code
2773        * and probably less bug prone, although it's probably much
2774        * slower --SDM
2775        */
2776 #if 0 /* do it properly... */
2777       if (GET_INFO(updatee_bypass) == BLACKHOLE_BQ_info) {
2778         /* Sigh.  It has one.  Don't lose those threads! */
2779           if (GET_INFO(updatee_keep) == BLACKHOLE_BQ_info) {
2780           /* Urgh.  Two queues.  Merge them. */
2781           P_ keep_tso = ((StgBlockingQueue *)updatee_keep)->blocking_queue;
2782           
2783           while (keep_tso->link != END_TSO_QUEUE) {
2784             keep_tso = keep_tso->link;
2785           }
2786           keep_tso->link = ((StgBlockingQueue *)updatee_bypass)->blocking_queue;
2787
2788         } else {
2789           /* For simplicity, just swap the BQ for the BH */
2790           P_ temp = updatee_keep;
2791           
2792           updatee_keep = updatee_bypass;
2793           updatee_bypass = temp;
2794           
2795           /* Record the swap in the kept frame (below) */
2796           prev_frame->updatee = updatee_keep;
2797         }
2798       }
2799 #endif
2800
2801       TICK_UPD_SQUEEZED();
2802       UPD_IND(updatee_bypass, updatee_keep); /* this wakes the threads up */
2803       
2804       sp = (P_)frame - 1;       /* sp = stuff to slide */
2805       displacement += sizeofW(StgUpdateFrame);
2806       
2807     } else {
2808       /* No squeeze for this frame */
2809       sp = frame_bottom - 1;    /* Keep the current frame */
2810       
2811       /* Do lazy black-holing.
2812        */
2813       if (is_update_frame) {
2814         StgBlockingQueue *bh = (StgBlockingQueue *)frame->updatee;
2815         if (bh->header.info != &BLACKHOLE_BQ_info &&
2816             bh->header.info != &CAF_BLACKHOLE_info) {
2817           SET_INFO(bh,&BLACKHOLE_info);
2818         }
2819       }
2820
2821       /* Fix the link in the current frame (should point to the frame below) */
2822       frame->link = prev_frame;
2823       prev_was_update_frame = is_update_frame;
2824     }
2825     
2826     /* Now slide all words from sp up to the next frame */
2827     
2828     if (displacement > 0) {
2829       P_ next_frame_bottom;
2830
2831       if (next_frame != NULL)
2832         next_frame_bottom = (P_)next_frame + sizeofW(StgUpdateFrame);
2833       else
2834         next_frame_bottom = tso->sp - 1;
2835       
2836 #if 0 /* DEBUG */
2837       fprintf(stderr, "sliding [%p, %p] by %ld\n", sp, next_frame_bottom,
2838               displacement);
2839 #endif
2840       
2841       while (sp >= next_frame_bottom) {
2842         sp[displacement] = *sp;
2843         sp -= 1;
2844       }
2845     }
2846     (P_)prev_frame = (P_)frame + displacement;
2847     frame = next_frame;
2848   }
2849
2850   tso->sp += displacement;
2851   tso->su = prev_frame;
2852 }
2853
2854 /* -----------------------------------------------------------------------------
2855  * Pausing a thread
2856  * 
2857  * We have to prepare for GC - this means doing lazy black holing
2858  * here.  We also take the opportunity to do stack squeezing if it's
2859  * turned on.
2860  * -------------------------------------------------------------------------- */
2861
2862 void
2863 threadPaused(StgTSO *tso)
2864 {
2865   if ( RtsFlags.GcFlags.squeezeUpdFrames == rtsTrue )
2866     threadSqueezeStack(tso);    /* does black holing too */
2867   else
2868     threadLazyBlackHole(tso);
2869 }