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