[project @ 2002-09-06 09:56:12 by simonmar]
[ghc-hetmet.git] / ghc / rts / GC.c
1 /* -----------------------------------------------------------------------------
2  * $Id: GC.c,v 1.140 2002/09/06 09:56:12 simonmar Exp $
3  *
4  * (c) The GHC Team 1998-1999
5  *
6  * Generational garbage collector
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "PosixSource.h"
11 #include "Rts.h"
12 #include "RtsFlags.h"
13 #include "RtsUtils.h"
14 #include "Storage.h"
15 #include "StoragePriv.h"
16 #include "Stats.h"
17 #include "Schedule.h"
18 #include "SchedAPI.h"           // for ReverCAFs prototype
19 #include "Sanity.h"
20 #include "BlockAlloc.h"
21 #include "MBlock.h"
22 #include "Main.h"
23 #include "ProfHeap.h"
24 #include "SchedAPI.h"
25 #include "Weak.h"
26 #include "StablePriv.h"
27 #include "Prelude.h"
28 #include "ParTicky.h"           // ToDo: move into Rts.h
29 #include "GCCompact.h"
30 #if defined(GRAN) || defined(PAR)
31 # include "GranSimRts.h"
32 # include "ParallelRts.h"
33 # include "FetchMe.h"
34 # if defined(DEBUG)
35 #  include "Printer.h"
36 #  include "ParallelDebug.h"
37 # endif
38 #endif
39 #include "HsFFI.h"
40 #include "Linker.h"
41 #if defined(RTS_GTK_FRONTPANEL)
42 #include "FrontPanel.h"
43 #endif
44
45 #include "RetainerProfile.h"
46 #include "LdvProfile.h"
47
48 #include <string.h>
49
50 /* STATIC OBJECT LIST.
51  *
52  * During GC:
53  * We maintain a linked list of static objects that are still live.
54  * The requirements for this list are:
55  *
56  *  - we need to scan the list while adding to it, in order to
57  *    scavenge all the static objects (in the same way that
58  *    breadth-first scavenging works for dynamic objects).
59  *
60  *  - we need to be able to tell whether an object is already on
61  *    the list, to break loops.
62  *
63  * Each static object has a "static link field", which we use for
64  * linking objects on to the list.  We use a stack-type list, consing
65  * objects on the front as they are added (this means that the
66  * scavenge phase is depth-first, not breadth-first, but that
67  * shouldn't matter).  
68  *
69  * A separate list is kept for objects that have been scavenged
70  * already - this is so that we can zero all the marks afterwards.
71  *
72  * An object is on the list if its static link field is non-zero; this
73  * means that we have to mark the end of the list with '1', not NULL.  
74  *
75  * Extra notes for generational GC:
76  *
77  * Each generation has a static object list associated with it.  When
78  * collecting generations up to N, we treat the static object lists
79  * from generations > N as roots.
80  *
81  * We build up a static object list while collecting generations 0..N,
82  * which is then appended to the static object list of generation N+1.
83  */
84 static StgClosure* static_objects;      // live static objects
85 StgClosure* scavenged_static_objects;   // static objects scavenged so far
86
87 /* N is the oldest generation being collected, where the generations
88  * are numbered starting at 0.  A major GC (indicated by the major_gc
89  * flag) is when we're collecting all generations.  We only attempt to
90  * deal with static objects and GC CAFs when doing a major GC.
91  */
92 static nat N;
93 static rtsBool major_gc;
94
95 /* Youngest generation that objects should be evacuated to in
96  * evacuate().  (Logically an argument to evacuate, but it's static
97  * a lot of the time so we optimise it into a global variable).
98  */
99 static nat evac_gen;
100
101 /* Weak pointers
102  */
103 StgWeak *old_weak_ptr_list; // also pending finaliser list
104
105 /* Which stage of processing various kinds of weak pointer are we at?
106  * (see traverse_weak_ptr_list() below for discussion).
107  */
108 typedef enum { WeakPtrs, WeakThreads, WeakDone } WeakStage;
109 static WeakStage weak_stage;
110
111 /* List of all threads during GC
112  */
113 static StgTSO *old_all_threads;
114 StgTSO *resurrected_threads;
115
116 /* Flag indicating failure to evacuate an object to the desired
117  * generation.
118  */
119 static rtsBool failed_to_evac;
120
121 /* Old to-space (used for two-space collector only)
122  */
123 static bdescr *old_to_blocks;
124
125 /* Data used for allocation area sizing.
126  */
127 static lnat new_blocks;          // blocks allocated during this GC 
128 static lnat g0s0_pcnt_kept = 30; // percentage of g0s0 live at last minor GC 
129
130 /* Used to avoid long recursion due to selector thunks
131  */
132 static lnat thunk_selector_depth = 0;
133 #define MAX_THUNK_SELECTOR_DEPTH 256
134
135 /* -----------------------------------------------------------------------------
136    Static function declarations
137    -------------------------------------------------------------------------- */
138
139 static void         mark_root               ( StgClosure **root );
140 static StgClosure * evacuate                ( StgClosure *q );
141 static void         zero_static_object_list ( StgClosure* first_static );
142 static void         zero_mutable_list       ( StgMutClosure *first );
143
144 static rtsBool      traverse_weak_ptr_list  ( void );
145 static void         mark_weak_ptr_list      ( StgWeak **list );
146
147 static StgClosure * eval_thunk_selector     ( nat field, StgSelector * p );
148
149 static void         scavenge                ( step * );
150 static void         scavenge_mark_stack     ( void );
151 static void         scavenge_stack          ( StgPtr p, StgPtr stack_end );
152 static rtsBool      scavenge_one            ( StgPtr p );
153 static void         scavenge_large          ( step * );
154 static void         scavenge_static         ( void );
155 static void         scavenge_mutable_list   ( generation *g );
156 static void         scavenge_mut_once_list  ( generation *g );
157
158 #if 0 && defined(DEBUG)
159 static void         gcCAFs                  ( void );
160 #endif
161
162 /* -----------------------------------------------------------------------------
163    inline functions etc. for dealing with the mark bitmap & stack.
164    -------------------------------------------------------------------------- */
165
166 #define MARK_STACK_BLOCKS 4
167
168 static bdescr *mark_stack_bdescr;
169 static StgPtr *mark_stack;
170 static StgPtr *mark_sp;
171 static StgPtr *mark_splim;
172
173 // Flag and pointers used for falling back to a linear scan when the
174 // mark stack overflows.
175 static rtsBool mark_stack_overflowed;
176 static bdescr *oldgen_scan_bd;
177 static StgPtr  oldgen_scan;
178
179 static inline rtsBool
180 mark_stack_empty(void)
181 {
182     return mark_sp == mark_stack;
183 }
184
185 static inline rtsBool
186 mark_stack_full(void)
187 {
188     return mark_sp >= mark_splim;
189 }
190
191 static inline void
192 reset_mark_stack(void)
193 {
194     mark_sp = mark_stack;
195 }
196
197 static inline void
198 push_mark_stack(StgPtr p)
199 {
200     *mark_sp++ = p;
201 }
202
203 static inline StgPtr
204 pop_mark_stack(void)
205 {
206     return *--mark_sp;
207 }
208
209 /* -----------------------------------------------------------------------------
210    GarbageCollect
211
212    For garbage collecting generation N (and all younger generations):
213
214      - follow all pointers in the root set.  the root set includes all 
215        mutable objects in all steps in all generations.
216
217      - for each pointer, evacuate the object it points to into either
218        + to-space in the next higher step in that generation, if one exists,
219        + if the object's generation == N, then evacuate it to the next
220          generation if one exists, or else to-space in the current
221          generation.
222        + if the object's generation < N, then evacuate it to to-space
223          in the next generation.
224
225      - repeatedly scavenge to-space from each step in each generation
226        being collected until no more objects can be evacuated.
227       
228      - free from-space in each step, and set from-space = to-space.
229
230    Locks held: sched_mutex
231
232    -------------------------------------------------------------------------- */
233
234 void
235 GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
236 {
237   bdescr *bd;
238   step *stp;
239   lnat live, allocated, collected = 0, copied = 0;
240   lnat oldgen_saved_blocks = 0;
241   nat g, s;
242
243 #ifdef PROFILING
244   CostCentreStack *prev_CCS;
245 #endif
246
247 #if defined(DEBUG) && defined(GRAN)
248   IF_DEBUG(gc, belch("@@ Starting garbage collection at %ld (%lx)\n", 
249                      Now, Now));
250 #endif
251
252   // tell the stats department that we've started a GC 
253   stat_startGC();
254
255   // Init stats and print par specific (timing) info 
256   PAR_TICKY_PAR_START();
257
258   // attribute any costs to CCS_GC 
259 #ifdef PROFILING
260   prev_CCS = CCCS;
261   CCCS = CCS_GC;
262 #endif
263
264   /* Approximate how much we allocated.  
265    * Todo: only when generating stats? 
266    */
267   allocated = calcAllocated();
268
269   /* Figure out which generation to collect
270    */
271   if (force_major_gc) {
272     N = RtsFlags.GcFlags.generations - 1;
273     major_gc = rtsTrue;
274   } else {
275     N = 0;
276     for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
277       if (generations[g].steps[0].n_blocks +
278           generations[g].steps[0].n_large_blocks
279           >= generations[g].max_blocks) {
280         N = g;
281       }
282     }
283     major_gc = (N == RtsFlags.GcFlags.generations-1);
284   }
285
286 #ifdef RTS_GTK_FRONTPANEL
287   if (RtsFlags.GcFlags.frontpanel) {
288       updateFrontPanelBeforeGC(N);
289   }
290 #endif
291
292   // check stack sanity *before* GC (ToDo: check all threads) 
293 #if defined(GRAN)
294   // ToDo!: check sanity  IF_DEBUG(sanity, checkTSOsSanity());
295 #endif
296   IF_DEBUG(sanity, checkFreeListSanity());
297
298   /* Initialise the static object lists
299    */
300   static_objects = END_OF_STATIC_LIST;
301   scavenged_static_objects = END_OF_STATIC_LIST;
302
303   /* zero the mutable list for the oldest generation (see comment by
304    * zero_mutable_list below).
305    */
306   if (major_gc) { 
307     zero_mutable_list(generations[RtsFlags.GcFlags.generations-1].mut_once_list);
308   }
309
310   /* Save the old to-space if we're doing a two-space collection
311    */
312   if (RtsFlags.GcFlags.generations == 1) {
313     old_to_blocks = g0s0->to_blocks;
314     g0s0->to_blocks = NULL;
315   }
316
317   /* Keep a count of how many new blocks we allocated during this GC
318    * (used for resizing the allocation area, later).
319    */
320   new_blocks = 0;
321
322   /* Initialise to-space in all the generations/steps that we're
323    * collecting.
324    */
325   for (g = 0; g <= N; g++) {
326     generations[g].mut_once_list = END_MUT_LIST;
327     generations[g].mut_list = END_MUT_LIST;
328
329     for (s = 0; s < generations[g].n_steps; s++) {
330
331       // generation 0, step 0 doesn't need to-space 
332       if (g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1) { 
333         continue; 
334       }
335
336       /* Get a free block for to-space.  Extra blocks will be chained on
337        * as necessary.
338        */
339       bd = allocBlock();
340       stp = &generations[g].steps[s];
341       ASSERT(stp->gen_no == g);
342       ASSERT(stp->hp ? Bdescr(stp->hp)->step == stp : rtsTrue);
343       bd->gen_no = g;
344       bd->step = stp;
345       bd->link = NULL;
346       bd->flags        = BF_EVACUATED;  // it's a to-space block 
347       stp->hp          = bd->start;
348       stp->hpLim       = stp->hp + BLOCK_SIZE_W;
349       stp->hp_bd       = bd;
350       stp->to_blocks   = bd;
351       stp->n_to_blocks = 1;
352       stp->scan        = bd->start;
353       stp->scan_bd     = bd;
354       stp->new_large_objects = NULL;
355       stp->scavenged_large_objects = NULL;
356       stp->n_scavenged_large_blocks = 0;
357       new_blocks++;
358       // mark the large objects as not evacuated yet 
359       for (bd = stp->large_objects; bd; bd = bd->link) {
360         bd->flags = BF_LARGE;
361       }
362
363       // for a compacted step, we need to allocate the bitmap
364       if (stp->is_compacted) {
365           nat bitmap_size; // in bytes
366           bdescr *bitmap_bdescr;
367           StgWord *bitmap;
368
369           bitmap_size = stp->n_blocks * BLOCK_SIZE / (sizeof(W_)*BITS_PER_BYTE);
370
371           if (bitmap_size > 0) {
372               bitmap_bdescr = allocGroup((nat)BLOCK_ROUND_UP(bitmap_size) 
373                                          / BLOCK_SIZE);
374               stp->bitmap = bitmap_bdescr;
375               bitmap = bitmap_bdescr->start;
376               
377               IF_DEBUG(gc, belch("bitmap_size: %d, bitmap: %p",
378                                    bitmap_size, bitmap););
379               
380               // don't forget to fill it with zeros!
381               memset(bitmap, 0, bitmap_size);
382               
383               // for each block in this step, point to its bitmap from the
384               // block descriptor.
385               for (bd=stp->blocks; bd != NULL; bd = bd->link) {
386                   bd->u.bitmap = bitmap;
387                   bitmap += BLOCK_SIZE_W / (sizeof(W_)*BITS_PER_BYTE);
388               }
389           }
390       }
391     }
392   }
393
394   /* make sure the older generations have at least one block to
395    * allocate into (this makes things easier for copy(), see below.
396    */
397   for (g = N+1; g < RtsFlags.GcFlags.generations; g++) {
398     for (s = 0; s < generations[g].n_steps; s++) {
399       stp = &generations[g].steps[s];
400       if (stp->hp_bd == NULL) {
401           ASSERT(stp->blocks == NULL);
402           bd = allocBlock();
403           bd->gen_no = g;
404           bd->step = stp;
405           bd->link = NULL;
406           bd->flags = 0;        // *not* a to-space block or a large object
407           stp->hp = bd->start;
408           stp->hpLim = stp->hp + BLOCK_SIZE_W;
409           stp->hp_bd = bd;
410           stp->blocks = bd;
411           stp->n_blocks = 1;
412           new_blocks++;
413       }
414       /* Set the scan pointer for older generations: remember we
415        * still have to scavenge objects that have been promoted. */
416       stp->scan = stp->hp;
417       stp->scan_bd = stp->hp_bd;
418       stp->to_blocks = NULL;
419       stp->n_to_blocks = 0;
420       stp->new_large_objects = NULL;
421       stp->scavenged_large_objects = NULL;
422       stp->n_scavenged_large_blocks = 0;
423     }
424   }
425
426   /* Allocate a mark stack if we're doing a major collection.
427    */
428   if (major_gc) {
429       mark_stack_bdescr = allocGroup(MARK_STACK_BLOCKS);
430       mark_stack = (StgPtr *)mark_stack_bdescr->start;
431       mark_sp    = mark_stack;
432       mark_splim = mark_stack + (MARK_STACK_BLOCKS * BLOCK_SIZE_W);
433   } else {
434       mark_stack_bdescr = NULL;
435   }
436
437   /* -----------------------------------------------------------------------
438    * follow all the roots that we know about:
439    *   - mutable lists from each generation > N
440    * we want to *scavenge* these roots, not evacuate them: they're not
441    * going to move in this GC.
442    * Also: do them in reverse generation order.  This is because we
443    * often want to promote objects that are pointed to by older
444    * generations early, so we don't have to repeatedly copy them.
445    * Doing the generations in reverse order ensures that we don't end
446    * up in the situation where we want to evac an object to gen 3 and
447    * it has already been evaced to gen 2.
448    */
449   { 
450     int st;
451     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
452       generations[g].saved_mut_list = generations[g].mut_list;
453       generations[g].mut_list = END_MUT_LIST;
454     }
455
456     // Do the mut-once lists first 
457     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
458       IF_PAR_DEBUG(verbose,
459                    printMutOnceList(&generations[g]));
460       scavenge_mut_once_list(&generations[g]);
461       evac_gen = g;
462       for (st = generations[g].n_steps-1; st >= 0; st--) {
463         scavenge(&generations[g].steps[st]);
464       }
465     }
466
467     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
468       IF_PAR_DEBUG(verbose,
469                    printMutableList(&generations[g]));
470       scavenge_mutable_list(&generations[g]);
471       evac_gen = g;
472       for (st = generations[g].n_steps-1; st >= 0; st--) {
473         scavenge(&generations[g].steps[st]);
474       }
475     }
476   }
477
478   /* follow roots from the CAF list (used by GHCi)
479    */
480   evac_gen = 0;
481   markCAFs(mark_root);
482
483   /* follow all the roots that the application knows about.
484    */
485   evac_gen = 0;
486   get_roots(mark_root);
487
488 #if defined(PAR)
489   /* And don't forget to mark the TSO if we got here direct from
490    * Haskell! */
491   /* Not needed in a seq version?
492   if (CurrentTSO) {
493     CurrentTSO = (StgTSO *)MarkRoot((StgClosure *)CurrentTSO);
494   }
495   */
496
497   // Mark the entries in the GALA table of the parallel system 
498   markLocalGAs(major_gc);
499   // Mark all entries on the list of pending fetches 
500   markPendingFetches(major_gc);
501 #endif
502
503   /* Mark the weak pointer list, and prepare to detect dead weak
504    * pointers.
505    */
506   mark_weak_ptr_list(&weak_ptr_list);
507   old_weak_ptr_list = weak_ptr_list;
508   weak_ptr_list = NULL;
509   weak_stage = WeakPtrs;
510
511   /* The all_threads list is like the weak_ptr_list.  
512    * See traverse_weak_ptr_list() for the details.
513    */
514   old_all_threads = all_threads;
515   all_threads = END_TSO_QUEUE;
516   resurrected_threads = END_TSO_QUEUE;
517
518   /* Mark the stable pointer table.
519    */
520   markStablePtrTable(mark_root);
521
522 #ifdef INTERPRETER
523   { 
524       /* ToDo: To fix the caf leak, we need to make the commented out
525        * parts of this code do something sensible - as described in 
526        * the CAF document.
527        */
528       extern void markHugsObjects(void);
529       markHugsObjects();
530   }
531 #endif
532
533   /* -------------------------------------------------------------------------
534    * Repeatedly scavenge all the areas we know about until there's no
535    * more scavenging to be done.
536    */
537   { 
538     rtsBool flag;
539   loop:
540     flag = rtsFalse;
541
542     // scavenge static objects 
543     if (major_gc && static_objects != END_OF_STATIC_LIST) {
544         IF_DEBUG(sanity, checkStaticObjects(static_objects));
545         scavenge_static();
546     }
547
548     /* When scavenging the older generations:  Objects may have been
549      * evacuated from generations <= N into older generations, and we
550      * need to scavenge these objects.  We're going to try to ensure that
551      * any evacuations that occur move the objects into at least the
552      * same generation as the object being scavenged, otherwise we
553      * have to create new entries on the mutable list for the older
554      * generation.
555      */
556
557     // scavenge each step in generations 0..maxgen 
558     { 
559       long gen;
560       int st; 
561
562     loop2:
563       // scavenge objects in compacted generation
564       if (mark_stack_overflowed || oldgen_scan_bd != NULL ||
565           (mark_stack_bdescr != NULL && !mark_stack_empty())) {
566           scavenge_mark_stack();
567           flag = rtsTrue;
568       }
569
570       for (gen = RtsFlags.GcFlags.generations; --gen >= 0; ) {
571         for (st = generations[gen].n_steps; --st >= 0; ) {
572           if (gen == 0 && st == 0 && RtsFlags.GcFlags.generations > 1) { 
573             continue; 
574           }
575           stp = &generations[gen].steps[st];
576           evac_gen = gen;
577           if (stp->hp_bd != stp->scan_bd || stp->scan < stp->hp) {
578             scavenge(stp);
579             flag = rtsTrue;
580             goto loop2;
581           }
582           if (stp->new_large_objects != NULL) {
583             scavenge_large(stp);
584             flag = rtsTrue;
585             goto loop2;
586           }
587         }
588       }
589     }
590
591     if (flag) { goto loop; }
592
593     // must be last...  invariant is that everything is fully
594     // scavenged at this point.
595     if (traverse_weak_ptr_list()) { // returns rtsTrue if evaced something 
596       goto loop;
597     }
598   }
599
600   /* Update the pointers from the "main thread" list - these are
601    * treated as weak pointers because we want to allow a main thread
602    * to get a BlockedOnDeadMVar exception in the same way as any other
603    * thread.  Note that the threads should all have been retained by
604    * GC by virtue of being on the all_threads list, we're just
605    * updating pointers here.
606    */
607   {
608       StgMainThread *m;
609       StgTSO *tso;
610       for (m = main_threads; m != NULL; m = m->link) {
611           tso = (StgTSO *) isAlive((StgClosure *)m->tso);
612           if (tso == NULL) {
613               barf("main thread has been GC'd");
614           }
615           m->tso = tso;
616       }
617   }
618
619 #if defined(PAR)
620   // Reconstruct the Global Address tables used in GUM 
621   rebuildGAtables(major_gc);
622   IF_DEBUG(sanity, checkLAGAtable(rtsTrue/*check closures, too*/));
623 #endif
624
625   // Now see which stable names are still alive.
626   gcStablePtrTable();
627
628   // Tidy the end of the to-space chains 
629   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
630       for (s = 0; s < generations[g].n_steps; s++) {
631           stp = &generations[g].steps[s];
632           if (!(g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1)) {
633               stp->hp_bd->free = stp->hp;
634               stp->hp_bd->link = NULL;
635           }
636       }
637   }
638
639 #ifdef PROFILING
640   // We call processHeapClosureForDead() on every closure destroyed during
641   // the current garbage collection, so we invoke LdvCensusForDead().
642   if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_LDV
643       || RtsFlags.ProfFlags.bioSelector != NULL)
644     LdvCensusForDead(N);
645 #endif
646
647   // NO MORE EVACUATION AFTER THIS POINT!
648   // Finally: compaction of the oldest generation.
649   if (major_gc && oldest_gen->steps[0].is_compacted) {
650       // save number of blocks for stats
651       oldgen_saved_blocks = oldest_gen->steps[0].n_blocks;
652       compact(get_roots);
653   }
654
655   IF_DEBUG(sanity, checkGlobalTSOList(rtsFalse));
656
657   /* run through all the generations/steps and tidy up 
658    */
659   copied = new_blocks * BLOCK_SIZE_W;
660   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
661
662     if (g <= N) {
663       generations[g].collections++; // for stats 
664     }
665
666     for (s = 0; s < generations[g].n_steps; s++) {
667       bdescr *next;
668       stp = &generations[g].steps[s];
669
670       if (!(g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1)) {
671         // stats information: how much we copied 
672         if (g <= N) {
673           copied -= stp->hp_bd->start + BLOCK_SIZE_W -
674             stp->hp_bd->free;
675         }
676       }
677
678       // for generations we collected... 
679       if (g <= N) {
680
681           // rough calculation of garbage collected, for stats output
682           if (stp->is_compacted) {
683               collected += (oldgen_saved_blocks - stp->n_blocks) * BLOCK_SIZE_W;
684           } else {
685               collected += stp->n_blocks * BLOCK_SIZE_W;
686           }
687
688         /* free old memory and shift to-space into from-space for all
689          * the collected steps (except the allocation area).  These
690          * freed blocks will probaby be quickly recycled.
691          */
692         if (!(g == 0 && s == 0)) {
693             if (stp->is_compacted) {
694                 // for a compacted step, just shift the new to-space
695                 // onto the front of the now-compacted existing blocks.
696                 for (bd = stp->to_blocks; bd != NULL; bd = bd->link) {
697                     bd->flags &= ~BF_EVACUATED; // now from-space 
698                 }
699                 // tack the new blocks on the end of the existing blocks
700                 if (stp->blocks == NULL) {
701                     stp->blocks = stp->to_blocks;
702                 } else {
703                     for (bd = stp->blocks; bd != NULL; bd = next) {
704                         next = bd->link;
705                         if (next == NULL) {
706                             bd->link = stp->to_blocks;
707                         }
708                     }
709                 }
710                 // add the new blocks to the block tally
711                 stp->n_blocks += stp->n_to_blocks;
712             } else {
713                 freeChain(stp->blocks);
714                 stp->blocks = stp->to_blocks;
715                 stp->n_blocks = stp->n_to_blocks;
716                 for (bd = stp->blocks; bd != NULL; bd = bd->link) {
717                     bd->flags &= ~BF_EVACUATED; // now from-space 
718                 }
719             }
720             stp->to_blocks = NULL;
721             stp->n_to_blocks = 0;
722         }
723
724         /* LARGE OBJECTS.  The current live large objects are chained on
725          * scavenged_large, having been moved during garbage
726          * collection from large_objects.  Any objects left on
727          * large_objects list are therefore dead, so we free them here.
728          */
729         for (bd = stp->large_objects; bd != NULL; bd = next) {
730           next = bd->link;
731           freeGroup(bd);
732           bd = next;
733         }
734
735         // update the count of blocks used by large objects
736         for (bd = stp->scavenged_large_objects; bd != NULL; bd = bd->link) {
737           bd->flags &= ~BF_EVACUATED;
738         }
739         stp->large_objects  = stp->scavenged_large_objects;
740         stp->n_large_blocks = stp->n_scavenged_large_blocks;
741
742       } else {
743         // for older generations... 
744         
745         /* For older generations, we need to append the
746          * scavenged_large_object list (i.e. large objects that have been
747          * promoted during this GC) to the large_object list for that step.
748          */
749         for (bd = stp->scavenged_large_objects; bd; bd = next) {
750           next = bd->link;
751           bd->flags &= ~BF_EVACUATED;
752           dbl_link_onto(bd, &stp->large_objects);
753         }
754
755         // add the new blocks we promoted during this GC 
756         stp->n_blocks += stp->n_to_blocks;
757         stp->n_large_blocks += stp->n_scavenged_large_blocks;
758       }
759     }
760   }
761
762   /* Reset the sizes of the older generations when we do a major
763    * collection.
764    *
765    * CURRENT STRATEGY: make all generations except zero the same size.
766    * We have to stay within the maximum heap size, and leave a certain
767    * percentage of the maximum heap size available to allocate into.
768    */
769   if (major_gc && RtsFlags.GcFlags.generations > 1) {
770       nat live, size, min_alloc;
771       nat max  = RtsFlags.GcFlags.maxHeapSize;
772       nat gens = RtsFlags.GcFlags.generations;
773
774       // live in the oldest generations
775       live = oldest_gen->steps[0].n_blocks +
776              oldest_gen->steps[0].n_large_blocks;
777
778       // default max size for all generations except zero
779       size = stg_max(live * RtsFlags.GcFlags.oldGenFactor,
780                      RtsFlags.GcFlags.minOldGenSize);
781
782       // minimum size for generation zero
783       min_alloc = stg_max((RtsFlags.GcFlags.pcFreeHeap * max) / 200,
784                           RtsFlags.GcFlags.minAllocAreaSize);
785
786       // Auto-enable compaction when the residency reaches a
787       // certain percentage of the maximum heap size (default: 30%).
788       if (RtsFlags.GcFlags.generations > 1 &&
789           (RtsFlags.GcFlags.compact ||
790            (max > 0 &&
791             oldest_gen->steps[0].n_blocks > 
792             (RtsFlags.GcFlags.compactThreshold * max) / 100))) {
793           oldest_gen->steps[0].is_compacted = 1;
794 //        fprintf(stderr,"compaction: on\n", live);
795       } else {
796           oldest_gen->steps[0].is_compacted = 0;
797 //        fprintf(stderr,"compaction: off\n", live);
798       }
799
800       // if we're going to go over the maximum heap size, reduce the
801       // size of the generations accordingly.  The calculation is
802       // different if compaction is turned on, because we don't need
803       // to double the space required to collect the old generation.
804       if (max != 0) {
805
806           // this test is necessary to ensure that the calculations
807           // below don't have any negative results - we're working
808           // with unsigned values here.
809           if (max < min_alloc) {
810               heapOverflow();
811           }
812
813           if (oldest_gen->steps[0].is_compacted) {
814               if ( (size + (size - 1) * (gens - 2) * 2) + min_alloc > max ) {
815                   size = (max - min_alloc) / ((gens - 1) * 2 - 1);
816               }
817           } else {
818               if ( (size * (gens - 1) * 2) + min_alloc > max ) {
819                   size = (max - min_alloc) / ((gens - 1) * 2);
820               }
821           }
822
823           if (size < live) {
824               heapOverflow();
825           }
826       }
827
828 #if 0
829       fprintf(stderr,"live: %d, min_alloc: %d, size : %d, max = %d\n", live,
830               min_alloc, size, max);
831 #endif
832
833       for (g = 0; g < gens; g++) {
834           generations[g].max_blocks = size;
835       }
836   }
837
838   // Guess the amount of live data for stats.
839   live = calcLive();
840
841   /* Free the small objects allocated via allocate(), since this will
842    * all have been copied into G0S1 now.  
843    */
844   if (small_alloc_list != NULL) {
845     freeChain(small_alloc_list);
846   }
847   small_alloc_list = NULL;
848   alloc_blocks = 0;
849   alloc_Hp = NULL;
850   alloc_HpLim = NULL;
851   alloc_blocks_lim = RtsFlags.GcFlags.minAllocAreaSize;
852
853   // Start a new pinned_object_block
854   pinned_object_block = NULL;
855
856   /* Free the mark stack.
857    */
858   if (mark_stack_bdescr != NULL) {
859       freeGroup(mark_stack_bdescr);
860   }
861
862   /* Free any bitmaps.
863    */
864   for (g = 0; g <= N; g++) {
865       for (s = 0; s < generations[g].n_steps; s++) {
866           stp = &generations[g].steps[s];
867           if (stp->is_compacted && stp->bitmap != NULL) {
868               freeGroup(stp->bitmap);
869           }
870       }
871   }
872
873   /* Two-space collector:
874    * Free the old to-space, and estimate the amount of live data.
875    */
876   if (RtsFlags.GcFlags.generations == 1) {
877     nat blocks;
878     
879     if (old_to_blocks != NULL) {
880       freeChain(old_to_blocks);
881     }
882     for (bd = g0s0->to_blocks; bd != NULL; bd = bd->link) {
883       bd->flags = 0;    // now from-space 
884     }
885
886     /* For a two-space collector, we need to resize the nursery. */
887     
888     /* set up a new nursery.  Allocate a nursery size based on a
889      * function of the amount of live data (by default a factor of 2)
890      * Use the blocks from the old nursery if possible, freeing up any
891      * left over blocks.
892      *
893      * If we get near the maximum heap size, then adjust our nursery
894      * size accordingly.  If the nursery is the same size as the live
895      * data (L), then we need 3L bytes.  We can reduce the size of the
896      * nursery to bring the required memory down near 2L bytes.
897      * 
898      * A normal 2-space collector would need 4L bytes to give the same
899      * performance we get from 3L bytes, reducing to the same
900      * performance at 2L bytes.
901      */
902     blocks = g0s0->n_to_blocks;
903
904     if ( RtsFlags.GcFlags.maxHeapSize != 0 &&
905          blocks * RtsFlags.GcFlags.oldGenFactor * 2 > 
906            RtsFlags.GcFlags.maxHeapSize ) {
907       long adjusted_blocks;  // signed on purpose 
908       int pc_free; 
909       
910       adjusted_blocks = (RtsFlags.GcFlags.maxHeapSize - 2 * blocks);
911       IF_DEBUG(gc, belch("@@ Near maximum heap size of 0x%x blocks, blocks = %d, adjusted to %ld", RtsFlags.GcFlags.maxHeapSize, blocks, adjusted_blocks));
912       pc_free = adjusted_blocks * 100 / RtsFlags.GcFlags.maxHeapSize;
913       if (pc_free < RtsFlags.GcFlags.pcFreeHeap) /* might even be < 0 */ {
914         heapOverflow();
915       }
916       blocks = adjusted_blocks;
917       
918     } else {
919       blocks *= RtsFlags.GcFlags.oldGenFactor;
920       if (blocks < RtsFlags.GcFlags.minAllocAreaSize) {
921         blocks = RtsFlags.GcFlags.minAllocAreaSize;
922       }
923     }
924     resizeNursery(blocks);
925     
926   } else {
927     /* Generational collector:
928      * If the user has given us a suggested heap size, adjust our
929      * allocation area to make best use of the memory available.
930      */
931
932     if (RtsFlags.GcFlags.heapSizeSuggestion) {
933       long blocks;
934       nat needed = calcNeeded();        // approx blocks needed at next GC 
935
936       /* Guess how much will be live in generation 0 step 0 next time.
937        * A good approximation is obtained by finding the
938        * percentage of g0s0 that was live at the last minor GC.
939        */
940       if (N == 0) {
941         g0s0_pcnt_kept = (new_blocks * 100) / g0s0->n_blocks;
942       }
943
944       /* Estimate a size for the allocation area based on the
945        * information available.  We might end up going slightly under
946        * or over the suggested heap size, but we should be pretty
947        * close on average.
948        *
949        * Formula:            suggested - needed
950        *                ----------------------------
951        *                    1 + g0s0_pcnt_kept/100
952        *
953        * where 'needed' is the amount of memory needed at the next
954        * collection for collecting all steps except g0s0.
955        */
956       blocks = 
957         (((long)RtsFlags.GcFlags.heapSizeSuggestion - (long)needed) * 100) /
958         (100 + (long)g0s0_pcnt_kept);
959       
960       if (blocks < (long)RtsFlags.GcFlags.minAllocAreaSize) {
961         blocks = RtsFlags.GcFlags.minAllocAreaSize;
962       }
963       
964       resizeNursery((nat)blocks);
965
966     } else {
967       // we might have added extra large blocks to the nursery, so
968       // resize back to minAllocAreaSize again.
969       resizeNursery(RtsFlags.GcFlags.minAllocAreaSize);
970     }
971   }
972
973  // mark the garbage collected CAFs as dead 
974 #if 0 && defined(DEBUG) // doesn't work at the moment 
975   if (major_gc) { gcCAFs(); }
976 #endif
977   
978 #ifdef PROFILING
979   // resetStaticObjectForRetainerProfiling() must be called before
980   // zeroing below.
981   resetStaticObjectForRetainerProfiling();
982 #endif
983
984   // zero the scavenged static object list 
985   if (major_gc) {
986     zero_static_object_list(scavenged_static_objects);
987   }
988
989   // Reset the nursery
990   resetNurseries();
991
992   RELEASE_LOCK(&sched_mutex);
993   
994   // start any pending finalizers 
995   scheduleFinalizers(old_weak_ptr_list);
996   
997   // send exceptions to any threads which were about to die 
998   resurrectThreads(resurrected_threads);
999   
1000   ACQUIRE_LOCK(&sched_mutex);
1001
1002   // Update the stable pointer hash table.
1003   updateStablePtrTable(major_gc);
1004
1005   // check sanity after GC 
1006   IF_DEBUG(sanity, checkSanity());
1007
1008   // extra GC trace info 
1009   IF_DEBUG(gc, statDescribeGens());
1010
1011 #ifdef DEBUG
1012   // symbol-table based profiling 
1013   /*  heapCensus(to_blocks); */ /* ToDo */
1014 #endif
1015
1016   // restore enclosing cost centre 
1017 #ifdef PROFILING
1018   CCCS = prev_CCS;
1019 #endif
1020
1021   // check for memory leaks if sanity checking is on 
1022   IF_DEBUG(sanity, memInventory());
1023
1024 #ifdef RTS_GTK_FRONTPANEL
1025   if (RtsFlags.GcFlags.frontpanel) {
1026       updateFrontPanelAfterGC( N, live );
1027   }
1028 #endif
1029
1030   // ok, GC over: tell the stats department what happened. 
1031   stat_endGC(allocated, collected, live, copied, N);
1032
1033   //PAR_TICKY_TP();
1034 }
1035
1036
1037 /* -----------------------------------------------------------------------------
1038    Weak Pointers
1039
1040    traverse_weak_ptr_list is called possibly many times during garbage
1041    collection.  It returns a flag indicating whether it did any work
1042    (i.e. called evacuate on any live pointers).
1043
1044    Invariant: traverse_weak_ptr_list is called when the heap is in an
1045    idempotent state.  That means that there are no pending
1046    evacuate/scavenge operations.  This invariant helps the weak
1047    pointer code decide which weak pointers are dead - if there are no
1048    new live weak pointers, then all the currently unreachable ones are
1049    dead.
1050
1051    For generational GC: we just don't try to finalize weak pointers in
1052    older generations than the one we're collecting.  This could
1053    probably be optimised by keeping per-generation lists of weak
1054    pointers, but for a few weak pointers this scheme will work.
1055
1056    There are three distinct stages to processing weak pointers:
1057
1058    - weak_stage == WeakPtrs
1059
1060      We process all the weak pointers whos keys are alive (evacuate
1061      their values and finalizers), and repeat until we can find no new
1062      live keys.  If no live keys are found in this pass, then we
1063      evacuate the finalizers of all the dead weak pointers in order to
1064      run them.
1065
1066    - weak_stage == WeakThreads
1067
1068      Now, we discover which *threads* are still alive.  Pointers to
1069      threads from the all_threads and main thread lists are the
1070      weakest of all: a pointers from the finalizer of a dead weak
1071      pointer can keep a thread alive.  Any threads found to be unreachable
1072      are evacuated and placed on the resurrected_threads list so we 
1073      can send them a signal later.
1074
1075    - weak_stage == WeakDone
1076
1077      No more evacuation is done.
1078
1079    -------------------------------------------------------------------------- */
1080
1081 static rtsBool 
1082 traverse_weak_ptr_list(void)
1083 {
1084   StgWeak *w, **last_w, *next_w;
1085   StgClosure *new;
1086   rtsBool flag = rtsFalse;
1087
1088   switch (weak_stage) {
1089
1090   case WeakDone:
1091       return rtsFalse;
1092
1093   case WeakPtrs:
1094       /* doesn't matter where we evacuate values/finalizers to, since
1095        * these pointers are treated as roots (iff the keys are alive).
1096        */
1097       evac_gen = 0;
1098       
1099       last_w = &old_weak_ptr_list;
1100       for (w = old_weak_ptr_list; w != NULL; w = next_w) {
1101           
1102           /* There might be a DEAD_WEAK on the list if finalizeWeak# was
1103            * called on a live weak pointer object.  Just remove it.
1104            */
1105           if (w->header.info == &stg_DEAD_WEAK_info) {
1106               next_w = ((StgDeadWeak *)w)->link;
1107               *last_w = next_w;
1108               continue;
1109           }
1110           
1111           switch (get_itbl(w)->type) {
1112
1113           case EVACUATED:
1114               next_w = (StgWeak *)((StgEvacuated *)w)->evacuee;
1115               *last_w = next_w;
1116               continue;
1117
1118           case WEAK:
1119               /* Now, check whether the key is reachable.
1120                */
1121               new = isAlive(w->key);
1122               if (new != NULL) {
1123                   w->key = new;
1124                   // evacuate the value and finalizer 
1125                   w->value = evacuate(w->value);
1126                   w->finalizer = evacuate(w->finalizer);
1127                   // remove this weak ptr from the old_weak_ptr list 
1128                   *last_w = w->link;
1129                   // and put it on the new weak ptr list 
1130                   next_w  = w->link;
1131                   w->link = weak_ptr_list;
1132                   weak_ptr_list = w;
1133                   flag = rtsTrue;
1134                   IF_DEBUG(weak, belch("Weak pointer still alive at %p -> %p", 
1135                                        w, w->key));
1136                   continue;
1137               }
1138               else {
1139                   last_w = &(w->link);
1140                   next_w = w->link;
1141                   continue;
1142               }
1143
1144           default:
1145               barf("traverse_weak_ptr_list: not WEAK");
1146           }
1147       }
1148       
1149       /* If we didn't make any changes, then we can go round and kill all
1150        * the dead weak pointers.  The old_weak_ptr list is used as a list
1151        * of pending finalizers later on.
1152        */
1153       if (flag == rtsFalse) {
1154           for (w = old_weak_ptr_list; w; w = w->link) {
1155               w->finalizer = evacuate(w->finalizer);
1156           }
1157
1158           // Next, move to the WeakThreads stage after fully
1159           // scavenging the finalizers we've just evacuated.
1160           weak_stage = WeakThreads;
1161       }
1162
1163       return rtsTrue;
1164
1165   case WeakThreads:
1166       /* Now deal with the all_threads list, which behaves somewhat like
1167        * the weak ptr list.  If we discover any threads that are about to
1168        * become garbage, we wake them up and administer an exception.
1169        */
1170       {
1171           StgTSO *t, *tmp, *next, **prev;
1172           
1173           prev = &old_all_threads;
1174           for (t = old_all_threads; t != END_TSO_QUEUE; t = next) {
1175               
1176               (StgClosure *)tmp = isAlive((StgClosure *)t);
1177               
1178               if (tmp != NULL) {
1179                   t = tmp;
1180               }
1181               
1182               ASSERT(get_itbl(t)->type == TSO);
1183               switch (t->what_next) {
1184               case ThreadRelocated:
1185                   next = t->link;
1186                   *prev = next;
1187                   continue;
1188               case ThreadKilled:
1189               case ThreadComplete:
1190                   // finshed or died.  The thread might still be alive, but we
1191                   // don't keep it on the all_threads list.  Don't forget to
1192                   // stub out its global_link field.
1193                   next = t->global_link;
1194                   t->global_link = END_TSO_QUEUE;
1195                   *prev = next;
1196                   continue;
1197               default:
1198                   ;
1199               }
1200               
1201               if (tmp == NULL) {
1202                   // not alive (yet): leave this thread on the
1203                   // old_all_threads list.
1204                   prev = &(t->global_link);
1205                   next = t->global_link;
1206               } 
1207               else {
1208                   // alive: move this thread onto the all_threads list.
1209                   next = t->global_link;
1210                   t->global_link = all_threads;
1211                   all_threads  = t;
1212                   *prev = next;
1213               }
1214           }
1215       }
1216       
1217       /* And resurrect any threads which were about to become garbage.
1218        */
1219       {
1220           StgTSO *t, *tmp, *next;
1221           for (t = old_all_threads; t != END_TSO_QUEUE; t = next) {
1222               next = t->global_link;
1223               (StgClosure *)tmp = evacuate((StgClosure *)t);
1224               tmp->global_link = resurrected_threads;
1225               resurrected_threads = tmp;
1226           }
1227       }
1228       
1229       weak_stage = WeakDone;  // *now* we're done,
1230       return rtsTrue;         // but one more round of scavenging, please
1231
1232   default:
1233       barf("traverse_weak_ptr_list");
1234   }
1235
1236 }
1237
1238 /* -----------------------------------------------------------------------------
1239    After GC, the live weak pointer list may have forwarding pointers
1240    on it, because a weak pointer object was evacuated after being
1241    moved to the live weak pointer list.  We remove those forwarding
1242    pointers here.
1243
1244    Also, we don't consider weak pointer objects to be reachable, but
1245    we must nevertheless consider them to be "live" and retain them.
1246    Therefore any weak pointer objects which haven't as yet been
1247    evacuated need to be evacuated now.
1248    -------------------------------------------------------------------------- */
1249
1250
1251 static void
1252 mark_weak_ptr_list ( StgWeak **list )
1253 {
1254   StgWeak *w, **last_w;
1255
1256   last_w = list;
1257   for (w = *list; w; w = w->link) {
1258       // w might be WEAK, EVACUATED, or DEAD_WEAK (actually CON_STATIC) here
1259       ASSERT(w->header.info == &stg_DEAD_WEAK_info 
1260              || get_itbl(w)->type == WEAK || get_itbl(w)->type == EVACUATED);
1261       (StgClosure *)w = evacuate((StgClosure *)w);
1262       *last_w = w;
1263       last_w = &(w->link);
1264   }
1265 }
1266
1267 /* -----------------------------------------------------------------------------
1268    isAlive determines whether the given closure is still alive (after
1269    a garbage collection) or not.  It returns the new address of the
1270    closure if it is alive, or NULL otherwise.
1271
1272    NOTE: Use it before compaction only!
1273    -------------------------------------------------------------------------- */
1274
1275
1276 StgClosure *
1277 isAlive(StgClosure *p)
1278 {
1279   const StgInfoTable *info;
1280   bdescr *bd;
1281
1282   while (1) {
1283
1284     info = get_itbl(p);
1285
1286     /* ToDo: for static closures, check the static link field.
1287      * Problem here is that we sometimes don't set the link field, eg.
1288      * for static closures with an empty SRT or CONSTR_STATIC_NOCAFs.
1289      */
1290
1291   loop:
1292     bd = Bdescr((P_)p);
1293
1294     // ignore closures in generations that we're not collecting. 
1295     if (LOOKS_LIKE_STATIC(p) || bd->gen_no > N) {
1296         return p;
1297     }
1298     // large objects have an evacuated flag
1299     if (bd->flags & BF_LARGE) {
1300         if (bd->flags & BF_EVACUATED) {
1301             return p;
1302         } else {
1303             return NULL;
1304         }
1305     }
1306     // check the mark bit for compacted steps
1307     if (bd->step->is_compacted && is_marked((P_)p,bd)) {
1308         return p;
1309     }
1310
1311     switch (info->type) {
1312
1313     case IND:
1314     case IND_STATIC:
1315     case IND_PERM:
1316     case IND_OLDGEN:            // rely on compatible layout with StgInd 
1317     case IND_OLDGEN_PERM:
1318       // follow indirections 
1319       p = ((StgInd *)p)->indirectee;
1320       continue;
1321
1322     case EVACUATED:
1323       // alive! 
1324       return ((StgEvacuated *)p)->evacuee;
1325
1326     case TSO:
1327       if (((StgTSO *)p)->what_next == ThreadRelocated) {
1328         p = (StgClosure *)((StgTSO *)p)->link;
1329         goto loop;
1330       }
1331
1332     default:
1333       // dead. 
1334       return NULL;
1335     }
1336   }
1337 }
1338
1339 static void
1340 mark_root(StgClosure **root)
1341 {
1342   *root = evacuate(*root);
1343 }
1344
1345 static void
1346 addBlock(step *stp)
1347 {
1348   bdescr *bd = allocBlock();
1349   bd->gen_no = stp->gen_no;
1350   bd->step = stp;
1351
1352   if (stp->gen_no <= N) {
1353     bd->flags = BF_EVACUATED;
1354   } else {
1355     bd->flags = 0;
1356   }
1357
1358   stp->hp_bd->free = stp->hp;
1359   stp->hp_bd->link = bd;
1360   stp->hp = bd->start;
1361   stp->hpLim = stp->hp + BLOCK_SIZE_W;
1362   stp->hp_bd = bd;
1363   stp->n_to_blocks++;
1364   new_blocks++;
1365 }
1366
1367
1368 static __inline__ void 
1369 upd_evacuee(StgClosure *p, StgClosure *dest)
1370 {
1371   p->header.info = &stg_EVACUATED_info;
1372   ((StgEvacuated *)p)->evacuee = dest;
1373 }
1374
1375
1376 static __inline__ StgClosure *
1377 copy(StgClosure *src, nat size, step *stp)
1378 {
1379   P_ to, from, dest;
1380 #ifdef PROFILING
1381   // @LDV profiling
1382   nat size_org = size;
1383 #endif
1384
1385   TICK_GC_WORDS_COPIED(size);
1386   /* Find out where we're going, using the handy "to" pointer in 
1387    * the step of the source object.  If it turns out we need to
1388    * evacuate to an older generation, adjust it here (see comment
1389    * by evacuate()).
1390    */
1391   if (stp->gen_no < evac_gen) {
1392 #ifdef NO_EAGER_PROMOTION    
1393     failed_to_evac = rtsTrue;
1394 #else
1395     stp = &generations[evac_gen].steps[0];
1396 #endif
1397   }
1398
1399   /* chain a new block onto the to-space for the destination step if
1400    * necessary.
1401    */
1402   if (stp->hp + size >= stp->hpLim) {
1403     addBlock(stp);
1404   }
1405
1406   for(to = stp->hp, from = (P_)src; size>0; --size) {
1407     *to++ = *from++;
1408   }
1409
1410   dest = stp->hp;
1411   stp->hp = to;
1412   upd_evacuee(src,(StgClosure *)dest);
1413 #ifdef PROFILING
1414   // We store the size of the just evacuated object in the LDV word so that
1415   // the profiler can guess the position of the next object later.
1416   SET_EVACUAEE_FOR_LDV(src, size_org);
1417 #endif
1418   return (StgClosure *)dest;
1419 }
1420
1421 /* Special version of copy() for when we only want to copy the info
1422  * pointer of an object, but reserve some padding after it.  This is
1423  * used to optimise evacuation of BLACKHOLEs.
1424  */
1425
1426
1427 static StgClosure *
1428 copyPart(StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
1429 {
1430   P_ dest, to, from;
1431 #ifdef PROFILING
1432   // @LDV profiling
1433   nat size_to_copy_org = size_to_copy;
1434 #endif
1435
1436   TICK_GC_WORDS_COPIED(size_to_copy);
1437   if (stp->gen_no < evac_gen) {
1438 #ifdef NO_EAGER_PROMOTION    
1439     failed_to_evac = rtsTrue;
1440 #else
1441     stp = &generations[evac_gen].steps[0];
1442 #endif
1443   }
1444
1445   if (stp->hp + size_to_reserve >= stp->hpLim) {
1446     addBlock(stp);
1447   }
1448
1449   for(to = stp->hp, from = (P_)src; size_to_copy>0; --size_to_copy) {
1450     *to++ = *from++;
1451   }
1452   
1453   dest = stp->hp;
1454   stp->hp += size_to_reserve;
1455   upd_evacuee(src,(StgClosure *)dest);
1456 #ifdef PROFILING
1457   // We store the size of the just evacuated object in the LDV word so that
1458   // the profiler can guess the position of the next object later.
1459   // size_to_copy_org is wrong because the closure already occupies size_to_reserve
1460   // words.
1461   SET_EVACUAEE_FOR_LDV(src, size_to_reserve);
1462   // fill the slop
1463   if (size_to_reserve - size_to_copy_org > 0)
1464     FILL_SLOP(stp->hp - 1, (int)(size_to_reserve - size_to_copy_org)); 
1465 #endif
1466   return (StgClosure *)dest;
1467 }
1468
1469
1470 /* -----------------------------------------------------------------------------
1471    Evacuate a large object
1472
1473    This just consists of removing the object from the (doubly-linked)
1474    step->large_objects list, and linking it on to the (singly-linked)
1475    step->new_large_objects list, from where it will be scavenged later.
1476
1477    Convention: bd->flags has BF_EVACUATED set for a large object
1478    that has been evacuated, or unset otherwise.
1479    -------------------------------------------------------------------------- */
1480
1481
1482 static inline void
1483 evacuate_large(StgPtr p)
1484 {
1485   bdescr *bd = Bdescr(p);
1486   step *stp;
1487
1488   // object must be at the beginning of the block (or be a ByteArray)
1489   ASSERT(get_itbl((StgClosure *)p)->type == ARR_WORDS ||
1490          (((W_)p & BLOCK_MASK) == 0));
1491
1492   // already evacuated? 
1493   if (bd->flags & BF_EVACUATED) { 
1494     /* Don't forget to set the failed_to_evac flag if we didn't get
1495      * the desired destination (see comments in evacuate()).
1496      */
1497     if (bd->gen_no < evac_gen) {
1498       failed_to_evac = rtsTrue;
1499       TICK_GC_FAILED_PROMOTION();
1500     }
1501     return;
1502   }
1503
1504   stp = bd->step;
1505   // remove from large_object list 
1506   if (bd->u.back) {
1507     bd->u.back->link = bd->link;
1508   } else { // first object in the list 
1509     stp->large_objects = bd->link;
1510   }
1511   if (bd->link) {
1512     bd->link->u.back = bd->u.back;
1513   }
1514   
1515   /* link it on to the evacuated large object list of the destination step
1516    */
1517   stp = bd->step->to;
1518   if (stp->gen_no < evac_gen) {
1519 #ifdef NO_EAGER_PROMOTION    
1520     failed_to_evac = rtsTrue;
1521 #else
1522     stp = &generations[evac_gen].steps[0];
1523 #endif
1524   }
1525
1526   bd->step = stp;
1527   bd->gen_no = stp->gen_no;
1528   bd->link = stp->new_large_objects;
1529   stp->new_large_objects = bd;
1530   bd->flags |= BF_EVACUATED;
1531 }
1532
1533 /* -----------------------------------------------------------------------------
1534    Adding a MUT_CONS to an older generation.
1535
1536    This is necessary from time to time when we end up with an
1537    old-to-new generation pointer in a non-mutable object.  We defer
1538    the promotion until the next GC.
1539    -------------------------------------------------------------------------- */
1540
1541
1542 static StgClosure *
1543 mkMutCons(StgClosure *ptr, generation *gen)
1544 {
1545   StgMutVar *q;
1546   step *stp;
1547
1548   stp = &gen->steps[0];
1549
1550   /* chain a new block onto the to-space for the destination step if
1551    * necessary.
1552    */
1553   if (stp->hp + sizeofW(StgIndOldGen) >= stp->hpLim) {
1554     addBlock(stp);
1555   }
1556
1557   q = (StgMutVar *)stp->hp;
1558   stp->hp += sizeofW(StgMutVar);
1559
1560   SET_HDR(q,&stg_MUT_CONS_info,CCS_GC);
1561   q->var = ptr;
1562   recordOldToNewPtrs((StgMutClosure *)q);
1563
1564   return (StgClosure *)q;
1565 }
1566
1567 /* -----------------------------------------------------------------------------
1568    Evacuate
1569
1570    This is called (eventually) for every live object in the system.
1571
1572    The caller to evacuate specifies a desired generation in the
1573    evac_gen global variable.  The following conditions apply to
1574    evacuating an object which resides in generation M when we're
1575    collecting up to generation N
1576
1577    if  M >= evac_gen 
1578            if  M > N     do nothing
1579            else          evac to step->to
1580
1581    if  M < evac_gen      evac to evac_gen, step 0
1582
1583    if the object is already evacuated, then we check which generation
1584    it now resides in.
1585
1586    if  M >= evac_gen     do nothing
1587    if  M <  evac_gen     set failed_to_evac flag to indicate that we
1588                          didn't manage to evacuate this object into evac_gen.
1589
1590    -------------------------------------------------------------------------- */
1591
1592 static StgClosure *
1593 evacuate(StgClosure *q)
1594 {
1595   StgClosure *to;
1596   bdescr *bd = NULL;
1597   step *stp;
1598   const StgInfoTable *info;
1599
1600 loop:
1601   if (HEAP_ALLOCED(q)) {
1602     bd = Bdescr((P_)q);
1603
1604     if (bd->gen_no > N) {
1605         /* Can't evacuate this object, because it's in a generation
1606          * older than the ones we're collecting.  Let's hope that it's
1607          * in evac_gen or older, or we will have to arrange to track
1608          * this pointer using the mutable list.
1609          */
1610         if (bd->gen_no < evac_gen) {
1611             // nope 
1612             failed_to_evac = rtsTrue;
1613             TICK_GC_FAILED_PROMOTION();
1614         }
1615         return q;
1616     }
1617
1618     /* evacuate large objects by re-linking them onto a different list.
1619      */
1620     if (bd->flags & BF_LARGE) {
1621         info = get_itbl(q);
1622         if (info->type == TSO && 
1623             ((StgTSO *)q)->what_next == ThreadRelocated) {
1624             q = (StgClosure *)((StgTSO *)q)->link;
1625             goto loop;
1626         }
1627         evacuate_large((P_)q);
1628         return q;
1629     }
1630
1631     /* If the object is in a step that we're compacting, then we
1632      * need to use an alternative evacuate procedure.
1633      */
1634     if (bd->step->is_compacted) {
1635         if (!is_marked((P_)q,bd)) {
1636             mark((P_)q,bd);
1637             if (mark_stack_full()) {
1638                 mark_stack_overflowed = rtsTrue;
1639                 reset_mark_stack();
1640             }
1641             push_mark_stack((P_)q);
1642         }
1643         return q;
1644     }
1645
1646     stp = bd->step->to;
1647   }
1648 #ifdef DEBUG
1649   else stp = NULL; // make sure copy() will crash if HEAP_ALLOCED is wrong 
1650 #endif
1651
1652   // make sure the info pointer is into text space 
1653   ASSERT(q && (LOOKS_LIKE_GHC_INFO(GET_INFO(q))
1654                || IS_HUGS_CONSTR_INFO(GET_INFO(q))));
1655   info = get_itbl(q);
1656   
1657   switch (info -> type) {
1658
1659   case MUT_VAR:
1660   case MVAR:
1661       to = copy(q,sizeW_fromITBL(info),stp);
1662       return to;
1663
1664   case CONSTR_0_1:
1665   { 
1666       StgWord w = (StgWord)q->payload[0];
1667       if (q->header.info == Czh_con_info &&
1668           // unsigned, so always true:  (StgChar)w >= MIN_CHARLIKE &&  
1669           (StgChar)w <= MAX_CHARLIKE) {
1670           return (StgClosure *)CHARLIKE_CLOSURE((StgChar)w);
1671       }
1672       if (q->header.info == Izh_con_info &&
1673           (StgInt)w >= MIN_INTLIKE && (StgInt)w <= MAX_INTLIKE) {
1674           return (StgClosure *)INTLIKE_CLOSURE((StgInt)w);
1675       }
1676       // else, fall through ... 
1677   }
1678
1679   case FUN_1_0:
1680   case FUN_0_1:
1681   case CONSTR_1_0:
1682     return copy(q,sizeofW(StgHeader)+1,stp);
1683
1684   case THUNK_1_0:               // here because of MIN_UPD_SIZE 
1685   case THUNK_0_1:
1686   case THUNK_1_1:
1687   case THUNK_0_2:
1688   case THUNK_2_0:
1689 #ifdef NO_PROMOTE_THUNKS
1690     if (bd->gen_no == 0 && 
1691         bd->step->no != 0 &&
1692         bd->step->no == generations[bd->gen_no].n_steps-1) {
1693       stp = bd->step;
1694     }
1695 #endif
1696     return copy(q,sizeofW(StgHeader)+2,stp);
1697
1698   case FUN_1_1:
1699   case FUN_0_2:
1700   case FUN_2_0:
1701   case CONSTR_1_1:
1702   case CONSTR_0_2:
1703   case CONSTR_2_0:
1704     return copy(q,sizeofW(StgHeader)+2,stp);
1705
1706   case FUN:
1707   case THUNK:
1708   case CONSTR:
1709   case IND_PERM:
1710   case IND_OLDGEN_PERM:
1711   case WEAK:
1712   case FOREIGN:
1713   case STABLE_NAME:
1714   case BCO:
1715     return copy(q,sizeW_fromITBL(info),stp);
1716
1717   case CAF_BLACKHOLE:
1718   case SE_CAF_BLACKHOLE:
1719   case SE_BLACKHOLE:
1720   case BLACKHOLE:
1721     return copyPart(q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
1722
1723   case BLACKHOLE_BQ:
1724     to = copy(q,BLACKHOLE_sizeW(),stp); 
1725     return to;
1726
1727   case THUNK_SELECTOR:
1728     {
1729         StgClosure *p;
1730
1731         if (thunk_selector_depth > MAX_THUNK_SELECTOR_DEPTH) {
1732             return copy(q,THUNK_SELECTOR_sizeW(),stp);
1733         }
1734
1735         p = eval_thunk_selector(info->layout.selector_offset,
1736                                 (StgSelector *)q);
1737
1738         if (p == NULL) {
1739             return copy(q,THUNK_SELECTOR_sizeW(),stp);
1740         } else {
1741             // q is still BLACKHOLE'd.
1742             thunk_selector_depth++;
1743             p = evacuate(p);
1744             thunk_selector_depth--;
1745             upd_evacuee(q,p);
1746             return p;
1747         }
1748     }
1749
1750   case IND:
1751   case IND_OLDGEN:
1752     // follow chains of indirections, don't evacuate them 
1753     q = ((StgInd*)q)->indirectee;
1754     goto loop;
1755
1756   case THUNK_STATIC:
1757     if (info->srt_len > 0 && major_gc && 
1758         THUNK_STATIC_LINK((StgClosure *)q) == NULL) {
1759       THUNK_STATIC_LINK((StgClosure *)q) = static_objects;
1760       static_objects = (StgClosure *)q;
1761     }
1762     return q;
1763
1764   case FUN_STATIC:
1765     if (info->srt_len > 0 && major_gc && 
1766         FUN_STATIC_LINK((StgClosure *)q) == NULL) {
1767       FUN_STATIC_LINK((StgClosure *)q) = static_objects;
1768       static_objects = (StgClosure *)q;
1769     }
1770     return q;
1771
1772   case IND_STATIC:
1773     /* If q->saved_info != NULL, then it's a revertible CAF - it'll be
1774      * on the CAF list, so don't do anything with it here (we'll
1775      * scavenge it later).
1776      */
1777     if (major_gc
1778           && ((StgIndStatic *)q)->saved_info == NULL
1779           && IND_STATIC_LINK((StgClosure *)q) == NULL) {
1780         IND_STATIC_LINK((StgClosure *)q) = static_objects;
1781         static_objects = (StgClosure *)q;
1782     }
1783     return q;
1784
1785   case CONSTR_STATIC:
1786     if (major_gc && STATIC_LINK(info,(StgClosure *)q) == NULL) {
1787       STATIC_LINK(info,(StgClosure *)q) = static_objects;
1788       static_objects = (StgClosure *)q;
1789     }
1790     return q;
1791
1792   case CONSTR_INTLIKE:
1793   case CONSTR_CHARLIKE:
1794   case CONSTR_NOCAF_STATIC:
1795     /* no need to put these on the static linked list, they don't need
1796      * to be scavenged.
1797      */
1798     return q;
1799
1800   case RET_BCO:
1801   case RET_SMALL:
1802   case RET_VEC_SMALL:
1803   case RET_BIG:
1804   case RET_VEC_BIG:
1805   case RET_DYN:
1806   case UPDATE_FRAME:
1807   case STOP_FRAME:
1808   case CATCH_FRAME:
1809   case SEQ_FRAME:
1810     // shouldn't see these 
1811     barf("evacuate: stack frame at %p\n", q);
1812
1813   case AP_UPD:
1814   case PAP:
1815     /* PAPs and AP_UPDs are special - the payload is a copy of a chunk
1816      * of stack, tagging and all.
1817      */
1818       return copy(q,pap_sizeW((StgPAP*)q),stp);
1819
1820   case EVACUATED:
1821     /* Already evacuated, just return the forwarding address.
1822      * HOWEVER: if the requested destination generation (evac_gen) is
1823      * older than the actual generation (because the object was
1824      * already evacuated to a younger generation) then we have to
1825      * set the failed_to_evac flag to indicate that we couldn't 
1826      * manage to promote the object to the desired generation.
1827      */
1828     if (evac_gen > 0) {         // optimisation 
1829       StgClosure *p = ((StgEvacuated*)q)->evacuee;
1830       if (HEAP_ALLOCED(p) && Bdescr((P_)p)->gen_no < evac_gen) {
1831         failed_to_evac = rtsTrue;
1832         TICK_GC_FAILED_PROMOTION();
1833       }
1834     }
1835     return ((StgEvacuated*)q)->evacuee;
1836
1837   case ARR_WORDS:
1838       // just copy the block 
1839       return copy(q,arr_words_sizeW((StgArrWords *)q),stp);
1840
1841   case MUT_ARR_PTRS:
1842   case MUT_ARR_PTRS_FROZEN:
1843       // just copy the block 
1844       return copy(q,mut_arr_ptrs_sizeW((StgMutArrPtrs *)q),stp);
1845
1846   case TSO:
1847     {
1848       StgTSO *tso = (StgTSO *)q;
1849
1850       /* Deal with redirected TSOs (a TSO that's had its stack enlarged).
1851        */
1852       if (tso->what_next == ThreadRelocated) {
1853         q = (StgClosure *)tso->link;
1854         goto loop;
1855       }
1856
1857       /* To evacuate a small TSO, we need to relocate the update frame
1858        * list it contains.  
1859        */
1860       {
1861           StgTSO *new_tso = (StgTSO *)copy((StgClosure *)tso,tso_sizeW(tso),stp);
1862           move_TSO(tso, new_tso);
1863           return (StgClosure *)new_tso;
1864       }
1865     }
1866
1867 #if defined(PAR)
1868   case RBH: // cf. BLACKHOLE_BQ
1869     {
1870       //StgInfoTable *rip = get_closure_info(q, &size, &ptrs, &nonptrs, &vhs, str);
1871       to = copy(q,BLACKHOLE_sizeW(),stp); 
1872       //ToDo: derive size etc from reverted IP
1873       //to = copy(q,size,stp);
1874       IF_DEBUG(gc,
1875                belch("@@ evacuate: RBH %p (%s) to %p (%s)",
1876                      q, info_type(q), to, info_type(to)));
1877       return to;
1878     }
1879
1880   case BLOCKED_FETCH:
1881     ASSERT(sizeofW(StgBlockedFetch) >= MIN_NONUPD_SIZE);
1882     to = copy(q,sizeofW(StgBlockedFetch),stp);
1883     IF_DEBUG(gc,
1884              belch("@@ evacuate: %p (%s) to %p (%s)",
1885                    q, info_type(q), to, info_type(to)));
1886     return to;
1887
1888 # ifdef DIST    
1889   case REMOTE_REF:
1890 # endif
1891   case FETCH_ME:
1892     ASSERT(sizeofW(StgBlockedFetch) >= MIN_UPD_SIZE);
1893     to = copy(q,sizeofW(StgFetchMe),stp);
1894     IF_DEBUG(gc,
1895              belch("@@ evacuate: %p (%s) to %p (%s)",
1896                    q, info_type(q), to, info_type(to)));
1897     return to;
1898
1899   case FETCH_ME_BQ:
1900     ASSERT(sizeofW(StgBlockedFetch) >= MIN_UPD_SIZE);
1901     to = copy(q,sizeofW(StgFetchMeBlockingQueue),stp);
1902     IF_DEBUG(gc,
1903              belch("@@ evacuate: %p (%s) to %p (%s)",
1904                    q, info_type(q), to, info_type(to)));
1905     return to;
1906 #endif
1907
1908   default:
1909     barf("evacuate: strange closure type %d", (int)(info->type));
1910   }
1911
1912   barf("evacuate");
1913 }
1914
1915 /* -----------------------------------------------------------------------------
1916    Evaluate a THUNK_SELECTOR if possible.
1917
1918    returns: NULL if we couldn't evaluate this THUNK_SELECTOR, or
1919    a closure pointer if we evaluated it and this is the result
1920
1921    If the return value is non-NULL, the original selector thunk has
1922    been BLACKHOLE'd, and should be updated with an indirection or a
1923    forwarding pointer.  If the return value is NULL, then the selector
1924    thunk is unchanged.
1925    -------------------------------------------------------------------------- */
1926
1927 static StgClosure *
1928 eval_thunk_selector( nat field, StgSelector * p )
1929 {
1930     StgInfoTable *info;
1931     const StgInfoTable *info_ptr;
1932     StgClosure *selectee;
1933
1934     selectee = p->selectee;
1935
1936     // Save the real info pointer (NOTE: not the same as get_itbl()).
1937     info_ptr = p->header.info;
1938
1939     // BLACKHOLE the selector thunk, since it is now under evaluation.
1940     // This is important to stop us going into an infinite loop if
1941     // this selector thunk eventually refers to itself.
1942     SET_INFO(p,&stg_BLACKHOLE_info);
1943
1944 selector_loop:
1945     info = get_itbl(selectee);
1946     switch (info->type) {
1947       case CONSTR:
1948       case CONSTR_1_0:
1949       case CONSTR_0_1:
1950       case CONSTR_2_0:
1951       case CONSTR_1_1:
1952       case CONSTR_0_2:
1953       case CONSTR_STATIC:
1954       case CONSTR_NOCAF_STATIC:
1955           // check that the size is in range 
1956           ASSERT(field <  (StgWord32)(info->layout.payload.ptrs + 
1957                                       info->layout.payload.nptrs));
1958           
1959           return selectee->payload[field];
1960
1961       case IND:
1962       case IND_STATIC:
1963       case IND_PERM:
1964       case IND_OLDGEN:
1965       case IND_OLDGEN_PERM:
1966           selectee = ((StgInd *)selectee)->indirectee;
1967           goto selector_loop;
1968
1969       case EVACUATED:
1970           // We don't follow pointers into to-space; the constructor
1971           // has already been evacuated, so we won't save any space
1972           // leaks by evaluating this selector thunk anyhow.
1973           break;
1974
1975       case THUNK_SELECTOR:
1976       {
1977           StgClosure *val;
1978
1979           // check that we don't recurse too much, re-using the
1980           // depth bound also used in evacuate().
1981           thunk_selector_depth++;
1982           if (thunk_selector_depth > MAX_THUNK_SELECTOR_DEPTH) {
1983               break;
1984           }
1985
1986           val = eval_thunk_selector(info->layout.selector_offset, 
1987                                     (StgSelector *)selectee);
1988
1989           thunk_selector_depth--;
1990
1991           if (val == NULL) { 
1992               break;
1993           } else {
1994               // we evaluated this selector thunk, so update it with
1995               // an indirection.
1996               UPD_IND_NOLOCK(selectee, val);
1997               selectee = val;
1998               goto selector_loop;
1999           }
2000       }
2001
2002       case AP_UPD:
2003       case THUNK:
2004       case THUNK_1_0:
2005       case THUNK_0_1:
2006       case THUNK_2_0:
2007       case THUNK_1_1:
2008       case THUNK_0_2:
2009       case THUNK_STATIC:
2010       case CAF_BLACKHOLE:
2011       case SE_CAF_BLACKHOLE:
2012       case SE_BLACKHOLE:
2013       case BLACKHOLE:
2014       case BLACKHOLE_BQ:
2015 #if defined(PAR)
2016       case RBH:
2017       case BLOCKED_FETCH:
2018 # ifdef DIST    
2019       case REMOTE_REF:
2020 # endif
2021       case FETCH_ME:
2022       case FETCH_ME_BQ:
2023 #endif
2024           // not evaluated yet 
2025           break;
2026     
2027       default:
2028         barf("eval_thunk_selector: strange selectee %d",
2029              (int)(info->type));
2030     }
2031
2032     // We didn't manage to evaluate this thunk; restore the old info pointer
2033     SET_INFO(p, info_ptr);
2034     return NULL;
2035 }
2036
2037 /* -----------------------------------------------------------------------------
2038    move_TSO is called to update the TSO structure after it has been
2039    moved from one place to another.
2040    -------------------------------------------------------------------------- */
2041
2042 void
2043 move_TSO(StgTSO *src, StgTSO *dest)
2044 {
2045     ptrdiff_t diff;
2046
2047     // relocate the stack pointers... 
2048     diff = (StgPtr)dest - (StgPtr)src; // In *words* 
2049     dest->sp = (StgPtr)dest->sp + diff;
2050     dest->su = (StgUpdateFrame *) ((P_)dest->su + diff);
2051
2052     relocate_stack(dest, diff);
2053 }
2054
2055 /* -----------------------------------------------------------------------------
2056    relocate_stack is called to update the linkage between
2057    UPDATE_FRAMEs (and SEQ_FRAMEs etc.) when a stack is moved from one
2058    place to another.
2059    -------------------------------------------------------------------------- */
2060
2061 StgTSO *
2062 relocate_stack(StgTSO *dest, ptrdiff_t diff)
2063 {
2064   StgUpdateFrame *su;
2065   StgCatchFrame  *cf;
2066   StgSeqFrame    *sf;
2067
2068   su = dest->su;
2069
2070   while ((P_)su < dest->stack + dest->stack_size) {
2071     switch (get_itbl(su)->type) {
2072    
2073       // GCC actually manages to common up these three cases! 
2074
2075     case UPDATE_FRAME:
2076       su->link = (StgUpdateFrame *) ((StgPtr)su->link + diff);
2077       su = su->link;
2078       continue;
2079
2080     case CATCH_FRAME:
2081       cf = (StgCatchFrame *)su;
2082       cf->link = (StgUpdateFrame *) ((StgPtr)cf->link + diff);
2083       su = cf->link;
2084       continue;
2085
2086     case SEQ_FRAME:
2087       sf = (StgSeqFrame *)su;
2088       sf->link = (StgUpdateFrame *) ((StgPtr)sf->link + diff);
2089       su = sf->link;
2090       continue;
2091
2092     case STOP_FRAME:
2093       // all done! 
2094       break;
2095
2096     default:
2097       barf("relocate_stack %d", (int)(get_itbl(su)->type));
2098     }
2099     break;
2100   }
2101
2102   return dest;
2103 }
2104
2105
2106
2107 static inline void
2108 scavenge_srt(const StgInfoTable *info)
2109 {
2110   StgClosure **srt, **srt_end;
2111
2112   /* evacuate the SRT.  If srt_len is zero, then there isn't an
2113    * srt field in the info table.  That's ok, because we'll
2114    * never dereference it.
2115    */
2116   srt = (StgClosure **)(info->srt);
2117   srt_end = srt + info->srt_len;
2118   for (; srt < srt_end; srt++) {
2119     /* Special-case to handle references to closures hiding out in DLLs, since
2120        double indirections required to get at those. The code generator knows
2121        which is which when generating the SRT, so it stores the (indirect)
2122        reference to the DLL closure in the table by first adding one to it.
2123        We check for this here, and undo the addition before evacuating it.
2124
2125        If the SRT entry hasn't got bit 0 set, the SRT entry points to a
2126        closure that's fixed at link-time, and no extra magic is required.
2127     */
2128 #ifdef ENABLE_WIN32_DLL_SUPPORT
2129     if ( (unsigned long)(*srt) & 0x1 ) {
2130        evacuate(*stgCast(StgClosure**,(stgCast(unsigned long, *srt) & ~0x1)));
2131     } else {
2132        evacuate(*srt);
2133     }
2134 #else
2135        evacuate(*srt);
2136 #endif
2137   }
2138 }
2139
2140 /* -----------------------------------------------------------------------------
2141    Scavenge a TSO.
2142    -------------------------------------------------------------------------- */
2143
2144 static void
2145 scavengeTSO (StgTSO *tso)
2146 {
2147   // chase the link field for any TSOs on the same queue 
2148   (StgClosure *)tso->link = evacuate((StgClosure *)tso->link);
2149   if (   tso->why_blocked == BlockedOnMVar
2150          || tso->why_blocked == BlockedOnBlackHole
2151          || tso->why_blocked == BlockedOnException
2152 #if defined(PAR)
2153          || tso->why_blocked == BlockedOnGA
2154          || tso->why_blocked == BlockedOnGA_NoSend
2155 #endif
2156          ) {
2157     tso->block_info.closure = evacuate(tso->block_info.closure);
2158   }
2159   if ( tso->blocked_exceptions != NULL ) {
2160     tso->blocked_exceptions = 
2161       (StgTSO *)evacuate((StgClosure *)tso->blocked_exceptions);
2162   }
2163   // scavenge this thread's stack 
2164   scavenge_stack(tso->sp, &(tso->stack[tso->stack_size]));
2165 }
2166
2167 /* -----------------------------------------------------------------------------
2168    Scavenge a given step until there are no more objects in this step
2169    to scavenge.
2170
2171    evac_gen is set by the caller to be either zero (for a step in a
2172    generation < N) or G where G is the generation of the step being
2173    scavenged.  
2174
2175    We sometimes temporarily change evac_gen back to zero if we're
2176    scavenging a mutable object where early promotion isn't such a good
2177    idea.  
2178    -------------------------------------------------------------------------- */
2179
2180 static void
2181 scavenge(step *stp)
2182 {
2183   StgPtr p, q;
2184   StgInfoTable *info;
2185   bdescr *bd;
2186   nat saved_evac_gen = evac_gen;
2187
2188   p = stp->scan;
2189   bd = stp->scan_bd;
2190
2191   failed_to_evac = rtsFalse;
2192
2193   /* scavenge phase - standard breadth-first scavenging of the
2194    * evacuated objects 
2195    */
2196
2197   while (bd != stp->hp_bd || p < stp->hp) {
2198
2199     // If we're at the end of this block, move on to the next block 
2200     if (bd != stp->hp_bd && p == bd->free) {
2201       bd = bd->link;
2202       p = bd->start;
2203       continue;
2204     }
2205
2206     info = get_itbl((StgClosure *)p);
2207     ASSERT(p && (LOOKS_LIKE_GHC_INFO(info) || IS_HUGS_CONSTR_INFO(info)));
2208     
2209     ASSERT(thunk_selector_depth == 0);
2210
2211     q = p;
2212     switch (info->type) {
2213         
2214     case MVAR:
2215         /* treat MVars specially, because we don't want to evacuate the
2216          * mut_link field in the middle of the closure.
2217          */
2218     { 
2219         StgMVar *mvar = ((StgMVar *)p);
2220         evac_gen = 0;
2221         (StgClosure *)mvar->head = evacuate((StgClosure *)mvar->head);
2222         (StgClosure *)mvar->tail = evacuate((StgClosure *)mvar->tail);
2223         (StgClosure *)mvar->value = evacuate((StgClosure *)mvar->value);
2224         evac_gen = saved_evac_gen;
2225         recordMutable((StgMutClosure *)mvar);
2226         failed_to_evac = rtsFalse; // mutable.
2227         p += sizeofW(StgMVar);
2228         break;
2229     }
2230
2231     case THUNK_2_0:
2232     case FUN_2_0:
2233         scavenge_srt(info);
2234     case CONSTR_2_0:
2235         ((StgClosure *)p)->payload[1] = evacuate(((StgClosure *)p)->payload[1]);
2236         ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
2237         p += sizeofW(StgHeader) + 2;
2238         break;
2239         
2240     case THUNK_1_0:
2241         scavenge_srt(info);
2242         ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
2243         p += sizeofW(StgHeader) + 2; // MIN_UPD_SIZE 
2244         break;
2245         
2246     case FUN_1_0:
2247         scavenge_srt(info);
2248     case CONSTR_1_0:
2249         ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
2250         p += sizeofW(StgHeader) + 1;
2251         break;
2252         
2253     case THUNK_0_1:
2254         scavenge_srt(info);
2255         p += sizeofW(StgHeader) + 2; // MIN_UPD_SIZE 
2256         break;
2257         
2258     case FUN_0_1:
2259         scavenge_srt(info);
2260     case CONSTR_0_1:
2261         p += sizeofW(StgHeader) + 1;
2262         break;
2263         
2264     case THUNK_0_2:
2265     case FUN_0_2:
2266         scavenge_srt(info);
2267     case CONSTR_0_2:
2268         p += sizeofW(StgHeader) + 2;
2269         break;
2270         
2271     case THUNK_1_1:
2272     case FUN_1_1:
2273         scavenge_srt(info);
2274     case CONSTR_1_1:
2275         ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
2276         p += sizeofW(StgHeader) + 2;
2277         break;
2278         
2279     case FUN:
2280     case THUNK:
2281         scavenge_srt(info);
2282         // fall through 
2283         
2284     case CONSTR:
2285     case WEAK:
2286     case FOREIGN:
2287     case STABLE_NAME:
2288     case BCO:
2289     {
2290         StgPtr end;
2291
2292         end = (P_)((StgClosure *)p)->payload + info->layout.payload.ptrs;
2293         for (p = (P_)((StgClosure *)p)->payload; p < end; p++) {
2294             (StgClosure *)*p = evacuate((StgClosure *)*p);
2295         }
2296         p += info->layout.payload.nptrs;
2297         break;
2298     }
2299
2300     case IND_PERM:
2301       if (stp->gen->no != 0) {
2302 #ifdef PROFILING
2303         // @LDV profiling
2304         // No need to call LDV_recordDead_FILL_SLOP_DYNAMIC() because an 
2305         // IND_OLDGEN_PERM closure is larger than an IND_PERM closure.
2306         LDV_recordDead((StgClosure *)p, sizeofW(StgInd));
2307 #endif        
2308         // 
2309         // Todo: maybe use SET_HDR() and remove LDV_recordCreate()?
2310         //
2311         SET_INFO(((StgClosure *)p), &stg_IND_OLDGEN_PERM_info);
2312 #ifdef PROFILING
2313         // @LDV profiling
2314         // We pretend that p has just been created.
2315         LDV_recordCreate((StgClosure *)p);
2316 #endif
2317       }
2318         // fall through 
2319     case IND_OLDGEN_PERM:
2320         ((StgIndOldGen *)p)->indirectee = 
2321             evacuate(((StgIndOldGen *)p)->indirectee);
2322         if (failed_to_evac) {
2323             failed_to_evac = rtsFalse;
2324             recordOldToNewPtrs((StgMutClosure *)p);
2325         }
2326         p += sizeofW(StgIndOldGen);
2327         break;
2328
2329     case MUT_VAR:
2330         evac_gen = 0;
2331         ((StgMutVar *)p)->var = evacuate(((StgMutVar *)p)->var);
2332         evac_gen = saved_evac_gen;
2333         recordMutable((StgMutClosure *)p);
2334         failed_to_evac = rtsFalse; // mutable anyhow
2335         p += sizeofW(StgMutVar);
2336         break;
2337
2338     case MUT_CONS:
2339         // ignore these
2340         failed_to_evac = rtsFalse; // mutable anyhow
2341         p += sizeofW(StgMutVar);
2342         break;
2343
2344     case CAF_BLACKHOLE:
2345     case SE_CAF_BLACKHOLE:
2346     case SE_BLACKHOLE:
2347     case BLACKHOLE:
2348         p += BLACKHOLE_sizeW();
2349         break;
2350
2351     case BLACKHOLE_BQ:
2352     { 
2353         StgBlockingQueue *bh = (StgBlockingQueue *)p;
2354         (StgClosure *)bh->blocking_queue = 
2355             evacuate((StgClosure *)bh->blocking_queue);
2356         recordMutable((StgMutClosure *)bh);
2357         failed_to_evac = rtsFalse;
2358         p += BLACKHOLE_sizeW();
2359         break;
2360     }
2361
2362     case THUNK_SELECTOR:
2363     { 
2364         StgSelector *s = (StgSelector *)p;
2365         s->selectee = evacuate(s->selectee);
2366         p += THUNK_SELECTOR_sizeW();
2367         break;
2368     }
2369
2370     case AP_UPD: // same as PAPs 
2371     case PAP:
2372         /* Treat a PAP just like a section of stack, not forgetting to
2373          * evacuate the function pointer too...
2374          */
2375     { 
2376         StgPAP* pap = (StgPAP *)p;
2377
2378         pap->fun = evacuate(pap->fun);
2379         scavenge_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
2380         p += pap_sizeW(pap);
2381         break;
2382     }
2383       
2384     case ARR_WORDS:
2385         // nothing to follow 
2386         p += arr_words_sizeW((StgArrWords *)p);
2387         break;
2388
2389     case MUT_ARR_PTRS:
2390         // follow everything 
2391     {
2392         StgPtr next;
2393
2394         evac_gen = 0;           // repeatedly mutable 
2395         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2396         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2397             (StgClosure *)*p = evacuate((StgClosure *)*p);
2398         }
2399         evac_gen = saved_evac_gen;
2400         recordMutable((StgMutClosure *)q);
2401         failed_to_evac = rtsFalse; // mutable anyhow.
2402         break;
2403     }
2404
2405     case MUT_ARR_PTRS_FROZEN:
2406         // follow everything 
2407     {
2408         StgPtr next;
2409
2410         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2411         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2412             (StgClosure *)*p = evacuate((StgClosure *)*p);
2413         }
2414         // it's tempting to recordMutable() if failed_to_evac is
2415         // false, but that breaks some assumptions (eg. every
2416         // closure on the mutable list is supposed to have the MUT
2417         // flag set, and MUT_ARR_PTRS_FROZEN doesn't).
2418         break;
2419     }
2420
2421     case TSO:
2422     { 
2423         StgTSO *tso = (StgTSO *)p;
2424         evac_gen = 0;
2425         scavengeTSO(tso);
2426         evac_gen = saved_evac_gen;
2427         recordMutable((StgMutClosure *)tso);
2428         failed_to_evac = rtsFalse; // mutable anyhow.
2429         p += tso_sizeW(tso);
2430         break;
2431     }
2432
2433 #if defined(PAR)
2434     case RBH: // cf. BLACKHOLE_BQ
2435     { 
2436 #if 0
2437         nat size, ptrs, nonptrs, vhs;
2438         char str[80];
2439         StgInfoTable *rip = get_closure_info(p, &size, &ptrs, &nonptrs, &vhs, str);
2440 #endif
2441         StgRBH *rbh = (StgRBH *)p;
2442         (StgClosure *)rbh->blocking_queue = 
2443             evacuate((StgClosure *)rbh->blocking_queue);
2444         recordMutable((StgMutClosure *)to);
2445         failed_to_evac = rtsFalse;  // mutable anyhow.
2446         IF_DEBUG(gc,
2447                  belch("@@ scavenge: RBH %p (%s) (new blocking_queue link=%p)",
2448                        p, info_type(p), (StgClosure *)rbh->blocking_queue));
2449         // ToDo: use size of reverted closure here!
2450         p += BLACKHOLE_sizeW(); 
2451         break;
2452     }
2453
2454     case BLOCKED_FETCH:
2455     { 
2456         StgBlockedFetch *bf = (StgBlockedFetch *)p;
2457         // follow the pointer to the node which is being demanded 
2458         (StgClosure *)bf->node = 
2459             evacuate((StgClosure *)bf->node);
2460         // follow the link to the rest of the blocking queue 
2461         (StgClosure *)bf->link = 
2462             evacuate((StgClosure *)bf->link);
2463         if (failed_to_evac) {
2464             failed_to_evac = rtsFalse;
2465             recordMutable((StgMutClosure *)bf);
2466         }
2467         IF_DEBUG(gc,
2468                  belch("@@ scavenge: %p (%s); node is now %p; exciting, isn't it",
2469                        bf, info_type((StgClosure *)bf), 
2470                        bf->node, info_type(bf->node)));
2471         p += sizeofW(StgBlockedFetch);
2472         break;
2473     }
2474
2475 #ifdef DIST
2476     case REMOTE_REF:
2477 #endif
2478     case FETCH_ME:
2479         p += sizeofW(StgFetchMe);
2480         break; // nothing to do in this case
2481
2482     case FETCH_ME_BQ: // cf. BLACKHOLE_BQ
2483     { 
2484         StgFetchMeBlockingQueue *fmbq = (StgFetchMeBlockingQueue *)p;
2485         (StgClosure *)fmbq->blocking_queue = 
2486             evacuate((StgClosure *)fmbq->blocking_queue);
2487         if (failed_to_evac) {
2488             failed_to_evac = rtsFalse;
2489             recordMutable((StgMutClosure *)fmbq);
2490         }
2491         IF_DEBUG(gc,
2492                  belch("@@ scavenge: %p (%s) exciting, isn't it",
2493                        p, info_type((StgClosure *)p)));
2494         p += sizeofW(StgFetchMeBlockingQueue);
2495         break;
2496     }
2497 #endif
2498
2499     default:
2500         barf("scavenge: unimplemented/strange closure type %d @ %p", 
2501              info->type, p);
2502     }
2503
2504     /* If we didn't manage to promote all the objects pointed to by
2505      * the current object, then we have to designate this object as
2506      * mutable (because it contains old-to-new generation pointers).
2507      */
2508     if (failed_to_evac) {
2509         failed_to_evac = rtsFalse;
2510         mkMutCons((StgClosure *)q, &generations[evac_gen]);
2511     }
2512   }
2513
2514   stp->scan_bd = bd;
2515   stp->scan = p;
2516 }    
2517
2518 /* -----------------------------------------------------------------------------
2519    Scavenge everything on the mark stack.
2520
2521    This is slightly different from scavenge():
2522       - we don't walk linearly through the objects, so the scavenger
2523         doesn't need to advance the pointer on to the next object.
2524    -------------------------------------------------------------------------- */
2525
2526 static void
2527 scavenge_mark_stack(void)
2528 {
2529     StgPtr p, q;
2530     StgInfoTable *info;
2531     nat saved_evac_gen;
2532
2533     evac_gen = oldest_gen->no;
2534     saved_evac_gen = evac_gen;
2535
2536 linear_scan:
2537     while (!mark_stack_empty()) {
2538         p = pop_mark_stack();
2539
2540         info = get_itbl((StgClosure *)p);
2541         ASSERT(p && (LOOKS_LIKE_GHC_INFO(info) || IS_HUGS_CONSTR_INFO(info)));
2542         
2543         q = p;
2544         switch (info->type) {
2545             
2546         case MVAR:
2547             /* treat MVars specially, because we don't want to evacuate the
2548              * mut_link field in the middle of the closure.
2549              */
2550         {
2551             StgMVar *mvar = ((StgMVar *)p);
2552             evac_gen = 0;
2553             (StgClosure *)mvar->head = evacuate((StgClosure *)mvar->head);
2554             (StgClosure *)mvar->tail = evacuate((StgClosure *)mvar->tail);
2555             (StgClosure *)mvar->value = evacuate((StgClosure *)mvar->value);
2556             evac_gen = saved_evac_gen;
2557             failed_to_evac = rtsFalse; // mutable.
2558             break;
2559         }
2560
2561         case FUN_2_0:
2562         case THUNK_2_0:
2563             scavenge_srt(info);
2564         case CONSTR_2_0:
2565             ((StgClosure *)p)->payload[1] = evacuate(((StgClosure *)p)->payload[1]);
2566             ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
2567             break;
2568         
2569         case FUN_1_0:
2570         case FUN_1_1:
2571         case THUNK_1_0:
2572         case THUNK_1_1:
2573             scavenge_srt(info);
2574         case CONSTR_1_0:
2575         case CONSTR_1_1:
2576             ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]);
2577             break;
2578         
2579         case FUN_0_1:
2580         case FUN_0_2:
2581         case THUNK_0_1:
2582         case THUNK_0_2:
2583             scavenge_srt(info);
2584         case CONSTR_0_1:
2585         case CONSTR_0_2:
2586             break;
2587         
2588         case FUN:
2589         case THUNK:
2590             scavenge_srt(info);
2591             // fall through 
2592         
2593         case CONSTR:
2594         case WEAK:
2595         case FOREIGN:
2596         case STABLE_NAME:
2597         case BCO:
2598         {
2599             StgPtr end;
2600             
2601             end = (P_)((StgClosure *)p)->payload + info->layout.payload.ptrs;
2602             for (p = (P_)((StgClosure *)p)->payload; p < end; p++) {
2603                 (StgClosure *)*p = evacuate((StgClosure *)*p);
2604             }
2605             break;
2606         }
2607
2608         case IND_PERM:
2609             // don't need to do anything here: the only possible case
2610             // is that we're in a 1-space compacting collector, with
2611             // no "old" generation.
2612             break;
2613
2614         case IND_OLDGEN:
2615         case IND_OLDGEN_PERM:
2616             ((StgIndOldGen *)p)->indirectee = 
2617                 evacuate(((StgIndOldGen *)p)->indirectee);
2618             if (failed_to_evac) {
2619                 recordOldToNewPtrs((StgMutClosure *)p);
2620             }
2621             failed_to_evac = rtsFalse;
2622             break;
2623
2624         case MUT_VAR:
2625             evac_gen = 0;
2626             ((StgMutVar *)p)->var = evacuate(((StgMutVar *)p)->var);
2627             evac_gen = saved_evac_gen;
2628             failed_to_evac = rtsFalse;
2629             break;
2630
2631         case MUT_CONS:
2632             // ignore these
2633             failed_to_evac = rtsFalse;
2634             break;
2635
2636         case CAF_BLACKHOLE:
2637         case SE_CAF_BLACKHOLE:
2638         case SE_BLACKHOLE:
2639         case BLACKHOLE:
2640         case ARR_WORDS:
2641             break;
2642
2643         case BLACKHOLE_BQ:
2644         { 
2645             StgBlockingQueue *bh = (StgBlockingQueue *)p;
2646             (StgClosure *)bh->blocking_queue = 
2647                 evacuate((StgClosure *)bh->blocking_queue);
2648             failed_to_evac = rtsFalse;
2649             break;
2650         }
2651
2652         case THUNK_SELECTOR:
2653         { 
2654             StgSelector *s = (StgSelector *)p;
2655             s->selectee = evacuate(s->selectee);
2656             break;
2657         }
2658
2659         case AP_UPD: // same as PAPs 
2660         case PAP:
2661             /* Treat a PAP just like a section of stack, not forgetting to
2662              * evacuate the function pointer too...
2663              */
2664         { 
2665             StgPAP* pap = (StgPAP *)p;
2666             
2667             pap->fun = evacuate(pap->fun);
2668             scavenge_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
2669             break;
2670         }
2671       
2672         case MUT_ARR_PTRS:
2673             // follow everything 
2674         {
2675             StgPtr next;
2676             
2677             evac_gen = 0;               // repeatedly mutable 
2678             next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2679             for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2680                 (StgClosure *)*p = evacuate((StgClosure *)*p);
2681             }
2682             evac_gen = saved_evac_gen;
2683             failed_to_evac = rtsFalse; // mutable anyhow.
2684             break;
2685         }
2686
2687         case MUT_ARR_PTRS_FROZEN:
2688             // follow everything 
2689         {
2690             StgPtr next;
2691             
2692             next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2693             for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2694                 (StgClosure *)*p = evacuate((StgClosure *)*p);
2695             }
2696             break;
2697         }
2698
2699         case TSO:
2700         { 
2701             StgTSO *tso = (StgTSO *)p;
2702             evac_gen = 0;
2703             scavengeTSO(tso);
2704             evac_gen = saved_evac_gen;
2705             failed_to_evac = rtsFalse;
2706             break;
2707         }
2708
2709 #if defined(PAR)
2710         case RBH: // cf. BLACKHOLE_BQ
2711         { 
2712 #if 0
2713             nat size, ptrs, nonptrs, vhs;
2714             char str[80];
2715             StgInfoTable *rip = get_closure_info(p, &size, &ptrs, &nonptrs, &vhs, str);
2716 #endif
2717             StgRBH *rbh = (StgRBH *)p;
2718             (StgClosure *)rbh->blocking_queue = 
2719                 evacuate((StgClosure *)rbh->blocking_queue);
2720             recordMutable((StgMutClosure *)rbh);
2721             failed_to_evac = rtsFalse;  // mutable anyhow.
2722             IF_DEBUG(gc,
2723                      belch("@@ scavenge: RBH %p (%s) (new blocking_queue link=%p)",
2724                            p, info_type(p), (StgClosure *)rbh->blocking_queue));
2725             break;
2726         }
2727         
2728         case BLOCKED_FETCH:
2729         { 
2730             StgBlockedFetch *bf = (StgBlockedFetch *)p;
2731             // follow the pointer to the node which is being demanded 
2732             (StgClosure *)bf->node = 
2733                 evacuate((StgClosure *)bf->node);
2734             // follow the link to the rest of the blocking queue 
2735             (StgClosure *)bf->link = 
2736                 evacuate((StgClosure *)bf->link);
2737             if (failed_to_evac) {
2738                 failed_to_evac = rtsFalse;
2739                 recordMutable((StgMutClosure *)bf);
2740             }
2741             IF_DEBUG(gc,
2742                      belch("@@ scavenge: %p (%s); node is now %p; exciting, isn't it",
2743                            bf, info_type((StgClosure *)bf), 
2744                            bf->node, info_type(bf->node)));
2745             break;
2746         }
2747
2748 #ifdef DIST
2749         case REMOTE_REF:
2750 #endif
2751         case FETCH_ME:
2752             break; // nothing to do in this case
2753
2754         case FETCH_ME_BQ: // cf. BLACKHOLE_BQ
2755         { 
2756             StgFetchMeBlockingQueue *fmbq = (StgFetchMeBlockingQueue *)p;
2757             (StgClosure *)fmbq->blocking_queue = 
2758                 evacuate((StgClosure *)fmbq->blocking_queue);
2759             if (failed_to_evac) {
2760                 failed_to_evac = rtsFalse;
2761                 recordMutable((StgMutClosure *)fmbq);
2762             }
2763             IF_DEBUG(gc,
2764                      belch("@@ scavenge: %p (%s) exciting, isn't it",
2765                            p, info_type((StgClosure *)p)));
2766             break;
2767         }
2768 #endif // PAR
2769
2770         default:
2771             barf("scavenge_mark_stack: unimplemented/strange closure type %d @ %p", 
2772                  info->type, p);
2773         }
2774
2775         if (failed_to_evac) {
2776             failed_to_evac = rtsFalse;
2777             mkMutCons((StgClosure *)q, &generations[evac_gen]);
2778         }
2779         
2780         // mark the next bit to indicate "scavenged"
2781         mark(q+1, Bdescr(q));
2782
2783     } // while (!mark_stack_empty())
2784
2785     // start a new linear scan if the mark stack overflowed at some point
2786     if (mark_stack_overflowed && oldgen_scan_bd == NULL) {
2787         IF_DEBUG(gc, belch("scavenge_mark_stack: starting linear scan"));
2788         mark_stack_overflowed = rtsFalse;
2789         oldgen_scan_bd = oldest_gen->steps[0].blocks;
2790         oldgen_scan = oldgen_scan_bd->start;
2791     }
2792
2793     if (oldgen_scan_bd) {
2794         // push a new thing on the mark stack
2795     loop:
2796         // find a closure that is marked but not scavenged, and start
2797         // from there.
2798         while (oldgen_scan < oldgen_scan_bd->free 
2799                && !is_marked(oldgen_scan,oldgen_scan_bd)) {
2800             oldgen_scan++;
2801         }
2802
2803         if (oldgen_scan < oldgen_scan_bd->free) {
2804
2805             // already scavenged?
2806             if (is_marked(oldgen_scan+1,oldgen_scan_bd)) {
2807                 oldgen_scan += sizeofW(StgHeader) + MIN_NONUPD_SIZE;
2808                 goto loop;
2809             }
2810             push_mark_stack(oldgen_scan);
2811             // ToDo: bump the linear scan by the actual size of the object
2812             oldgen_scan += sizeofW(StgHeader) + MIN_NONUPD_SIZE;
2813             goto linear_scan;
2814         }
2815
2816         oldgen_scan_bd = oldgen_scan_bd->link;
2817         if (oldgen_scan_bd != NULL) {
2818             oldgen_scan = oldgen_scan_bd->start;
2819             goto loop;
2820         }
2821     }
2822 }
2823
2824 /* -----------------------------------------------------------------------------
2825    Scavenge one object.
2826
2827    This is used for objects that are temporarily marked as mutable
2828    because they contain old-to-new generation pointers.  Only certain
2829    objects can have this property.
2830    -------------------------------------------------------------------------- */
2831
2832 static rtsBool
2833 scavenge_one(StgPtr p)
2834 {
2835     const StgInfoTable *info;
2836     nat saved_evac_gen = evac_gen;
2837     rtsBool no_luck;
2838     
2839     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO((StgClosure *)p))
2840                  || IS_HUGS_CONSTR_INFO(GET_INFO((StgClosure *)p))));
2841     
2842     info = get_itbl((StgClosure *)p);
2843     
2844     switch (info->type) {
2845         
2846     case FUN:
2847     case FUN_1_0:                       // hardly worth specialising these guys
2848     case FUN_0_1:
2849     case FUN_1_1:
2850     case FUN_0_2:
2851     case FUN_2_0:
2852     case THUNK:
2853     case THUNK_1_0:
2854     case THUNK_0_1:
2855     case THUNK_1_1:
2856     case THUNK_0_2:
2857     case THUNK_2_0:
2858     case CONSTR:
2859     case CONSTR_1_0:
2860     case CONSTR_0_1:
2861     case CONSTR_1_1:
2862     case CONSTR_0_2:
2863     case CONSTR_2_0:
2864     case WEAK:
2865     case FOREIGN:
2866     case IND_PERM:
2867     case IND_OLDGEN_PERM:
2868     {
2869         StgPtr q, end;
2870         
2871         end = (StgPtr)((StgClosure *)p)->payload + info->layout.payload.ptrs;
2872         for (q = (StgPtr)((StgClosure *)p)->payload; q < end; q++) {
2873             (StgClosure *)*q = evacuate((StgClosure *)*q);
2874         }
2875         break;
2876     }
2877     
2878     case CAF_BLACKHOLE:
2879     case SE_CAF_BLACKHOLE:
2880     case SE_BLACKHOLE:
2881     case BLACKHOLE:
2882         break;
2883         
2884     case THUNK_SELECTOR:
2885     { 
2886         StgSelector *s = (StgSelector *)p;
2887         s->selectee = evacuate(s->selectee);
2888         break;
2889     }
2890     
2891     case ARR_WORDS:
2892         // nothing to follow 
2893         break;
2894       
2895     case MUT_ARR_PTRS:
2896     {
2897         // follow everything 
2898         StgPtr next;
2899       
2900         evac_gen = 0;           // repeatedly mutable 
2901         recordMutable((StgMutClosure *)p);
2902         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2903         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2904             (StgClosure *)*p = evacuate((StgClosure *)*p);
2905         }
2906         evac_gen = saved_evac_gen;
2907         failed_to_evac = rtsFalse;
2908         break;
2909     }
2910
2911     case MUT_ARR_PTRS_FROZEN:
2912     {
2913         // follow everything 
2914         StgPtr next;
2915       
2916         next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
2917         for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
2918             (StgClosure *)*p = evacuate((StgClosure *)*p);
2919         }
2920         break;
2921     }
2922
2923     case TSO:
2924     {
2925         StgTSO *tso = (StgTSO *)p;
2926       
2927         evac_gen = 0;           // repeatedly mutable 
2928         scavengeTSO(tso);
2929         recordMutable((StgMutClosure *)tso);
2930         evac_gen = saved_evac_gen;
2931         failed_to_evac = rtsFalse;
2932         break;
2933     }
2934   
2935     case AP_UPD:
2936     case PAP:
2937     { 
2938         StgPAP* pap = (StgPAP *)p;
2939         pap->fun = evacuate(pap->fun);
2940         scavenge_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
2941         break;
2942     }
2943
2944     case IND_OLDGEN:
2945         // This might happen if for instance a MUT_CONS was pointing to a
2946         // THUNK which has since been updated.  The IND_OLDGEN will
2947         // be on the mutable list anyway, so we don't need to do anything
2948         // here.
2949         break;
2950
2951     default:
2952         barf("scavenge_one: strange object %d", (int)(info->type));
2953     }    
2954
2955     no_luck = failed_to_evac;
2956     failed_to_evac = rtsFalse;
2957     return (no_luck);
2958 }
2959
2960 /* -----------------------------------------------------------------------------
2961    Scavenging mutable lists.
2962
2963    We treat the mutable list of each generation > N (i.e. all the
2964    generations older than the one being collected) as roots.  We also
2965    remove non-mutable objects from the mutable list at this point.
2966    -------------------------------------------------------------------------- */
2967
2968 static void
2969 scavenge_mut_once_list(generation *gen)
2970 {
2971   const StgInfoTable *info;
2972   StgMutClosure *p, *next, *new_list;
2973
2974   p = gen->mut_once_list;
2975   new_list = END_MUT_LIST;
2976   next = p->mut_link;
2977
2978   evac_gen = gen->no;
2979   failed_to_evac = rtsFalse;
2980
2981   for (; p != END_MUT_LIST; p = next, next = p->mut_link) {
2982
2983     // make sure the info pointer is into text space 
2984     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
2985                  || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
2986     
2987     info = get_itbl(p);
2988     /*
2989     if (info->type==RBH)
2990       info = REVERT_INFOPTR(info); // if it's an RBH, look at the orig closure
2991     */
2992     switch(info->type) {
2993       
2994     case IND_OLDGEN:
2995     case IND_OLDGEN_PERM:
2996     case IND_STATIC:
2997       /* Try to pull the indirectee into this generation, so we can
2998        * remove the indirection from the mutable list.  
2999        */
3000       ((StgIndOldGen *)p)->indirectee = 
3001         evacuate(((StgIndOldGen *)p)->indirectee);
3002       
3003 #if 0 && defined(DEBUG)
3004       if (RtsFlags.DebugFlags.gc) 
3005       /* Debugging code to print out the size of the thing we just
3006        * promoted 
3007        */
3008       { 
3009         StgPtr start = gen->steps[0].scan;
3010         bdescr *start_bd = gen->steps[0].scan_bd;
3011         nat size = 0;
3012         scavenge(&gen->steps[0]);
3013         if (start_bd != gen->steps[0].scan_bd) {
3014           size += (P_)BLOCK_ROUND_UP(start) - start;
3015           start_bd = start_bd->link;
3016           while (start_bd != gen->steps[0].scan_bd) {
3017             size += BLOCK_SIZE_W;
3018             start_bd = start_bd->link;
3019           }
3020           size += gen->steps[0].scan -
3021             (P_)BLOCK_ROUND_DOWN(gen->steps[0].scan);
3022         } else {
3023           size = gen->steps[0].scan - start;
3024         }
3025         belch("evac IND_OLDGEN: %ld bytes", size * sizeof(W_));
3026       }
3027 #endif
3028
3029       /* failed_to_evac might happen if we've got more than two
3030        * generations, we're collecting only generation 0, the
3031        * indirection resides in generation 2 and the indirectee is
3032        * in generation 1.
3033        */
3034       if (failed_to_evac) {
3035         failed_to_evac = rtsFalse;
3036         p->mut_link = new_list;
3037         new_list = p;
3038       } else {
3039         /* the mut_link field of an IND_STATIC is overloaded as the
3040          * static link field too (it just so happens that we don't need
3041          * both at the same time), so we need to NULL it out when
3042          * removing this object from the mutable list because the static
3043          * link fields are all assumed to be NULL before doing a major
3044          * collection. 
3045          */
3046         p->mut_link = NULL;
3047       }
3048       continue;
3049
3050     case MUT_CONS:
3051         /* MUT_CONS is a kind of MUT_VAR, except it that we try to remove
3052          * it from the mutable list if possible by promoting whatever it
3053          * points to.
3054          */
3055         if (scavenge_one((StgPtr)((StgMutVar *)p)->var)) {
3056             /* didn't manage to promote everything, so put the
3057              * MUT_CONS back on the list.
3058              */
3059             p->mut_link = new_list;
3060             new_list = p;
3061         }
3062         continue;
3063
3064     default:
3065       // shouldn't have anything else on the mutables list 
3066       barf("scavenge_mut_once_list: strange object? %d", (int)(info->type));
3067     }
3068   }
3069
3070   gen->mut_once_list = new_list;
3071 }
3072
3073
3074 static void
3075 scavenge_mutable_list(generation *gen)
3076 {
3077   const StgInfoTable *info;
3078   StgMutClosure *p, *next;
3079
3080   p = gen->saved_mut_list;
3081   next = p->mut_link;
3082
3083   evac_gen = 0;
3084   failed_to_evac = rtsFalse;
3085
3086   for (; p != END_MUT_LIST; p = next, next = p->mut_link) {
3087
3088     // make sure the info pointer is into text space 
3089     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
3090                  || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
3091     
3092     info = get_itbl(p);
3093     /*
3094     if (info->type==RBH)
3095       info = REVERT_INFOPTR(info); // if it's an RBH, look at the orig closure
3096     */
3097     switch(info->type) {
3098       
3099     case MUT_ARR_PTRS:
3100       // follow everything 
3101       p->mut_link = gen->mut_list;
3102       gen->mut_list = p;
3103       {
3104         StgPtr end, q;
3105         
3106         end = (P_)p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
3107         for (q = (P_)((StgMutArrPtrs *)p)->payload; q < end; q++) {
3108           (StgClosure *)*q = evacuate((StgClosure *)*q);
3109         }
3110         continue;
3111       }
3112       
3113       // Happens if a MUT_ARR_PTRS in the old generation is frozen
3114     case MUT_ARR_PTRS_FROZEN:
3115       {
3116         StgPtr end, q;
3117         
3118         evac_gen = gen->no;
3119         end = (P_)p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
3120         for (q = (P_)((StgMutArrPtrs *)p)->payload; q < end; q++) {
3121           (StgClosure *)*q = evacuate((StgClosure *)*q);
3122         }
3123         evac_gen = 0;
3124         p->mut_link = NULL;
3125         if (failed_to_evac) {
3126             failed_to_evac = rtsFalse;
3127             mkMutCons((StgClosure *)p, gen);
3128         }
3129         continue;
3130       }
3131         
3132     case MUT_VAR:
3133         ((StgMutVar *)p)->var = evacuate(((StgMutVar *)p)->var);
3134         p->mut_link = gen->mut_list;
3135         gen->mut_list = p;
3136         continue;
3137
3138     case MVAR:
3139       {
3140         StgMVar *mvar = (StgMVar *)p;
3141         (StgClosure *)mvar->head = evacuate((StgClosure *)mvar->head);
3142         (StgClosure *)mvar->tail = evacuate((StgClosure *)mvar->tail);
3143         (StgClosure *)mvar->value = evacuate((StgClosure *)mvar->value);
3144         p->mut_link = gen->mut_list;
3145         gen->mut_list = p;
3146         continue;
3147       }
3148
3149     case TSO:
3150       { 
3151         StgTSO *tso = (StgTSO *)p;
3152
3153         scavengeTSO(tso);
3154
3155         /* Don't take this TSO off the mutable list - it might still
3156          * point to some younger objects (because we set evac_gen to 0
3157          * above). 
3158          */
3159         tso->mut_link = gen->mut_list;
3160         gen->mut_list = (StgMutClosure *)tso;
3161         continue;
3162       }
3163       
3164     case BLACKHOLE_BQ:
3165       { 
3166         StgBlockingQueue *bh = (StgBlockingQueue *)p;
3167         (StgClosure *)bh->blocking_queue = 
3168           evacuate((StgClosure *)bh->blocking_queue);
3169         p->mut_link = gen->mut_list;
3170         gen->mut_list = p;
3171         continue;
3172       }
3173
3174       /* Happens if a BLACKHOLE_BQ in the old generation is updated: 
3175        */
3176     case IND_OLDGEN:
3177     case IND_OLDGEN_PERM:
3178       /* Try to pull the indirectee into this generation, so we can
3179        * remove the indirection from the mutable list.  
3180        */
3181       evac_gen = gen->no;
3182       ((StgIndOldGen *)p)->indirectee = 
3183         evacuate(((StgIndOldGen *)p)->indirectee);
3184       evac_gen = 0;
3185
3186       if (failed_to_evac) {
3187         failed_to_evac = rtsFalse;
3188         p->mut_link = gen->mut_once_list;
3189         gen->mut_once_list = p;
3190       } else {
3191         p->mut_link = NULL;
3192       }
3193       continue;
3194
3195 #if defined(PAR)
3196     // HWL: check whether all of these are necessary
3197
3198     case RBH: // cf. BLACKHOLE_BQ
3199       { 
3200         // nat size, ptrs, nonptrs, vhs;
3201         // char str[80];
3202         // StgInfoTable *rip = get_closure_info(p, &size, &ptrs, &nonptrs, &vhs, str);
3203         StgRBH *rbh = (StgRBH *)p;
3204         (StgClosure *)rbh->blocking_queue = 
3205           evacuate((StgClosure *)rbh->blocking_queue);
3206         if (failed_to_evac) {
3207           failed_to_evac = rtsFalse;
3208           recordMutable((StgMutClosure *)rbh);
3209         }
3210         // ToDo: use size of reverted closure here!
3211         p += BLACKHOLE_sizeW(); 
3212         break;
3213       }
3214
3215     case BLOCKED_FETCH:
3216       { 
3217         StgBlockedFetch *bf = (StgBlockedFetch *)p;
3218         // follow the pointer to the node which is being demanded 
3219         (StgClosure *)bf->node = 
3220           evacuate((StgClosure *)bf->node);
3221         // follow the link to the rest of the blocking queue 
3222         (StgClosure *)bf->link = 
3223           evacuate((StgClosure *)bf->link);
3224         if (failed_to_evac) {
3225           failed_to_evac = rtsFalse;
3226           recordMutable((StgMutClosure *)bf);
3227         }
3228         p += sizeofW(StgBlockedFetch);
3229         break;
3230       }
3231
3232 #ifdef DIST
3233     case REMOTE_REF:
3234       barf("scavenge_mutable_list: REMOTE_REF %d", (int)(info->type));
3235 #endif
3236     case FETCH_ME:
3237       p += sizeofW(StgFetchMe);
3238       break; // nothing to do in this case
3239
3240     case FETCH_ME_BQ: // cf. BLACKHOLE_BQ
3241       { 
3242         StgFetchMeBlockingQueue *fmbq = (StgFetchMeBlockingQueue *)p;
3243         (StgClosure *)fmbq->blocking_queue = 
3244           evacuate((StgClosure *)fmbq->blocking_queue);
3245         if (failed_to_evac) {
3246           failed_to_evac = rtsFalse;
3247           recordMutable((StgMutClosure *)fmbq);
3248         }
3249         p += sizeofW(StgFetchMeBlockingQueue);
3250         break;
3251       }
3252 #endif
3253
3254     default:
3255       // shouldn't have anything else on the mutables list 
3256       barf("scavenge_mutable_list: strange object? %d", (int)(info->type));
3257     }
3258   }
3259 }
3260
3261
3262 static void
3263 scavenge_static(void)
3264 {
3265   StgClosure* p = static_objects;
3266   const StgInfoTable *info;
3267
3268   /* Always evacuate straight to the oldest generation for static
3269    * objects */
3270   evac_gen = oldest_gen->no;
3271
3272   /* keep going until we've scavenged all the objects on the linked
3273      list... */
3274   while (p != END_OF_STATIC_LIST) {
3275
3276     info = get_itbl(p);
3277     /*
3278     if (info->type==RBH)
3279       info = REVERT_INFOPTR(info); // if it's an RBH, look at the orig closure
3280     */
3281     // make sure the info pointer is into text space 
3282     ASSERT(p && (LOOKS_LIKE_GHC_INFO(GET_INFO(p))
3283                  || IS_HUGS_CONSTR_INFO(GET_INFO(p))));
3284     
3285     /* Take this object *off* the static_objects list,
3286      * and put it on the scavenged_static_objects list.
3287      */
3288     static_objects = STATIC_LINK(info,p);
3289     STATIC_LINK(info,p) = scavenged_static_objects;
3290     scavenged_static_objects = p;
3291     
3292     switch (info -> type) {
3293       
3294     case IND_STATIC:
3295       {
3296         StgInd *ind = (StgInd *)p;
3297         ind->indirectee = evacuate(ind->indirectee);
3298
3299         /* might fail to evacuate it, in which case we have to pop it
3300          * back on the mutable list (and take it off the
3301          * scavenged_static list because the static link and mut link
3302          * pointers are one and the same).
3303          */
3304         if (failed_to_evac) {
3305           failed_to_evac = rtsFalse;
3306           scavenged_static_objects = IND_STATIC_LINK(p);
3307           ((StgMutClosure *)ind)->mut_link = oldest_gen->mut_once_list;
3308           oldest_gen->mut_once_list = (StgMutClosure *)ind;
3309         }
3310         break;
3311       }
3312       
3313     case THUNK_STATIC:
3314     case FUN_STATIC:
3315       scavenge_srt(info);
3316       break;
3317       
3318     case CONSTR_STATIC:
3319       { 
3320         StgPtr q, next;
3321         
3322         next = (P_)p->payload + info->layout.payload.ptrs;
3323         // evacuate the pointers 
3324         for (q = (P_)p->payload; q < next; q++) {
3325           (StgClosure *)*q = evacuate((StgClosure *)*q);
3326         }
3327         break;
3328       }
3329       
3330     default:
3331       barf("scavenge_static: strange closure %d", (int)(info->type));
3332     }
3333
3334     ASSERT(failed_to_evac == rtsFalse);
3335
3336     /* get the next static object from the list.  Remember, there might
3337      * be more stuff on this list now that we've done some evacuating!
3338      * (static_objects is a global)
3339      */
3340     p = static_objects;
3341   }
3342 }
3343
3344 /* -----------------------------------------------------------------------------
3345    scavenge_stack walks over a section of stack and evacuates all the
3346    objects pointed to by it.  We can use the same code for walking
3347    PAPs, since these are just sections of copied stack.
3348    -------------------------------------------------------------------------- */
3349
3350 static void
3351 scavenge_stack(StgPtr p, StgPtr stack_end)
3352 {
3353   StgPtr q;
3354   const StgInfoTable* info;
3355   StgWord bitmap;
3356
3357   //IF_DEBUG(sanity, belch("  scavenging stack between %p and %p", p, stack_end));
3358
3359   /* 
3360    * Each time around this loop, we are looking at a chunk of stack
3361    * that starts with either a pending argument section or an 
3362    * activation record. 
3363    */
3364
3365   while (p < stack_end) {
3366     q = *(P_ *)p;
3367
3368     // If we've got a tag, skip over that many words on the stack 
3369     if (IS_ARG_TAG((W_)q)) {
3370       p += ARG_SIZE(q);
3371       p++; continue;
3372     }
3373      
3374     /* Is q a pointer to a closure?
3375      */
3376     if (! LOOKS_LIKE_GHC_INFO(q) ) {
3377 #ifdef DEBUG
3378       if ( 0 && LOOKS_LIKE_STATIC_CLOSURE(q) ) {  // Is it a static closure? 
3379         ASSERT(closure_STATIC((StgClosure *)q));
3380       }
3381       // otherwise, must be a pointer into the allocation space. 
3382 #endif
3383
3384       (StgClosure *)*p = evacuate((StgClosure *)q);
3385       p++; 
3386       continue;
3387     }
3388       
3389     /* 
3390      * Otherwise, q must be the info pointer of an activation
3391      * record.  All activation records have 'bitmap' style layout
3392      * info.
3393      */
3394     info  = get_itbl((StgClosure *)p);
3395       
3396     switch (info->type) {
3397         
3398       // Dynamic bitmap: the mask is stored on the stack 
3399     case RET_DYN:
3400       bitmap = ((StgRetDyn *)p)->liveness;
3401       p      = (P_)&((StgRetDyn *)p)->payload[0];
3402       goto small_bitmap;
3403
3404       // probably a slow-entry point return address: 
3405     case FUN:
3406     case FUN_STATIC:
3407       {
3408 #if 0   
3409         StgPtr old_p = p;
3410         p++; p++; 
3411         IF_DEBUG(sanity, 
3412                  belch("HWL: scavenge_stack: FUN(_STATIC) adjusting p from %p to %p (instead of %p)",
3413                        old_p, p, old_p+1));
3414 #else
3415       p++; // what if FHS!=1 !? -- HWL 
3416 #endif
3417       goto follow_srt;
3418       }
3419
3420       /* Specialised code for update frames, since they're so common.
3421        * We *know* the updatee points to a BLACKHOLE, CAF_BLACKHOLE,
3422        * or BLACKHOLE_BQ, so just inline the code to evacuate it here.  
3423        */
3424     case UPDATE_FRAME:
3425       {
3426         StgUpdateFrame *frame = (StgUpdateFrame *)p;
3427
3428         p += sizeofW(StgUpdateFrame);
3429
3430 #ifndef not_yet
3431         frame->updatee = evacuate(frame->updatee);
3432         continue;
3433 #else // specialised code for update frames, not sure if it's worth it.
3434         StgClosure *to;
3435         nat type = get_itbl(frame->updatee)->type;
3436
3437         if (type == EVACUATED) {
3438           frame->updatee = evacuate(frame->updatee);
3439           continue;
3440         } else {
3441           bdescr *bd = Bdescr((P_)frame->updatee);
3442           step *stp;
3443           if (bd->gen_no > N) { 
3444             if (bd->gen_no < evac_gen) {
3445               failed_to_evac = rtsTrue;
3446             }
3447             continue;
3448           }
3449
3450           // Don't promote blackholes 
3451           stp = bd->step;
3452           if (!(stp->gen_no == 0 && 
3453                 stp->no != 0 &&
3454                 stp->no == stp->gen->n_steps-1)) {
3455             stp = stp->to;
3456           }
3457
3458           switch (type) {
3459           case BLACKHOLE:
3460           case CAF_BLACKHOLE:
3461             to = copyPart(frame->updatee, BLACKHOLE_sizeW(), 
3462                           sizeofW(StgHeader), stp);
3463             frame->updatee = to;
3464             continue;
3465           case BLACKHOLE_BQ:
3466             to = copy(frame->updatee, BLACKHOLE_sizeW(), stp);
3467             frame->updatee = to;
3468             recordMutable((StgMutClosure *)to);
3469             continue;
3470           default:
3471             /* will never be SE_{,CAF_}BLACKHOLE, since we
3472                don't push an update frame for single-entry thunks.  KSW 1999-01. */
3473             barf("scavenge_stack: UPDATE_FRAME updatee");
3474           }
3475         }
3476 #endif
3477       }
3478
3479       // small bitmap (< 32 entries, or 64 on a 64-bit machine) 
3480     case STOP_FRAME:
3481     case CATCH_FRAME:
3482     case SEQ_FRAME:
3483     case RET_BCO:
3484     case RET_SMALL:
3485     case RET_VEC_SMALL:
3486       bitmap = info->layout.bitmap;
3487       p++;
3488       // this assumes that the payload starts immediately after the info-ptr 
3489     small_bitmap:
3490       while (bitmap != 0) {
3491         if ((bitmap & 1) == 0) {
3492           (StgClosure *)*p = evacuate((StgClosure *)*p);
3493         }
3494         p++;
3495         bitmap = bitmap >> 1;
3496       }
3497       
3498     follow_srt:
3499       scavenge_srt(info);
3500       continue;
3501
3502       // large bitmap (> 32 entries, or > 64 on a 64-bit machine) 
3503     case RET_BIG:
3504     case RET_VEC_BIG:
3505       {
3506         StgPtr q;
3507         StgLargeBitmap *large_bitmap;
3508         nat i;
3509
3510         large_bitmap = info->layout.large_bitmap;
3511         p++;
3512
3513         for (i=0; i<large_bitmap->size; i++) {
3514           bitmap = large_bitmap->bitmap[i];
3515           q = p + BITS_IN(W_);
3516           while (bitmap != 0) {
3517             if ((bitmap & 1) == 0) {
3518               (StgClosure *)*p = evacuate((StgClosure *)*p);
3519             }
3520             p++;
3521             bitmap = bitmap >> 1;
3522           }
3523           if (i+1 < large_bitmap->size) {
3524             while (p < q) {
3525               (StgClosure *)*p = evacuate((StgClosure *)*p);
3526               p++;
3527             }
3528           }
3529         }
3530
3531         // and don't forget to follow the SRT 
3532         goto follow_srt;
3533       }
3534
3535     default:
3536       barf("scavenge_stack: weird activation record found on stack: %d", (int)(info->type));
3537     }
3538   }
3539 }
3540
3541 /*-----------------------------------------------------------------------------
3542   scavenge the large object list.
3543
3544   evac_gen set by caller; similar games played with evac_gen as with
3545   scavenge() - see comment at the top of scavenge().  Most large
3546   objects are (repeatedly) mutable, so most of the time evac_gen will
3547   be zero.
3548   --------------------------------------------------------------------------- */
3549
3550 static void
3551 scavenge_large(step *stp)
3552 {
3553   bdescr *bd;
3554   StgPtr p;
3555
3556   bd = stp->new_large_objects;
3557
3558   for (; bd != NULL; bd = stp->new_large_objects) {
3559
3560     /* take this object *off* the large objects list and put it on
3561      * the scavenged large objects list.  This is so that we can
3562      * treat new_large_objects as a stack and push new objects on
3563      * the front when evacuating.
3564      */
3565     stp->new_large_objects = bd->link;
3566     dbl_link_onto(bd, &stp->scavenged_large_objects);
3567
3568     // update the block count in this step.
3569     stp->n_scavenged_large_blocks += bd->blocks;
3570
3571     p = bd->start;
3572     if (scavenge_one(p)) {
3573         mkMutCons((StgClosure *)p, stp->gen);
3574     }
3575   }
3576 }
3577
3578 /* -----------------------------------------------------------------------------
3579    Initialising the static object & mutable lists
3580    -------------------------------------------------------------------------- */
3581
3582 static void
3583 zero_static_object_list(StgClosure* first_static)
3584 {
3585   StgClosure* p;
3586   StgClosure* link;
3587   const StgInfoTable *info;
3588
3589   for (p = first_static; p != END_OF_STATIC_LIST; p = link) {
3590     info = get_itbl(p);
3591     link = STATIC_LINK(info, p);
3592     STATIC_LINK(info,p) = NULL;
3593   }
3594 }
3595
3596 /* This function is only needed because we share the mutable link
3597  * field with the static link field in an IND_STATIC, so we have to
3598  * zero the mut_link field before doing a major GC, which needs the
3599  * static link field.  
3600  *
3601  * It doesn't do any harm to zero all the mutable link fields on the
3602  * mutable list.
3603  */
3604
3605 static void
3606 zero_mutable_list( StgMutClosure *first )
3607 {
3608   StgMutClosure *next, *c;
3609
3610   for (c = first; c != END_MUT_LIST; c = next) {
3611     next = c->mut_link;
3612     c->mut_link = NULL;
3613   }
3614 }
3615
3616 /* -----------------------------------------------------------------------------
3617    Reverting CAFs
3618    -------------------------------------------------------------------------- */
3619
3620 void
3621 revertCAFs( void )
3622 {
3623     StgIndStatic *c;
3624
3625     for (c = (StgIndStatic *)caf_list; c != NULL; 
3626          c = (StgIndStatic *)c->static_link) 
3627     {
3628         c->header.info = c->saved_info;
3629         c->saved_info = NULL;
3630         // could, but not necessary: c->static_link = NULL; 
3631     }
3632     caf_list = NULL;
3633 }
3634
3635 void
3636 markCAFs( evac_fn evac )
3637 {
3638     StgIndStatic *c;
3639
3640     for (c = (StgIndStatic *)caf_list; c != NULL; 
3641          c = (StgIndStatic *)c->static_link) 
3642     {
3643         evac(&c->indirectee);
3644     }
3645 }
3646
3647 /* -----------------------------------------------------------------------------
3648    Sanity code for CAF garbage collection.
3649
3650    With DEBUG turned on, we manage a CAF list in addition to the SRT
3651    mechanism.  After GC, we run down the CAF list and blackhole any
3652    CAFs which have been garbage collected.  This means we get an error
3653    whenever the program tries to enter a garbage collected CAF.
3654
3655    Any garbage collected CAFs are taken off the CAF list at the same
3656    time. 
3657    -------------------------------------------------------------------------- */
3658
3659 #if 0 && defined(DEBUG)
3660
3661 static void
3662 gcCAFs(void)
3663 {
3664   StgClosure*  p;
3665   StgClosure** pp;
3666   const StgInfoTable *info;
3667   nat i;
3668
3669   i = 0;
3670   p = caf_list;
3671   pp = &caf_list;
3672
3673   while (p != NULL) {
3674     
3675     info = get_itbl(p);
3676
3677     ASSERT(info->type == IND_STATIC);
3678
3679     if (STATIC_LINK(info,p) == NULL) {
3680       IF_DEBUG(gccafs, belch("CAF gc'd at 0x%04lx", (long)p));
3681       // black hole it 
3682       SET_INFO(p,&stg_BLACKHOLE_info);
3683       p = STATIC_LINK2(info,p);
3684       *pp = p;
3685     }
3686     else {
3687       pp = &STATIC_LINK2(info,p);
3688       p = *pp;
3689       i++;
3690     }
3691
3692   }
3693
3694   //  belch("%d CAFs live", i); 
3695 }
3696 #endif
3697
3698
3699 /* -----------------------------------------------------------------------------
3700    Lazy black holing.
3701
3702    Whenever a thread returns to the scheduler after possibly doing
3703    some work, we have to run down the stack and black-hole all the
3704    closures referred to by update frames.
3705    -------------------------------------------------------------------------- */
3706
3707 static void
3708 threadLazyBlackHole(StgTSO *tso)
3709 {
3710   StgUpdateFrame *update_frame;
3711   StgBlockingQueue *bh;
3712   StgPtr stack_end;
3713
3714   stack_end = &tso->stack[tso->stack_size];
3715   update_frame = tso->su;
3716
3717   while (1) {
3718     switch (get_itbl(update_frame)->type) {
3719
3720     case CATCH_FRAME:
3721       update_frame = ((StgCatchFrame *)update_frame)->link;
3722       break;
3723
3724     case UPDATE_FRAME:
3725       bh = (StgBlockingQueue *)update_frame->updatee;
3726
3727       /* if the thunk is already blackholed, it means we've also
3728        * already blackholed the rest of the thunks on this stack,
3729        * so we can stop early.
3730        *
3731        * The blackhole made for a CAF is a CAF_BLACKHOLE, so they
3732        * don't interfere with this optimisation.
3733        */
3734       if (bh->header.info == &stg_BLACKHOLE_info) {
3735         return;
3736       }
3737
3738       if (bh->header.info != &stg_BLACKHOLE_BQ_info &&
3739           bh->header.info != &stg_CAF_BLACKHOLE_info) {
3740 #if (!defined(LAZY_BLACKHOLING)) && defined(DEBUG)
3741         belch("Unexpected lazy BHing required at 0x%04x",(int)bh);
3742 #endif
3743 #ifdef PROFILING
3744         // @LDV profiling
3745         // We pretend that bh is now dead.
3746         LDV_recordDead_FILL_SLOP_DYNAMIC((StgClosure *)bh);
3747 #endif
3748         SET_INFO(bh,&stg_BLACKHOLE_info);
3749 #ifdef PROFILING
3750         // @LDV profiling
3751         // We pretend that bh has just been created.
3752         LDV_recordCreate(bh);
3753 #endif
3754       }
3755
3756       update_frame = update_frame->link;
3757       break;
3758
3759     case SEQ_FRAME:
3760       update_frame = ((StgSeqFrame *)update_frame)->link;
3761       break;
3762
3763     case STOP_FRAME:
3764       return;
3765     default:
3766       barf("threadPaused");
3767     }
3768   }
3769 }
3770
3771
3772 /* -----------------------------------------------------------------------------
3773  * Stack squeezing
3774  *
3775  * Code largely pinched from old RTS, then hacked to bits.  We also do
3776  * lazy black holing here.
3777  *
3778  * -------------------------------------------------------------------------- */
3779
3780 static void
3781 threadSqueezeStack(StgTSO *tso)
3782 {
3783   lnat displacement = 0;
3784   StgUpdateFrame *frame;
3785   StgUpdateFrame *next_frame;                   // Temporally next 
3786   StgUpdateFrame *prev_frame;                   // Temporally previous 
3787   StgPtr bottom;
3788   rtsBool prev_was_update_frame;
3789 #if DEBUG
3790   StgUpdateFrame *top_frame;
3791   nat upd_frames=0, stop_frames=0, catch_frames=0, seq_frames=0,
3792       bhs=0, squeezes=0;
3793   void printObj( StgClosure *obj ); // from Printer.c
3794
3795   top_frame  = tso->su;
3796 #endif
3797   
3798   bottom = &(tso->stack[tso->stack_size]);
3799   frame  = tso->su;
3800
3801   /* There must be at least one frame, namely the STOP_FRAME.
3802    */
3803   ASSERT((P_)frame < bottom);
3804
3805   /* Walk down the stack, reversing the links between frames so that
3806    * we can walk back up as we squeeze from the bottom.  Note that
3807    * next_frame and prev_frame refer to next and previous as they were
3808    * added to the stack, rather than the way we see them in this
3809    * walk. (It makes the next loop less confusing.)  
3810    *
3811    * Stop if we find an update frame pointing to a black hole 
3812    * (see comment in threadLazyBlackHole()).
3813    */
3814   
3815   next_frame = NULL;
3816   // bottom - sizeof(StgStopFrame) is the STOP_FRAME 
3817   while ((P_)frame < bottom - sizeofW(StgStopFrame)) {  
3818     prev_frame = frame->link;
3819     frame->link = next_frame;
3820     next_frame = frame;
3821     frame = prev_frame;
3822 #if DEBUG
3823     IF_DEBUG(sanity,
3824              if (!(frame>=top_frame && frame<=(StgUpdateFrame *)bottom)) {
3825                printObj((StgClosure *)prev_frame);
3826                barf("threadSqueezeStack: current frame is rubbish %p; previous was %p\n", 
3827                     frame, prev_frame);
3828              })
3829     switch (get_itbl(frame)->type) {
3830     case UPDATE_FRAME:
3831         upd_frames++;
3832         if (frame->updatee->header.info == &stg_BLACKHOLE_info)
3833             bhs++;
3834         break;
3835     case STOP_FRAME:
3836         stop_frames++;
3837         break;
3838     case CATCH_FRAME:
3839         catch_frames++;
3840         break;
3841     case SEQ_FRAME:
3842         seq_frames++;
3843         break;
3844     default:
3845       barf("Found non-frame during stack squeezing at %p (prev frame was %p)\n",
3846            frame, prev_frame);
3847       printObj((StgClosure *)prev_frame);
3848     }
3849 #endif
3850     if (get_itbl(frame)->type == UPDATE_FRAME
3851         && frame->updatee->header.info == &stg_BLACKHOLE_info) {
3852         break;
3853     }
3854   }
3855
3856   /* Now, we're at the bottom.  Frame points to the lowest update
3857    * frame on the stack, and its link actually points to the frame
3858    * above. We have to walk back up the stack, squeezing out empty
3859    * update frames and turning the pointers back around on the way
3860    * back up.
3861    *
3862    * The bottom-most frame (the STOP_FRAME) has not been altered, and
3863    * we never want to eliminate it anyway.  Just walk one step up
3864    * before starting to squeeze. When you get to the topmost frame,
3865    * remember that there are still some words above it that might have
3866    * to be moved.  
3867    */
3868   
3869   prev_frame = frame;
3870   frame = next_frame;
3871
3872   prev_was_update_frame = (get_itbl(prev_frame)->type == UPDATE_FRAME);
3873
3874   /*
3875    * Loop through all of the frames (everything except the very
3876    * bottom).  Things are complicated by the fact that we have 
3877    * CATCH_FRAMEs and SEQ_FRAMEs interspersed with the update frames.
3878    * We can only squeeze when there are two consecutive UPDATE_FRAMEs.
3879    */
3880   while (frame != NULL) {
3881     StgPtr sp;
3882     StgPtr frame_bottom = (P_)frame + sizeofW(StgUpdateFrame);
3883     rtsBool is_update_frame;
3884     
3885     next_frame = frame->link;
3886     is_update_frame = (get_itbl(frame)->type == UPDATE_FRAME);
3887
3888     /* Check to see if 
3889      *   1. both the previous and current frame are update frames
3890      *   2. the current frame is empty
3891      */
3892     if (prev_was_update_frame && is_update_frame &&
3893         (P_)prev_frame == frame_bottom + displacement) {
3894       
3895       // Now squeeze out the current frame 
3896       StgClosure *updatee_keep   = prev_frame->updatee;
3897       StgClosure *updatee_bypass = frame->updatee;
3898       
3899 #if DEBUG
3900       IF_DEBUG(gc, belch("@@ squeezing frame at %p", frame));
3901       squeezes++;
3902 #endif
3903
3904       /* Deal with blocking queues.  If both updatees have blocked
3905        * threads, then we should merge the queues into the update
3906        * frame that we're keeping.
3907        *
3908        * Alternatively, we could just wake them up: they'll just go
3909        * straight to sleep on the proper blackhole!  This is less code
3910        * and probably less bug prone, although it's probably much
3911        * slower --SDM
3912        */
3913 #if 0 // do it properly... 
3914 #  if (!defined(LAZY_BLACKHOLING)) && defined(DEBUG)
3915 #    error Unimplemented lazy BH warning.  (KSW 1999-01)
3916 #  endif
3917       if (GET_INFO(updatee_bypass) == stg_BLACKHOLE_BQ_info
3918           || GET_INFO(updatee_bypass) == stg_CAF_BLACKHOLE_info
3919           ) {
3920         // Sigh.  It has one.  Don't lose those threads! 
3921           if (GET_INFO(updatee_keep) == stg_BLACKHOLE_BQ_info) {
3922           // Urgh.  Two queues.  Merge them. 
3923           P_ keep_tso = ((StgBlockingQueue *)updatee_keep)->blocking_queue;
3924           
3925           while (keep_tso->link != END_TSO_QUEUE) {
3926             keep_tso = keep_tso->link;
3927           }
3928           keep_tso->link = ((StgBlockingQueue *)updatee_bypass)->blocking_queue;
3929
3930         } else {
3931           // For simplicity, just swap the BQ for the BH 
3932           P_ temp = updatee_keep;
3933           
3934           updatee_keep = updatee_bypass;
3935           updatee_bypass = temp;
3936           
3937           // Record the swap in the kept frame (below) 
3938           prev_frame->updatee = updatee_keep;
3939         }
3940       }
3941 #endif
3942
3943       TICK_UPD_SQUEEZED();
3944       /* wasn't there something about update squeezing and ticky to be
3945        * sorted out?  oh yes: we aren't counting each enter properly
3946        * in this case.  See the log somewhere.  KSW 1999-04-21
3947        *
3948        * Check two things: that the two update frames don't point to
3949        * the same object, and that the updatee_bypass isn't already an
3950        * indirection.  Both of these cases only happen when we're in a
3951        * block hole-style loop (and there are multiple update frames
3952        * on the stack pointing to the same closure), but they can both
3953        * screw us up if we don't check.
3954        */
3955       if (updatee_bypass != updatee_keep && !closure_IND(updatee_bypass)) {
3956           // this wakes the threads up 
3957           UPD_IND_NOLOCK(updatee_bypass, updatee_keep);
3958       }
3959       
3960       sp = (P_)frame - 1;       // sp = stuff to slide 
3961       displacement += sizeofW(StgUpdateFrame);
3962       
3963     } else {
3964       // No squeeze for this frame 
3965       sp = frame_bottom - 1;    // Keep the current frame 
3966       
3967       /* Do lazy black-holing.
3968        */
3969       if (is_update_frame) {
3970         StgBlockingQueue *bh = (StgBlockingQueue *)frame->updatee;
3971         if (bh->header.info != &stg_BLACKHOLE_info &&
3972             bh->header.info != &stg_BLACKHOLE_BQ_info &&
3973             bh->header.info != &stg_CAF_BLACKHOLE_info) {
3974 #if (!defined(LAZY_BLACKHOLING)) && defined(DEBUG)
3975           belch("Unexpected lazy BHing required at 0x%04x",(int)bh);
3976 #endif
3977 #ifdef DEBUG
3978           /* zero out the slop so that the sanity checker can tell
3979            * where the next closure is.
3980            */
3981           { 
3982               StgInfoTable *info = get_itbl(bh);
3983               nat np = info->layout.payload.ptrs, nw = info->layout.payload.nptrs, i;
3984               /* don't zero out slop for a THUNK_SELECTOR, because its layout
3985                * info is used for a different purpose, and it's exactly the
3986                * same size as a BLACKHOLE in any case.
3987                */
3988               if (info->type != THUNK_SELECTOR) {
3989                 for (i = np; i < np + nw; i++) {
3990                   ((StgClosure *)bh)->payload[i] = 0;
3991                 }
3992               }
3993           }
3994 #endif
3995 #ifdef PROFILING
3996           // @LDV profiling
3997           // We pretend that bh is now dead.
3998           LDV_recordDead_FILL_SLOP_DYNAMIC((StgClosure *)bh);
3999 #endif
4000           // 
4001           // Todo: maybe use SET_HDR() and remove LDV_recordCreate()?
4002           // 
4003           SET_INFO(bh,&stg_BLACKHOLE_info);
4004 #ifdef PROFILING
4005           // @LDV profiling
4006           // We pretend that bh has just been created.
4007           LDV_recordCreate(bh);
4008 #endif
4009         }
4010       }
4011
4012       // Fix the link in the current frame (should point to the frame below) 
4013       frame->link = prev_frame;
4014       prev_was_update_frame = is_update_frame;
4015     }
4016     
4017     // Now slide all words from sp up to the next frame 
4018     
4019     if (displacement > 0) {
4020       P_ next_frame_bottom;
4021
4022       if (next_frame != NULL)
4023         next_frame_bottom = (P_)next_frame + sizeofW(StgUpdateFrame);
4024       else
4025         next_frame_bottom = tso->sp - 1;
4026       
4027 #if 0
4028       IF_DEBUG(gc,
4029                belch("sliding [%p, %p] by %ld", sp, next_frame_bottom,
4030                      displacement))
4031 #endif
4032       
4033       while (sp >= next_frame_bottom) {
4034         sp[displacement] = *sp;
4035         sp -= 1;
4036       }
4037     }
4038     (P_)prev_frame = (P_)frame + displacement;
4039     frame = next_frame;
4040   }
4041
4042   tso->sp += displacement;
4043   tso->su = prev_frame;
4044 #if 0
4045   IF_DEBUG(gc,
4046            belch("@@ threadSqueezeStack: squeezed %d update-frames; found %d BHs; found %d update-, %d stop-, %d catch, %d seq-frames",
4047                    squeezes, bhs, upd_frames, stop_frames, catch_frames, seq_frames))
4048 #endif
4049 }
4050
4051
4052 /* -----------------------------------------------------------------------------
4053  * Pausing a thread
4054  * 
4055  * We have to prepare for GC - this means doing lazy black holing
4056  * here.  We also take the opportunity to do stack squeezing if it's
4057  * turned on.
4058  * -------------------------------------------------------------------------- */
4059 void
4060 threadPaused(StgTSO *tso)
4061 {
4062   if ( RtsFlags.GcFlags.squeezeUpdFrames == rtsTrue )
4063     threadSqueezeStack(tso);    // does black holing too 
4064   else
4065     threadLazyBlackHole(tso);
4066 }
4067
4068 /* -----------------------------------------------------------------------------
4069  * Debugging
4070  * -------------------------------------------------------------------------- */
4071
4072 #if DEBUG
4073 void
4074 printMutOnceList(generation *gen)
4075 {
4076   StgMutClosure *p, *next;
4077
4078   p = gen->mut_once_list;
4079   next = p->mut_link;
4080
4081   fprintf(stderr, "@@ Mut once list %p: ", gen->mut_once_list);
4082   for (; p != END_MUT_LIST; p = next, next = p->mut_link) {
4083     fprintf(stderr, "%p (%s), ", 
4084             p, info_type((StgClosure *)p));
4085   }
4086   fputc('\n', stderr);
4087 }
4088
4089 void
4090 printMutableList(generation *gen)
4091 {
4092   StgMutClosure *p, *next;
4093
4094   p = gen->mut_list;
4095   next = p->mut_link;
4096
4097   fprintf(stderr, "@@ Mutable list %p: ", gen->mut_list);
4098   for (; p != END_MUT_LIST; p = next, next = p->mut_link) {
4099     fprintf(stderr, "%p (%s), ",
4100             p, info_type((StgClosure *)p));
4101   }
4102   fputc('\n', stderr);
4103 }
4104
4105 static inline rtsBool
4106 maybeLarge(StgClosure *closure)
4107 {
4108   StgInfoTable *info = get_itbl(closure);
4109
4110   /* closure types that may be found on the new_large_objects list; 
4111      see scavenge_large */
4112   return (info->type == MUT_ARR_PTRS ||
4113           info->type == MUT_ARR_PTRS_FROZEN ||
4114           info->type == TSO ||
4115           info->type == ARR_WORDS);
4116 }
4117
4118   
4119 #endif // DEBUG