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