Remove the optimisation of avoiding scavenging for certain objects
[ghc-hetmet.git] / rts / sm / GC.c
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team 1998-2006
4  *
5  * Generational garbage collector
6  *
7  * Documentation on the architecture of the Garbage Collector can be
8  * found in the online commentary:
9  * 
10  *   http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
11  *
12  * ---------------------------------------------------------------------------*/
13
14 #include "PosixSource.h"
15 #include "Rts.h"
16 #include "RtsFlags.h"
17 #include "RtsUtils.h"
18 #include "Apply.h"
19 #include "OSThreads.h"
20 #include "LdvProfile.h"
21 #include "Updates.h"
22 #include "Stats.h"
23 #include "Schedule.h"
24 #include "Sanity.h"
25 #include "BlockAlloc.h"
26 #include "MBlock.h"
27 #include "ProfHeap.h"
28 #include "SchedAPI.h"
29 #include "Weak.h"
30 #include "Prelude.h"
31 #include "ParTicky.h"           // ToDo: move into Rts.h
32 #include "RtsSignals.h"
33 #include "STM.h"
34 #include "HsFFI.h"
35 #include "Linker.h"
36 #if defined(RTS_GTK_FRONTPANEL)
37 #include "FrontPanel.h"
38 #endif
39 #include "Trace.h"
40 #include "RetainerProfile.h"
41 #include "RaiseAsync.h"
42 #include "Sparks.h"
43
44 #include "GC.h"
45 #include "Compact.h"
46 #include "Evac.h"
47 #include "Scav.h"
48 #include "GCUtils.h"
49 #include "MarkWeak.h"
50 #include "Sparks.h"
51
52 #include <string.h> // for memset()
53
54 /* -----------------------------------------------------------------------------
55    Global variables
56    -------------------------------------------------------------------------- */
57
58 /* STATIC OBJECT LIST.
59  *
60  * During GC:
61  * We maintain a linked list of static objects that are still live.
62  * The requirements for this list are:
63  *
64  *  - we need to scan the list while adding to it, in order to
65  *    scavenge all the static objects (in the same way that
66  *    breadth-first scavenging works for dynamic objects).
67  *
68  *  - we need to be able to tell whether an object is already on
69  *    the list, to break loops.
70  *
71  * Each static object has a "static link field", which we use for
72  * linking objects on to the list.  We use a stack-type list, consing
73  * objects on the front as they are added (this means that the
74  * scavenge phase is depth-first, not breadth-first, but that
75  * shouldn't matter).  
76  *
77  * A separate list is kept for objects that have been scavenged
78  * already - this is so that we can zero all the marks afterwards.
79  *
80  * An object is on the list if its static link field is non-zero; this
81  * means that we have to mark the end of the list with '1', not NULL.  
82  *
83  * Extra notes for generational GC:
84  *
85  * Each generation has a static object list associated with it.  When
86  * collecting generations up to N, we treat the static object lists
87  * from generations > N as roots.
88  *
89  * We build up a static object list while collecting generations 0..N,
90  * which is then appended to the static object list of generation N+1.
91  */
92 StgClosure* static_objects;      // live static objects
93 StgClosure* scavenged_static_objects;   // static objects scavenged so far
94 #ifdef THREADED_RTS
95 SpinLock static_objects_sync;
96 #endif
97
98 /* N is the oldest generation being collected, where the generations
99  * are numbered starting at 0.  A major GC (indicated by the major_gc
100  * flag) is when we're collecting all generations.  We only attempt to
101  * deal with static objects and GC CAFs when doing a major GC.
102  */
103 nat N;
104 rtsBool major_gc;
105
106 /* Data used for allocation area sizing.
107  */
108 static lnat g0s0_pcnt_kept = 30; // percentage of g0s0 live at last minor GC 
109
110 /* Mut-list stats */
111 #ifdef DEBUG
112 nat mutlist_MUTVARS,
113     mutlist_MUTARRS,
114     mutlist_MVARS,
115     mutlist_OTHERS;
116 #endif
117
118 /* Thread-local data for each GC thread
119  */
120 gc_thread *gc_threads = NULL;
121 // gc_thread *gct = NULL;  // this thread's gct TODO: make thread-local
122
123 // For stats:
124 long copied;        // *words* copied & scavenged during this GC
125
126 #ifdef THREADED_RTS
127 SpinLock recordMutableGen_sync;
128 #endif
129
130 /* -----------------------------------------------------------------------------
131    Static function declarations
132    -------------------------------------------------------------------------- */
133
134 static void mark_root               (StgClosure **root);
135 static void zero_static_object_list (StgClosure* first_static);
136 static void initialise_N            (rtsBool force_major_gc);
137 static void alloc_gc_threads        (void);
138 static void init_collected_gen      (nat g, nat threads);
139 static void init_uncollected_gen    (nat g, nat threads);
140 static void init_gc_thread          (gc_thread *t);
141 static void update_task_list        (void);
142 static void resize_generations      (void);
143 static void resize_nursery          (void);
144 static void start_gc_threads        (void);
145 static void gc_thread_work          (void);
146 static nat  inc_running             (void);
147 static nat  dec_running             (void);
148 static void wakeup_gc_threads       (nat n_threads);
149
150 #if 0 && defined(DEBUG)
151 static void gcCAFs                  (void);
152 #endif
153
154 /* -----------------------------------------------------------------------------
155    The mark bitmap & stack.
156    -------------------------------------------------------------------------- */
157
158 #define MARK_STACK_BLOCKS 4
159
160 bdescr *mark_stack_bdescr;
161 StgPtr *mark_stack;
162 StgPtr *mark_sp;
163 StgPtr *mark_splim;
164
165 // Flag and pointers used for falling back to a linear scan when the
166 // mark stack overflows.
167 rtsBool mark_stack_overflowed;
168 bdescr *oldgen_scan_bd;
169 StgPtr  oldgen_scan;
170
171 /* -----------------------------------------------------------------------------
172    GarbageCollect: the main entry point to the garbage collector.
173
174    Locks held: all capabilities are held throughout GarbageCollect().
175    -------------------------------------------------------------------------- */
176
177 void
178 GarbageCollect ( rtsBool force_major_gc )
179 {
180   bdescr *bd;
181   step *stp;
182   lnat live, allocated;
183   lnat oldgen_saved_blocks = 0;
184   nat n_threads; // number of threads participating in GC
185   gc_thread *saved_gct;
186   nat g, s, t;
187
188   // necessary if we stole a callee-saves register for gct:
189   saved_gct = gct;
190
191 #ifdef PROFILING
192   CostCentreStack *prev_CCS;
193 #endif
194
195   ACQUIRE_SM_LOCK;
196
197   debugTrace(DEBUG_gc, "starting GC");
198
199 #if defined(RTS_USER_SIGNALS)
200   if (RtsFlags.MiscFlags.install_signal_handlers) {
201     // block signals
202     blockUserSignals();
203   }
204 #endif
205
206   // tell the STM to discard any cached closures it's hoping to re-use
207   stmPreGCHook();
208
209   // tell the stats department that we've started a GC 
210   stat_startGC();
211
212 #ifdef DEBUG
213   // check for memory leaks if DEBUG is on 
214   memInventory();
215 #endif
216
217 #ifdef DEBUG
218   mutlist_MUTVARS = 0;
219   mutlist_MUTARRS = 0;
220   mutlist_OTHERS = 0;
221 #endif
222
223   // attribute any costs to CCS_GC 
224 #ifdef PROFILING
225   prev_CCS = CCCS;
226   CCCS = CCS_GC;
227 #endif
228
229   /* Approximate how much we allocated.  
230    * Todo: only when generating stats? 
231    */
232   allocated = calcAllocated();
233
234   /* Figure out which generation to collect
235    */
236   initialise_N(force_major_gc);
237
238   /* Allocate + initialise the gc_thread structures.
239    */
240   alloc_gc_threads();
241
242   /* Start threads, so they can be spinning up while we finish initialisation.
243    */
244   start_gc_threads();
245
246   /* How many threads will be participating in this GC?
247    * We don't try to parallelise minor GC.
248    */
249 #if defined(THREADED_RTS)
250   if (N == 0) {
251       n_threads = 1;
252   } else {
253       n_threads = RtsFlags.ParFlags.gcThreads;
254   }
255 #else
256   n_threads = 1;
257 #endif
258
259 #ifdef RTS_GTK_FRONTPANEL
260   if (RtsFlags.GcFlags.frontpanel) {
261       updateFrontPanelBeforeGC(N);
262   }
263 #endif
264
265   // check stack sanity *before* GC (ToDo: check all threads) 
266   IF_DEBUG(sanity, checkFreeListSanity());
267
268   /* Initialise the static object lists
269    */
270   static_objects = END_OF_STATIC_LIST;
271   scavenged_static_objects = END_OF_STATIC_LIST;
272
273 #ifdef THREADED_RTS
274   initSpinLock(&static_objects_sync);
275   initSpinLock(&recordMutableGen_sync);
276   initSpinLock(&gc_alloc_block_sync);
277 #endif
278
279   // Initialise all the generations/steps that we're collecting.
280   for (g = 0; g <= N; g++) {
281       init_collected_gen(g,n_threads);
282   }
283   
284   // Initialise all the generations/steps that we're *not* collecting.
285   for (g = N+1; g < RtsFlags.GcFlags.generations; g++) {
286       init_uncollected_gen(g,n_threads);
287   }
288
289   /* Allocate a mark stack if we're doing a major collection.
290    */
291   if (major_gc) {
292       mark_stack_bdescr = allocGroup(MARK_STACK_BLOCKS);
293       mark_stack = (StgPtr *)mark_stack_bdescr->start;
294       mark_sp    = mark_stack;
295       mark_splim = mark_stack + (MARK_STACK_BLOCKS * BLOCK_SIZE_W);
296   } else {
297       mark_stack_bdescr = NULL;
298   }
299
300   // Initialise all our gc_thread structures
301   for (t = 0; t < n_threads; t++) {
302       init_gc_thread(&gc_threads[t]);
303   }
304
305   // the main thread is running: this prevents any other threads from
306   // exiting prematurely, so we can start them now.
307   inc_running();
308   wakeup_gc_threads(n_threads);
309
310   // Initialise stats
311   copied = 0;
312
313   // this is the main thread
314   gct = &gc_threads[0];
315
316   /* -----------------------------------------------------------------------
317    * follow all the roots that we know about:
318    *   - mutable lists from each generation > N
319    * we want to *scavenge* these roots, not evacuate them: they're not
320    * going to move in this GC.
321    * Also do them in reverse generation order, for the usual reason:
322    * namely to reduce the likelihood of spurious old->new pointers.
323    */
324   { 
325     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
326       generations[g].saved_mut_list = generations[g].mut_list;
327       generations[g].mut_list = allocBlock(); 
328         // mut_list always has at least one block.
329     }
330     for (g = RtsFlags.GcFlags.generations-1; g > N; g--) {
331       scavenge_mutable_list(&generations[g]);
332     }
333   }
334
335   // follow roots from the CAF list (used by GHCi)
336   gct->evac_step = 0;
337   markCAFs(mark_root);
338
339   // follow all the roots that the application knows about.
340   gct->evac_step = 0;
341   GetRoots(mark_root);
342
343   // Mark the weak pointer list, and prepare to detect dead weak pointers.
344   markWeakPtrList();
345   initWeakForGC();
346
347   // Mark the stable pointer table.
348   markStablePtrTable(mark_root);
349
350   /* -------------------------------------------------------------------------
351    * Repeatedly scavenge all the areas we know about until there's no
352    * more scavenging to be done.
353    */
354   for (;;)
355   {
356       gc_thread_work();
357       // The other threads are now stopped.  We might recurse back to
358       // here, but from now on this is the only thread.
359       
360       // if any blackholes are alive, make the threads that wait on
361       // them alive too.
362       if (traverseBlackholeQueue()) {
363           inc_running(); 
364           continue;
365       }
366   
367       // must be last...  invariant is that everything is fully
368       // scavenged at this point.
369       if (traverseWeakPtrList()) { // returns rtsTrue if evaced something 
370           inc_running();
371           continue;
372       }
373
374       // If we get to here, there's really nothing left to do.
375       break;
376   }
377
378   // Update pointers from the Task list
379   update_task_list();
380
381   // Now see which stable names are still alive.
382   gcStablePtrTable();
383
384 #ifdef PROFILING
385   // We call processHeapClosureForDead() on every closure destroyed during
386   // the current garbage collection, so we invoke LdvCensusForDead().
387   if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_LDV
388       || RtsFlags.ProfFlags.bioSelector != NULL)
389     LdvCensusForDead(N);
390 #endif
391
392   // NO MORE EVACUATION AFTER THIS POINT!
393   // Finally: compaction of the oldest generation.
394   if (major_gc && oldest_gen->steps[0].is_compacted) {
395       // save number of blocks for stats
396       oldgen_saved_blocks = oldest_gen->steps[0].n_old_blocks;
397       compact();
398   }
399
400   IF_DEBUG(sanity, checkGlobalTSOList(rtsFalse));
401
402   // Two-space collector: free the old to-space.
403   // g0s0->old_blocks is the old nursery
404   // g0s0->blocks is to-space from the previous GC
405   if (RtsFlags.GcFlags.generations == 1) {
406       if (g0s0->blocks != NULL) {
407           freeChain(g0s0->blocks);
408           g0s0->blocks = NULL;
409       }
410   }
411
412   // For each workspace, in each thread:
413   //    * clear the BF_EVACUATED flag from each copied block
414   //    * move the copied blocks to the step
415   {
416       gc_thread *thr;
417       step_workspace *ws;
418       bdescr *prev;
419
420       for (t = 0; t < n_threads; t++) {
421           thr = &gc_threads[t];
422
423           for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
424               for (s = 0; s < generations[g].n_steps; s++) {
425                   ws = &thr->steps[g][s];
426                   if (g==0 && s==0) continue;
427
428                   // Not true?
429                   // ASSERT( ws->scan_bd == ws->todo_bd );
430                   ASSERT( ws->scan_bd ? ws->scan == ws->scan_bd->free : 1 );
431
432                   // Push the final block
433                   if (ws->scan_bd) { push_scan_block(ws->scan_bd, ws); }
434
435                   ASSERT(countBlocks(ws->scavd_list) == ws->n_scavd_blocks);
436
437                   prev = ws->scavd_list;
438                   for (bd = ws->scavd_list; bd != NULL; bd = bd->link) {
439                       bd->flags &= ~BF_EVACUATED;        // now from-space 
440                       prev = bd;
441                   }
442                   prev->link = ws->stp->blocks;
443                   ws->stp->blocks = ws->scavd_list;
444                   ws->stp->n_blocks += ws->n_scavd_blocks;
445                   ASSERT(countBlocks(ws->stp->blocks) == ws->stp->n_blocks);
446               }
447           }
448       }
449   }
450
451   // Two-space collector: swap the semi-spaces around.
452   // Currently: g0s0->old_blocks is the old nursery
453   //            g0s0->blocks is to-space from this GC
454   // We want these the other way around.
455   if (RtsFlags.GcFlags.generations == 1) {
456       bdescr *nursery_blocks = g0s0->old_blocks;
457       nat n_nursery_blocks = g0s0->n_old_blocks;
458       g0s0->old_blocks = g0s0->blocks;
459       g0s0->n_old_blocks = g0s0->n_blocks;
460       g0s0->blocks = nursery_blocks;
461       g0s0->n_blocks = n_nursery_blocks;
462   }
463
464   /* run through all the generations/steps and tidy up 
465    */
466   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
467
468     if (g <= N) {
469       generations[g].collections++; // for stats 
470     }
471
472     // Count the mutable list as bytes "copied" for the purposes of
473     // stats.  Every mutable list is copied during every GC.
474     if (g > 0) {
475         nat mut_list_size = 0;
476         for (bd = generations[g].mut_list; bd != NULL; bd = bd->link) {
477             mut_list_size += bd->free - bd->start;
478         }
479         copied +=  mut_list_size;
480
481         debugTrace(DEBUG_gc,
482                    "mut_list_size: %lu (%d vars, %d arrays, %d MVARs, %d others)",
483                    (unsigned long)(mut_list_size * sizeof(W_)),
484                    mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, mutlist_OTHERS);
485     }
486
487     for (s = 0; s < generations[g].n_steps; s++) {
488       bdescr *next;
489       stp = &generations[g].steps[s];
490
491       // for generations we collected... 
492       if (g <= N) {
493
494         /* free old memory and shift to-space into from-space for all
495          * the collected steps (except the allocation area).  These
496          * freed blocks will probaby be quickly recycled.
497          */
498         if (!(g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1)) {
499             if (stp->is_compacted)
500             {
501                 // for a compacted step, just shift the new to-space
502                 // onto the front of the now-compacted existing blocks.
503                 for (bd = stp->blocks; bd != NULL; bd = bd->link) {
504                     bd->flags &= ~BF_EVACUATED;  // now from-space 
505                 }
506                 // tack the new blocks on the end of the existing blocks
507                 if (stp->old_blocks != NULL) {
508                     for (bd = stp->old_blocks; bd != NULL; bd = next) {
509                         // NB. this step might not be compacted next
510                         // time, so reset the BF_COMPACTED flags.
511                         // They are set before GC if we're going to
512                         // compact.  (search for BF_COMPACTED above).
513                         bd->flags &= ~BF_COMPACTED;
514                         next = bd->link;
515                         if (next == NULL) {
516                             bd->link = stp->blocks;
517                         }
518                     }
519                     stp->blocks = stp->old_blocks;
520                 }
521                 // add the new blocks to the block tally
522                 stp->n_blocks += stp->n_old_blocks;
523                 ASSERT(countBlocks(stp->blocks) == stp->n_blocks);
524             }
525             else // not copacted
526             {
527                 freeChain(stp->old_blocks);
528             }
529             stp->old_blocks = NULL;
530             stp->n_old_blocks = 0;
531         }
532
533         /* LARGE OBJECTS.  The current live large objects are chained on
534          * scavenged_large, having been moved during garbage
535          * collection from large_objects.  Any objects left on
536          * large_objects list are therefore dead, so we free them here.
537          */
538         for (bd = stp->large_objects; bd != NULL; bd = next) {
539           next = bd->link;
540           freeGroup(bd);
541           bd = next;
542         }
543
544         // update the count of blocks used by large objects
545         for (bd = stp->scavenged_large_objects; bd != NULL; bd = bd->link) {
546           bd->flags &= ~BF_EVACUATED;
547         }
548         stp->large_objects  = stp->scavenged_large_objects;
549         stp->n_large_blocks = stp->n_scavenged_large_blocks;
550
551       }
552       else // for older generations... 
553       {
554         /* For older generations, we need to append the
555          * scavenged_large_object list (i.e. large objects that have been
556          * promoted during this GC) to the large_object list for that step.
557          */
558         for (bd = stp->scavenged_large_objects; bd; bd = next) {
559           next = bd->link;
560           bd->flags &= ~BF_EVACUATED;
561           dbl_link_onto(bd, &stp->large_objects);
562         }
563
564         // add the new blocks we promoted during this GC 
565         stp->n_large_blocks += stp->n_scavenged_large_blocks;
566       }
567     }
568   }
569
570   // update the max size of older generations after a major GC
571   resize_generations();
572   
573   // Guess the amount of live data for stats.
574   live = calcLive();
575
576   // Free the small objects allocated via allocate(), since this will
577   // all have been copied into G0S1 now.  
578   if (RtsFlags.GcFlags.generations > 1) {
579       if (g0s0->blocks != NULL) {
580           freeChain(g0s0->blocks);
581           g0s0->blocks = NULL;
582       }
583       g0s0->n_blocks = 0;
584   }
585   alloc_blocks = 0;
586   alloc_blocks_lim = RtsFlags.GcFlags.minAllocAreaSize;
587
588   // Start a new pinned_object_block
589   pinned_object_block = NULL;
590
591   // Free the mark stack.
592   if (mark_stack_bdescr != NULL) {
593       freeGroup(mark_stack_bdescr);
594   }
595
596   // Free any bitmaps.
597   for (g = 0; g <= N; g++) {
598       for (s = 0; s < generations[g].n_steps; s++) {
599           stp = &generations[g].steps[s];
600           if (stp->bitmap != NULL) {
601               freeGroup(stp->bitmap);
602               stp->bitmap = NULL;
603           }
604       }
605   }
606
607   resize_nursery();
608
609  // mark the garbage collected CAFs as dead 
610 #if 0 && defined(DEBUG) // doesn't work at the moment 
611   if (major_gc) { gcCAFs(); }
612 #endif
613   
614 #ifdef PROFILING
615   // resetStaticObjectForRetainerProfiling() must be called before
616   // zeroing below.
617   resetStaticObjectForRetainerProfiling();
618 #endif
619
620   // zero the scavenged static object list 
621   if (major_gc) {
622     zero_static_object_list(scavenged_static_objects);
623   }
624
625   // Reset the nursery
626   resetNurseries();
627
628   // start any pending finalizers 
629   RELEASE_SM_LOCK;
630   scheduleFinalizers(last_free_capability, old_weak_ptr_list);
631   ACQUIRE_SM_LOCK;
632   
633   // send exceptions to any threads which were about to die 
634   RELEASE_SM_LOCK;
635   resurrectThreads(resurrected_threads);
636   ACQUIRE_SM_LOCK;
637
638   // Update the stable pointer hash table.
639   updateStablePtrTable(major_gc);
640
641   // check sanity after GC 
642   IF_DEBUG(sanity, checkSanity());
643
644   // extra GC trace info 
645   IF_DEBUG(gc, statDescribeGens());
646
647 #ifdef DEBUG
648   // symbol-table based profiling 
649   /*  heapCensus(to_blocks); */ /* ToDo */
650 #endif
651
652   // restore enclosing cost centre 
653 #ifdef PROFILING
654   CCCS = prev_CCS;
655 #endif
656
657 #ifdef DEBUG
658   // check for memory leaks if DEBUG is on 
659   memInventory();
660 #endif
661
662 #ifdef RTS_GTK_FRONTPANEL
663   if (RtsFlags.GcFlags.frontpanel) {
664       updateFrontPanelAfterGC( N, live );
665   }
666 #endif
667
668   // ok, GC over: tell the stats department what happened. 
669   stat_endGC(allocated, live, copied, N);
670
671 #if defined(RTS_USER_SIGNALS)
672   if (RtsFlags.MiscFlags.install_signal_handlers) {
673     // unblock signals again
674     unblockUserSignals();
675   }
676 #endif
677
678   RELEASE_SM_LOCK;
679
680   gct = saved_gct;
681 }
682
683 /* ---------------------------------------------------------------------------
684    Where are the roots that we know about?
685
686         - all the threads on the runnable queue
687         - all the threads on the blocked queue
688         - all the threads on the sleeping queue
689         - all the thread currently executing a _ccall_GC
690         - all the "main threads"
691      
692    ------------------------------------------------------------------------ */
693
694 /* This has to be protected either by the scheduler monitor, or by the
695         garbage collection monitor (probably the latter).
696         KH @ 25/10/99
697 */
698
699 void
700 GetRoots( evac_fn evac )
701 {
702     nat i;
703     Capability *cap;
704     Task *task;
705
706     for (i = 0; i < n_capabilities; i++) {
707         cap = &capabilities[i];
708         evac((StgClosure **)(void *)&cap->run_queue_hd);
709         evac((StgClosure **)(void *)&cap->run_queue_tl);
710 #if defined(THREADED_RTS)
711         evac((StgClosure **)(void *)&cap->wakeup_queue_hd);
712         evac((StgClosure **)(void *)&cap->wakeup_queue_tl);
713 #endif
714         for (task = cap->suspended_ccalling_tasks; task != NULL; 
715              task=task->next) {
716             debugTrace(DEBUG_sched,
717                        "evac'ing suspended TSO %lu", (unsigned long)task->suspended_tso->id);
718             evac((StgClosure **)(void *)&task->suspended_tso);
719         }
720
721     }
722     
723 #if !defined(THREADED_RTS)
724     evac((StgClosure **)(void *)&blocked_queue_hd);
725     evac((StgClosure **)(void *)&blocked_queue_tl);
726     evac((StgClosure **)(void *)&sleeping_queue);
727 #endif 
728
729     // evac((StgClosure **)&blackhole_queue);
730
731 #if defined(THREADED_RTS)
732     markSparkQueue(evac);
733 #endif
734     
735 #if defined(RTS_USER_SIGNALS)
736     // mark the signal handlers (signals should be already blocked)
737     markSignalHandlers(evac);
738 #endif
739 }
740
741 /* -----------------------------------------------------------------------------
742    isAlive determines whether the given closure is still alive (after
743    a garbage collection) or not.  It returns the new address of the
744    closure if it is alive, or NULL otherwise.
745
746    NOTE: Use it before compaction only!
747          It untags and (if needed) retags pointers to closures.
748    -------------------------------------------------------------------------- */
749
750
751 StgClosure *
752 isAlive(StgClosure *p)
753 {
754   const StgInfoTable *info;
755   bdescr *bd;
756   StgWord tag;
757   StgClosure *q;
758
759   while (1) {
760     /* The tag and the pointer are split, to be merged later when needed. */
761     tag = GET_CLOSURE_TAG(p);
762     q = UNTAG_CLOSURE(p);
763
764     ASSERT(LOOKS_LIKE_CLOSURE_PTR(q));
765     info = get_itbl(q);
766
767     // ignore static closures 
768     //
769     // ToDo: for static closures, check the static link field.
770     // Problem here is that we sometimes don't set the link field, eg.
771     // for static closures with an empty SRT or CONSTR_STATIC_NOCAFs.
772     //
773     if (!HEAP_ALLOCED(q)) {
774         return p;
775     }
776
777     // ignore closures in generations that we're not collecting. 
778     bd = Bdescr((P_)q);
779     if (bd->gen_no > N) {
780         return p;
781     }
782
783     // if it's a pointer into to-space, then we're done
784     if (bd->flags & BF_EVACUATED) {
785         return p;
786     }
787
788     // large objects use the evacuated flag
789     if (bd->flags & BF_LARGE) {
790         return NULL;
791     }
792
793     // check the mark bit for compacted steps
794     if ((bd->flags & BF_COMPACTED) && is_marked((P_)q,bd)) {
795         return p;
796     }
797
798     switch (info->type) {
799
800     case IND:
801     case IND_STATIC:
802     case IND_PERM:
803     case IND_OLDGEN:            // rely on compatible layout with StgInd 
804     case IND_OLDGEN_PERM:
805       // follow indirections 
806       p = ((StgInd *)q)->indirectee;
807       continue;
808
809     case EVACUATED:
810       // alive! 
811       return ((StgEvacuated *)q)->evacuee;
812
813     case TSO:
814       if (((StgTSO *)q)->what_next == ThreadRelocated) {
815         p = (StgClosure *)((StgTSO *)q)->link;
816         continue;
817       } 
818       return NULL;
819
820     default:
821       // dead. 
822       return NULL;
823     }
824   }
825 }
826
827 /* -----------------------------------------------------------------------------
828    Figure out which generation to collect, initialise N and major_gc.
829    -------------------------------------------------------------------------- */
830
831 static void
832 initialise_N (rtsBool force_major_gc)
833 {
834     nat g;
835
836     if (force_major_gc) {
837         N = RtsFlags.GcFlags.generations - 1;
838         major_gc = rtsTrue;
839     } else {
840         N = 0;
841         for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
842             if (generations[g].steps[0].n_blocks +
843                 generations[g].steps[0].n_large_blocks
844                 >= generations[g].max_blocks) {
845                 N = g;
846             }
847         }
848         major_gc = (N == RtsFlags.GcFlags.generations-1);
849     }
850 }
851
852 /* -----------------------------------------------------------------------------
853    Initialise the gc_thread structures.
854    -------------------------------------------------------------------------- */
855
856 static void
857 alloc_gc_thread (gc_thread *t, int n)
858 {
859     nat g, s;
860     step_workspace *ws;
861
862 #ifdef THREADED_RTS
863     t->id = 0;
864     initCondition(&t->wake_cond);
865     initMutex(&t->wake_mutex);
866     t->wakeup = rtsFalse;
867     t->exit   = rtsFalse;
868 #endif
869
870     t->thread_index = n;
871     t->free_blocks = NULL;
872     t->gc_count = 0;
873
874     init_gc_thread(t);
875     
876     t->steps = stgMallocBytes(RtsFlags.GcFlags.generations * 
877                                 sizeof(step_workspace *), 
878                                 "initialise_gc_thread");
879
880     for (g = 0; g < RtsFlags.GcFlags.generations; g++)
881     {
882         t->steps[g] = stgMallocBytes(generations[g].n_steps * 
883                                        sizeof(step_workspace),
884                                        "initialise_gc_thread/2");
885
886         for (s = 0; s < generations[g].n_steps; s++)
887         {
888             ws = &t->steps[g][s];
889             ws->stp = &generations[g].steps[s];
890             ws->gct = t;
891
892             ws->scan_bd = NULL;
893             ws->scan = NULL;
894
895             ws->todo_bd = NULL;
896             ws->buffer_todo_bd = NULL;
897
898             ws->scavd_list = NULL;
899             ws->n_scavd_blocks = 0;
900         }
901     }
902 }
903
904
905 static void
906 alloc_gc_threads (void)
907 {
908     if (gc_threads == NULL) {
909 #if defined(THREADED_RTS)
910         nat i;
911         gc_threads = stgMallocBytes (RtsFlags.ParFlags.gcThreads * 
912                                      sizeof(gc_thread), 
913                                      "alloc_gc_threads");
914
915         for (i = 0; i < RtsFlags.ParFlags.gcThreads; i++) {
916             alloc_gc_thread(&gc_threads[i], i);
917         }
918 #else
919         gc_threads = stgMallocBytes (sizeof(gc_thread), 
920                                      "alloc_gc_threads");
921
922         alloc_gc_thread(gc_threads, 0);
923 #endif
924     }
925 }
926
927 /* ----------------------------------------------------------------------------
928    Start GC threads
929    ------------------------------------------------------------------------- */
930
931 static nat gc_running_threads;
932
933 #if defined(THREADED_RTS)
934 static Mutex gc_running_mutex;
935 #endif
936
937 static nat
938 inc_running (void)
939 {
940     nat n_running;
941     ACQUIRE_LOCK(&gc_running_mutex);
942     n_running = ++gc_running_threads;
943     RELEASE_LOCK(&gc_running_mutex);
944     return n_running;
945 }
946
947 static nat
948 dec_running (void)
949 {
950     nat n_running;
951     ACQUIRE_LOCK(&gc_running_mutex);
952     n_running = --gc_running_threads;
953     RELEASE_LOCK(&gc_running_mutex);
954     return n_running;
955 }
956
957 //
958 // gc_thread_work(): Scavenge until there's no work left to do and all
959 // the running threads are idle.
960 //
961 static void
962 gc_thread_work (void)
963 {
964     nat r;
965         
966     debugTrace(DEBUG_gc, "GC thread %d working", gct->thread_index);
967
968     // gc_running_threads has already been incremented for us; either
969     // this is the main thread and we incremented it inside
970     // GarbageCollect(), or this is a worker thread and the main
971     // thread bumped gc_running_threads before waking us up.
972
973 loop:
974     scavenge_loop();
975     // scavenge_loop() only exits when there's no work to do
976     r = dec_running();
977     
978     debugTrace(DEBUG_gc, "GC thread %d idle (%d still running)", 
979                gct->thread_index, r);
980
981     while (gc_running_threads != 0) {
982         if (any_work()) {
983             inc_running();
984             goto loop;
985         }
986         // any_work() does not remove the work from the queue, it
987         // just checks for the presence of work.  If we find any,
988         // then we increment gc_running_threads and go back to 
989         // scavenge_loop() to perform any pending work.
990     }
991     
992     // All threads are now stopped
993     debugTrace(DEBUG_gc, "GC thread %d finished.", gct->thread_index);
994 }
995
996
997 #if defined(THREADED_RTS)
998 static void
999 gc_thread_mainloop (void)
1000 {
1001     while (!gct->exit) {
1002
1003         // Wait until we're told to wake up
1004         ACQUIRE_LOCK(&gct->wake_mutex);
1005         while (!gct->wakeup) {
1006             debugTrace(DEBUG_gc, "GC thread %d standing by...", 
1007                        gct->thread_index);
1008             waitCondition(&gct->wake_cond, &gct->wake_mutex);
1009         }
1010         RELEASE_LOCK(&gct->wake_mutex);
1011         gct->wakeup = rtsFalse;
1012         if (gct->exit) break;
1013
1014         gc_thread_work();
1015     }
1016 }       
1017 #endif
1018
1019 #if defined(THREADED_RTS)
1020 static void
1021 gc_thread_entry (gc_thread *my_gct)
1022 {
1023     gct = my_gct;
1024     debugTrace(DEBUG_gc, "GC thread %d starting...", gct->thread_index);
1025     gct->id = osThreadId();
1026     gc_thread_mainloop();
1027 }
1028 #endif
1029
1030 static void
1031 start_gc_threads (void)
1032 {
1033 #if defined(THREADED_RTS)
1034     nat i;
1035     OSThreadId id;
1036     static rtsBool done = rtsFalse;
1037
1038     gc_running_threads = 0;
1039     initMutex(&gc_running_mutex);
1040
1041     if (!done) {
1042         // Start from 1: the main thread is 0
1043         for (i = 1; i < RtsFlags.ParFlags.gcThreads; i++) {
1044             createOSThread(&id, (OSThreadProc*)&gc_thread_entry, 
1045                            &gc_threads[i]);
1046         }
1047         done = rtsTrue;
1048     }
1049 #endif
1050 }
1051
1052 static void
1053 wakeup_gc_threads (nat n_threads USED_IF_THREADS)
1054 {
1055 #if defined(THREADED_RTS)
1056     nat i;
1057     for (i=1; i < n_threads; i++) {
1058         inc_running();
1059         ACQUIRE_LOCK(&gc_threads[i].wake_mutex);
1060         gc_threads[i].wakeup = rtsTrue;
1061         signalCondition(&gc_threads[i].wake_cond);
1062         RELEASE_LOCK(&gc_threads[i].wake_mutex);
1063     }
1064 #endif
1065 }
1066
1067 /* ----------------------------------------------------------------------------
1068    Initialise a generation that is to be collected 
1069    ------------------------------------------------------------------------- */
1070
1071 static void
1072 init_collected_gen (nat g, nat n_threads)
1073 {
1074     nat s, t, i;
1075     step_workspace *ws;
1076     step *stp;
1077     bdescr *bd;
1078
1079     // Throw away the current mutable list.  Invariant: the mutable
1080     // list always has at least one block; this means we can avoid a
1081     // check for NULL in recordMutable().
1082     if (g != 0) {
1083         freeChain(generations[g].mut_list);
1084         generations[g].mut_list = allocBlock();
1085         for (i = 0; i < n_capabilities; i++) {
1086             freeChain(capabilities[i].mut_lists[g]);
1087             capabilities[i].mut_lists[g] = allocBlock();
1088         }
1089     }
1090
1091     for (s = 0; s < generations[g].n_steps; s++) {
1092
1093         // generation 0, step 0 doesn't need to-space 
1094         if (g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1) { 
1095             continue; 
1096         }
1097         
1098         stp = &generations[g].steps[s];
1099         ASSERT(stp->gen_no == g);
1100
1101         // deprecate the existing blocks
1102         stp->old_blocks   = stp->blocks;
1103         stp->n_old_blocks = stp->n_blocks;
1104         stp->blocks       = NULL;
1105         stp->n_blocks     = 0;
1106
1107         // we don't have any to-be-scavenged blocks yet
1108         stp->todos = NULL;
1109         stp->n_todos = 0;
1110
1111         // initialise the large object queues.
1112         stp->scavenged_large_objects = NULL;
1113         stp->n_scavenged_large_blocks = 0;
1114
1115         // mark the large objects as not evacuated yet 
1116         for (bd = stp->large_objects; bd; bd = bd->link) {
1117             bd->flags &= ~BF_EVACUATED;
1118         }
1119
1120         // for a compacted step, we need to allocate the bitmap
1121         if (stp->is_compacted) {
1122             nat bitmap_size; // in bytes
1123             bdescr *bitmap_bdescr;
1124             StgWord *bitmap;
1125             
1126             bitmap_size = stp->n_old_blocks * BLOCK_SIZE / (sizeof(W_)*BITS_PER_BYTE);
1127             
1128             if (bitmap_size > 0) {
1129                 bitmap_bdescr = allocGroup((lnat)BLOCK_ROUND_UP(bitmap_size) 
1130                                            / BLOCK_SIZE);
1131                 stp->bitmap = bitmap_bdescr;
1132                 bitmap = bitmap_bdescr->start;
1133                 
1134                 debugTrace(DEBUG_gc, "bitmap_size: %d, bitmap: %p",
1135                            bitmap_size, bitmap);
1136                 
1137                 // don't forget to fill it with zeros!
1138                 memset(bitmap, 0, bitmap_size);
1139                 
1140                 // For each block in this step, point to its bitmap from the
1141                 // block descriptor.
1142                 for (bd=stp->old_blocks; bd != NULL; bd = bd->link) {
1143                     bd->u.bitmap = bitmap;
1144                     bitmap += BLOCK_SIZE_W / (sizeof(W_)*BITS_PER_BYTE);
1145                     
1146                     // Also at this point we set the BF_COMPACTED flag
1147                     // for this block.  The invariant is that
1148                     // BF_COMPACTED is always unset, except during GC
1149                     // when it is set on those blocks which will be
1150                     // compacted.
1151                     bd->flags |= BF_COMPACTED;
1152                 }
1153             }
1154         }
1155     }
1156
1157     // For each GC thread, for each step, allocate a "todo" block to
1158     // store evacuated objects to be scavenged, and a block to store
1159     // evacuated objects that do not need to be scavenged.
1160     for (t = 0; t < n_threads; t++) {
1161         for (s = 0; s < generations[g].n_steps; s++) {
1162
1163             // we don't copy objects into g0s0, unless -G0
1164             if (g==0 && s==0 && RtsFlags.GcFlags.generations > 1) continue;
1165
1166             ws = &gc_threads[t].steps[g][s];
1167
1168             ws->scan_bd = NULL;
1169             ws->scan = NULL;
1170
1171             ws->todo_large_objects = NULL;
1172
1173             // allocate the first to-space block; extra blocks will be
1174             // chained on as necessary.
1175             ws->todo_bd = NULL;
1176             ws->buffer_todo_bd = NULL;
1177             gc_alloc_todo_block(ws);
1178
1179             ws->scavd_list = NULL;
1180             ws->n_scavd_blocks = 0;
1181         }
1182     }
1183 }
1184
1185
1186 /* ----------------------------------------------------------------------------
1187    Initialise a generation that is *not* to be collected 
1188    ------------------------------------------------------------------------- */
1189
1190 static void
1191 init_uncollected_gen (nat g, nat threads)
1192 {
1193     nat s, t, i;
1194     step_workspace *ws;
1195     step *stp;
1196     bdescr *bd;
1197
1198     for (s = 0; s < generations[g].n_steps; s++) {
1199         stp = &generations[g].steps[s];
1200         stp->scavenged_large_objects = NULL;
1201         stp->n_scavenged_large_blocks = 0;
1202     }
1203     
1204     for (t = 0; t < threads; t++) {
1205         for (s = 0; s < generations[g].n_steps; s++) {
1206             
1207             ws = &gc_threads[t].steps[g][s];
1208             stp = ws->stp;
1209             
1210             ws->buffer_todo_bd = NULL;
1211             ws->todo_large_objects = NULL;
1212
1213             ws->scavd_list = NULL;
1214             ws->n_scavd_blocks = 0;
1215
1216             // If the block at the head of the list in this generation
1217             // is less than 3/4 full, then use it as a todo block.
1218             if (isPartiallyFull(stp->blocks))
1219             {
1220                 ws->todo_bd = stp->blocks;
1221                 stp->blocks = stp->blocks->link;
1222                 stp->n_blocks -= 1;
1223                 ws->todo_bd->link = NULL;
1224
1225                 // this block is also the scan block; we must scan
1226                 // from the current end point.
1227                 ws->scan_bd = ws->todo_bd;
1228                 ws->scan = ws->scan_bd->free;
1229
1230                 // subtract the contents of this block from the stats,
1231                 // because we'll count the whole block later.
1232                 copied -= ws->scan_bd->free - ws->scan_bd->start;
1233             } 
1234             else
1235             {
1236                 ws->scan_bd = NULL;
1237                 ws->scan = NULL;
1238                 ws->todo_bd = NULL;
1239                 gc_alloc_todo_block(ws);
1240             }
1241         }
1242     }
1243
1244     // Move the private mutable lists from each capability onto the
1245     // main mutable list for the generation.
1246     for (i = 0; i < n_capabilities; i++) {
1247         for (bd = capabilities[i].mut_lists[g]; 
1248              bd->link != NULL; bd = bd->link) {
1249             /* nothing */
1250         }
1251         bd->link = generations[g].mut_list;
1252         generations[g].mut_list = capabilities[i].mut_lists[g];
1253         capabilities[i].mut_lists[g] = allocBlock();
1254     }
1255 }
1256
1257 /* -----------------------------------------------------------------------------
1258    Initialise a gc_thread before GC
1259    -------------------------------------------------------------------------- */
1260
1261 static void
1262 init_gc_thread (gc_thread *t)
1263 {
1264     t->evac_step = 0;
1265     t->failed_to_evac = rtsFalse;
1266     t->eager_promotion = rtsTrue;
1267     t->thunk_selector_depth = 0;
1268 }
1269
1270 /* -----------------------------------------------------------------------------
1271    Function we pass to GetRoots to evacuate roots.
1272    -------------------------------------------------------------------------- */
1273
1274 static void
1275 mark_root(StgClosure **root)
1276 {
1277   evacuate(root);
1278 }
1279
1280 /* -----------------------------------------------------------------------------
1281    Initialising the static object & mutable lists
1282    -------------------------------------------------------------------------- */
1283
1284 static void
1285 zero_static_object_list(StgClosure* first_static)
1286 {
1287   StgClosure* p;
1288   StgClosure* link;
1289   const StgInfoTable *info;
1290
1291   for (p = first_static; p != END_OF_STATIC_LIST; p = link) {
1292     info = get_itbl(p);
1293     link = *STATIC_LINK(info, p);
1294     *STATIC_LINK(info,p) = NULL;
1295   }
1296 }
1297
1298 /* -----------------------------------------------------------------------------
1299    Reverting CAFs
1300    -------------------------------------------------------------------------- */
1301
1302 void
1303 revertCAFs( void )
1304 {
1305     StgIndStatic *c;
1306
1307     for (c = (StgIndStatic *)revertible_caf_list; c != NULL; 
1308          c = (StgIndStatic *)c->static_link) 
1309     {
1310         SET_INFO(c, c->saved_info);
1311         c->saved_info = NULL;
1312         // could, but not necessary: c->static_link = NULL; 
1313     }
1314     revertible_caf_list = NULL;
1315 }
1316
1317 void
1318 markCAFs( evac_fn evac )
1319 {
1320     StgIndStatic *c;
1321
1322     for (c = (StgIndStatic *)caf_list; c != NULL; 
1323          c = (StgIndStatic *)c->static_link) 
1324     {
1325         evac(&c->indirectee);
1326     }
1327     for (c = (StgIndStatic *)revertible_caf_list; c != NULL; 
1328          c = (StgIndStatic *)c->static_link) 
1329     {
1330         evac(&c->indirectee);
1331     }
1332 }
1333
1334 /* ----------------------------------------------------------------------------
1335    Update the pointers from the task list
1336
1337    These are treated as weak pointers because we want to allow a main
1338    thread to get a BlockedOnDeadMVar exception in the same way as any
1339    other thread.  Note that the threads should all have been retained
1340    by GC by virtue of being on the all_threads list, we're just
1341    updating pointers here.
1342    ------------------------------------------------------------------------- */
1343
1344 static void
1345 update_task_list (void)
1346 {
1347     Task *task;
1348     StgTSO *tso;
1349     for (task = all_tasks; task != NULL; task = task->all_link) {
1350         if (!task->stopped && task->tso) {
1351             ASSERT(task->tso->bound == task);
1352             tso = (StgTSO *) isAlive((StgClosure *)task->tso);
1353             if (tso == NULL) {
1354                 barf("task %p: main thread %d has been GC'd", 
1355 #ifdef THREADED_RTS
1356                      (void *)task->id, 
1357 #else
1358                      (void *)task,
1359 #endif
1360                      task->tso->id);
1361             }
1362             task->tso = tso;
1363         }
1364     }
1365 }
1366
1367 /* ----------------------------------------------------------------------------
1368    Reset the sizes of the older generations when we do a major
1369    collection.
1370   
1371    CURRENT STRATEGY: make all generations except zero the same size.
1372    We have to stay within the maximum heap size, and leave a certain
1373    percentage of the maximum heap size available to allocate into.
1374    ------------------------------------------------------------------------- */
1375
1376 static void
1377 resize_generations (void)
1378 {
1379     nat g;
1380
1381     if (major_gc && RtsFlags.GcFlags.generations > 1) {
1382         nat live, size, min_alloc;
1383         nat max  = RtsFlags.GcFlags.maxHeapSize;
1384         nat gens = RtsFlags.GcFlags.generations;
1385         
1386         // live in the oldest generations
1387         live = oldest_gen->steps[0].n_blocks +
1388             oldest_gen->steps[0].n_large_blocks;
1389         
1390         // default max size for all generations except zero
1391         size = stg_max(live * RtsFlags.GcFlags.oldGenFactor,
1392                        RtsFlags.GcFlags.minOldGenSize);
1393         
1394         // minimum size for generation zero
1395         min_alloc = stg_max((RtsFlags.GcFlags.pcFreeHeap * max) / 200,
1396                             RtsFlags.GcFlags.minAllocAreaSize);
1397
1398         // Auto-enable compaction when the residency reaches a
1399         // certain percentage of the maximum heap size (default: 30%).
1400         if (RtsFlags.GcFlags.generations > 1 &&
1401             (RtsFlags.GcFlags.compact ||
1402              (max > 0 &&
1403               oldest_gen->steps[0].n_blocks > 
1404               (RtsFlags.GcFlags.compactThreshold * max) / 100))) {
1405             oldest_gen->steps[0].is_compacted = 1;
1406 //        debugBelch("compaction: on\n", live);
1407         } else {
1408             oldest_gen->steps[0].is_compacted = 0;
1409 //        debugBelch("compaction: off\n", live);
1410         }
1411
1412         // if we're going to go over the maximum heap size, reduce the
1413         // size of the generations accordingly.  The calculation is
1414         // different if compaction is turned on, because we don't need
1415         // to double the space required to collect the old generation.
1416         if (max != 0) {
1417             
1418             // this test is necessary to ensure that the calculations
1419             // below don't have any negative results - we're working
1420             // with unsigned values here.
1421             if (max < min_alloc) {
1422                 heapOverflow();
1423             }
1424             
1425             if (oldest_gen->steps[0].is_compacted) {
1426                 if ( (size + (size - 1) * (gens - 2) * 2) + min_alloc > max ) {
1427                     size = (max - min_alloc) / ((gens - 1) * 2 - 1);
1428                 }
1429             } else {
1430                 if ( (size * (gens - 1) * 2) + min_alloc > max ) {
1431                     size = (max - min_alloc) / ((gens - 1) * 2);
1432                 }
1433             }
1434             
1435             if (size < live) {
1436                 heapOverflow();
1437             }
1438         }
1439         
1440 #if 0
1441         debugBelch("live: %d, min_alloc: %d, size : %d, max = %d\n", live,
1442                    min_alloc, size, max);
1443 #endif
1444         
1445         for (g = 0; g < gens; g++) {
1446             generations[g].max_blocks = size;
1447         }
1448     }
1449 }
1450
1451 /* -----------------------------------------------------------------------------
1452    Calculate the new size of the nursery, and resize it.
1453    -------------------------------------------------------------------------- */
1454
1455 static void
1456 resize_nursery (void)
1457 {
1458     if (RtsFlags.GcFlags.generations == 1)
1459     {   // Two-space collector:
1460         nat blocks;
1461     
1462         /* set up a new nursery.  Allocate a nursery size based on a
1463          * function of the amount of live data (by default a factor of 2)
1464          * Use the blocks from the old nursery if possible, freeing up any
1465          * left over blocks.
1466          *
1467          * If we get near the maximum heap size, then adjust our nursery
1468          * size accordingly.  If the nursery is the same size as the live
1469          * data (L), then we need 3L bytes.  We can reduce the size of the
1470          * nursery to bring the required memory down near 2L bytes.
1471          * 
1472          * A normal 2-space collector would need 4L bytes to give the same
1473          * performance we get from 3L bytes, reducing to the same
1474          * performance at 2L bytes.
1475          */
1476         blocks = g0s0->n_old_blocks;
1477         
1478         if ( RtsFlags.GcFlags.maxHeapSize != 0 &&
1479              blocks * RtsFlags.GcFlags.oldGenFactor * 2 > 
1480              RtsFlags.GcFlags.maxHeapSize )
1481         {
1482             long adjusted_blocks;  // signed on purpose 
1483             int pc_free; 
1484             
1485             adjusted_blocks = (RtsFlags.GcFlags.maxHeapSize - 2 * blocks);
1486             
1487             debugTrace(DEBUG_gc, "near maximum heap size of 0x%x blocks, blocks = %d, adjusted to %ld", 
1488                        RtsFlags.GcFlags.maxHeapSize, blocks, adjusted_blocks);
1489             
1490             pc_free = adjusted_blocks * 100 / RtsFlags.GcFlags.maxHeapSize;
1491             if (pc_free < RtsFlags.GcFlags.pcFreeHeap) /* might even * be < 0 */
1492             {
1493                 heapOverflow();
1494             }
1495             blocks = adjusted_blocks;
1496         }
1497         else
1498         {
1499             blocks *= RtsFlags.GcFlags.oldGenFactor;
1500             if (blocks < RtsFlags.GcFlags.minAllocAreaSize)
1501             {
1502                 blocks = RtsFlags.GcFlags.minAllocAreaSize;
1503             }
1504         }
1505         resizeNurseries(blocks);
1506     }
1507     else  // Generational collector
1508     {
1509         /* 
1510          * If the user has given us a suggested heap size, adjust our
1511          * allocation area to make best use of the memory available.
1512          */
1513         if (RtsFlags.GcFlags.heapSizeSuggestion)
1514         {
1515             long blocks;
1516             nat needed = calcNeeded();  // approx blocks needed at next GC 
1517             
1518             /* Guess how much will be live in generation 0 step 0 next time.
1519              * A good approximation is obtained by finding the
1520              * percentage of g0s0 that was live at the last minor GC.
1521              *
1522              * We have an accurate figure for the amount of copied data in
1523              * 'copied', but we must convert this to a number of blocks, with
1524              * a small adjustment for estimated slop at the end of a block
1525              * (- 10 words).
1526              */
1527             if (N == 0)
1528             {
1529                 g0s0_pcnt_kept = ((copied / (BLOCK_SIZE_W - 10)) * 100)
1530                     / countNurseryBlocks();
1531             }
1532             
1533             /* Estimate a size for the allocation area based on the
1534              * information available.  We might end up going slightly under
1535              * or over the suggested heap size, but we should be pretty
1536              * close on average.
1537              *
1538              * Formula:            suggested - needed
1539              *                ----------------------------
1540              *                    1 + g0s0_pcnt_kept/100
1541              *
1542              * where 'needed' is the amount of memory needed at the next
1543              * collection for collecting all steps except g0s0.
1544              */
1545             blocks = 
1546                 (((long)RtsFlags.GcFlags.heapSizeSuggestion - (long)needed) * 100) /
1547                 (100 + (long)g0s0_pcnt_kept);
1548             
1549             if (blocks < (long)RtsFlags.GcFlags.minAllocAreaSize) {
1550                 blocks = RtsFlags.GcFlags.minAllocAreaSize;
1551             }
1552             
1553             resizeNurseries((nat)blocks);
1554         }
1555         else
1556         {
1557             // we might have added extra large blocks to the nursery, so
1558             // resize back to minAllocAreaSize again.
1559             resizeNurseriesFixed(RtsFlags.GcFlags.minAllocAreaSize);
1560         }
1561     }
1562 }
1563
1564 /* -----------------------------------------------------------------------------
1565    Sanity code for CAF garbage collection.
1566
1567    With DEBUG turned on, we manage a CAF list in addition to the SRT
1568    mechanism.  After GC, we run down the CAF list and blackhole any
1569    CAFs which have been garbage collected.  This means we get an error
1570    whenever the program tries to enter a garbage collected CAF.
1571
1572    Any garbage collected CAFs are taken off the CAF list at the same
1573    time. 
1574    -------------------------------------------------------------------------- */
1575
1576 #if 0 && defined(DEBUG)
1577
1578 static void
1579 gcCAFs(void)
1580 {
1581   StgClosure*  p;
1582   StgClosure** pp;
1583   const StgInfoTable *info;
1584   nat i;
1585
1586   i = 0;
1587   p = caf_list;
1588   pp = &caf_list;
1589
1590   while (p != NULL) {
1591     
1592     info = get_itbl(p);
1593
1594     ASSERT(info->type == IND_STATIC);
1595
1596     if (STATIC_LINK(info,p) == NULL) {
1597         debugTrace(DEBUG_gccafs, "CAF gc'd at 0x%04lx", (long)p);
1598         // black hole it 
1599         SET_INFO(p,&stg_BLACKHOLE_info);
1600         p = STATIC_LINK2(info,p);
1601         *pp = p;
1602     }
1603     else {
1604       pp = &STATIC_LINK2(info,p);
1605       p = *pp;
1606       i++;
1607     }
1608
1609   }
1610
1611   debugTrace(DEBUG_gccafs, "%d CAFs live", i); 
1612 }
1613 #endif