Use mutator threads to do GC, instead of having a separate pool of GC threads
[ghc-hetmet.git] / rts / sm / Storage.c
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2008
4  *
5  * Storage manager front end
6  *
7  * Documentation on the architecture of the Storage Manager can be
8  * found in the online commentary:
9  * 
10  *   http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage
11  *
12  * ---------------------------------------------------------------------------*/
13
14 #include "PosixSource.h"
15 #include "Rts.h"
16 #include "RtsUtils.h"
17 #include "RtsFlags.h"
18 #include "Stats.h"
19 #include "Hooks.h"
20 #include "BlockAlloc.h"
21 #include "MBlock.h"
22 #include "Weak.h"
23 #include "Sanity.h"
24 #include "Arena.h"
25 #include "OSThreads.h"
26 #include "Capability.h"
27 #include "Storage.h"
28 #include "Schedule.h"
29 #include "RetainerProfile.h"    // for counting memory blocks (memInventory)
30 #include "OSMem.h"
31 #include "Trace.h"
32 #include "GC.h"
33 #include "Evac.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "ffi.h"
39
40 /* 
41  * All these globals require sm_mutex to access in THREADED_RTS mode.
42  */
43 StgClosure    *caf_list         = NULL;
44 StgClosure    *revertible_caf_list = NULL;
45 rtsBool       keepCAFs;
46
47 bdescr *pinned_object_block;    /* allocate pinned objects into this block */
48 nat alloc_blocks;               /* number of allocate()d blocks since GC */
49 nat alloc_blocks_lim;           /* approximate limit on alloc_blocks */
50
51 static bdescr *exec_block;
52
53 generation *generations = NULL; /* all the generations */
54 generation *g0          = NULL; /* generation 0, for convenience */
55 generation *oldest_gen  = NULL; /* oldest generation, for convenience */
56 step *g0s0              = NULL; /* generation 0, step 0, for convenience */
57
58 nat total_steps         = 0;
59 step *all_steps         = NULL; /* single array of steps */
60
61 ullong total_allocated = 0;     /* total memory allocated during run */
62
63 nat n_nurseries         = 0;    /* == RtsFlags.ParFlags.nNodes, convenience */
64 step *nurseries         = NULL; /* array of nurseries, >1 only if THREADED_RTS */
65
66 #ifdef THREADED_RTS
67 /*
68  * Storage manager mutex:  protects all the above state from
69  * simultaneous access by two STG threads.
70  */
71 Mutex sm_mutex;
72 /*
73  * This mutex is used by atomicModifyMutVar# only
74  */
75 Mutex atomic_modify_mutvar_mutex;
76 #endif
77
78
79 /*
80  * Forward references
81  */
82 static void *stgAllocForGMP   (size_t size_in_bytes);
83 static void *stgReallocForGMP (void *ptr, size_t old_size, size_t new_size);
84 static void  stgDeallocForGMP (void *ptr, size_t size);
85
86 static void
87 initStep (step *stp, int g, int s)
88 {
89     stp->no = s;
90     stp->abs_no = RtsFlags.GcFlags.steps * g + s;
91     stp->blocks = NULL;
92     stp->n_blocks = 0;
93     stp->n_words = 0;
94     stp->live_estimate = 0;
95     stp->old_blocks = NULL;
96     stp->n_old_blocks = 0;
97     stp->gen = &generations[g];
98     stp->gen_no = g;
99     stp->large_objects = NULL;
100     stp->n_large_blocks = 0;
101     stp->scavenged_large_objects = NULL;
102     stp->n_scavenged_large_blocks = 0;
103     stp->mark = 0;
104     stp->compact = 0;
105     stp->bitmap = NULL;
106 #ifdef THREADED_RTS
107     initSpinLock(&stp->sync_todo);
108     initSpinLock(&stp->sync_large_objects);
109 #endif
110     stp->threads = END_TSO_QUEUE;
111     stp->old_threads = END_TSO_QUEUE;
112 }
113
114 void
115 initStorage( void )
116 {
117   nat g, s;
118   generation *gen;
119
120   if (generations != NULL) {
121       // multi-init protection
122       return;
123   }
124
125   initMBlocks();
126
127   /* Sanity check to make sure the LOOKS_LIKE_ macros appear to be
128    * doing something reasonable.
129    */
130   /* We use the NOT_NULL variant or gcc warns that the test is always true */
131   ASSERT(LOOKS_LIKE_INFO_PTR_NOT_NULL((StgWord)&stg_BLACKHOLE_info));
132   ASSERT(LOOKS_LIKE_CLOSURE_PTR(&stg_dummy_ret_closure));
133   ASSERT(!HEAP_ALLOCED(&stg_dummy_ret_closure));
134   
135   if (RtsFlags.GcFlags.maxHeapSize != 0 &&
136       RtsFlags.GcFlags.heapSizeSuggestion > 
137       RtsFlags.GcFlags.maxHeapSize) {
138     RtsFlags.GcFlags.maxHeapSize = RtsFlags.GcFlags.heapSizeSuggestion;
139   }
140
141   if (RtsFlags.GcFlags.maxHeapSize != 0 &&
142       RtsFlags.GcFlags.minAllocAreaSize > 
143       RtsFlags.GcFlags.maxHeapSize) {
144       errorBelch("maximum heap size (-M) is smaller than minimum alloc area size (-A)");
145       RtsFlags.GcFlags.minAllocAreaSize = RtsFlags.GcFlags.maxHeapSize;
146   }
147
148   initBlockAllocator();
149   
150 #if defined(THREADED_RTS)
151   initMutex(&sm_mutex);
152   initMutex(&atomic_modify_mutvar_mutex);
153 #endif
154
155   ACQUIRE_SM_LOCK;
156
157   /* allocate generation info array */
158   generations = (generation *)stgMallocBytes(RtsFlags.GcFlags.generations 
159                                              * sizeof(struct generation_),
160                                              "initStorage: gens");
161
162   /* allocate all the steps into an array.  It is important that we do
163      it this way, because we need the invariant that two step pointers
164      can be directly compared to see which is the oldest.
165      Remember that the last generation has only one step. */
166   total_steps = 1 + (RtsFlags.GcFlags.generations - 1) * RtsFlags.GcFlags.steps;
167   all_steps   = stgMallocBytes(total_steps * sizeof(struct step_),
168                                "initStorage: steps");
169
170   /* Initialise all generations */
171   for(g = 0; g < RtsFlags.GcFlags.generations; g++) {
172     gen = &generations[g];
173     gen->no = g;
174     gen->mut_list = allocBlock();
175     gen->collections = 0;
176     gen->par_collections = 0;
177     gen->failed_promotions = 0;
178     gen->max_blocks = 0;
179   }
180
181   /* A couple of convenience pointers */
182   g0 = &generations[0];
183   oldest_gen = &generations[RtsFlags.GcFlags.generations-1];
184
185   /* Allocate step structures in each generation */
186   if (RtsFlags.GcFlags.generations > 1) {
187     /* Only for multiple-generations */
188
189     /* Oldest generation: one step */
190     oldest_gen->n_steps = 1;
191     oldest_gen->steps   = all_steps + (RtsFlags.GcFlags.generations - 1)
192                                       * RtsFlags.GcFlags.steps;
193
194     /* set up all except the oldest generation with 2 steps */
195     for(g = 0; g < RtsFlags.GcFlags.generations-1; g++) {
196       generations[g].n_steps = RtsFlags.GcFlags.steps;
197       generations[g].steps   = all_steps + g * RtsFlags.GcFlags.steps;
198     }
199     
200   } else {
201     /* single generation, i.e. a two-space collector */
202     g0->n_steps = 1;
203     g0->steps   = all_steps;
204   }
205
206 #ifdef THREADED_RTS
207   n_nurseries = n_capabilities;
208 #else
209   n_nurseries = 1;
210 #endif
211   nurseries = stgMallocBytes (n_nurseries * sizeof(struct step_),
212                               "initStorage: nurseries");
213
214   /* Initialise all steps */
215   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
216     for (s = 0; s < generations[g].n_steps; s++) {
217         initStep(&generations[g].steps[s], g, s);
218     }
219   }
220   
221   for (s = 0; s < n_nurseries; s++) {
222       initStep(&nurseries[s], 0, s);
223   }
224   
225   /* Set up the destination pointers in each younger gen. step */
226   for (g = 0; g < RtsFlags.GcFlags.generations-1; g++) {
227     for (s = 0; s < generations[g].n_steps-1; s++) {
228       generations[g].steps[s].to = &generations[g].steps[s+1];
229     }
230     generations[g].steps[s].to = &generations[g+1].steps[0];
231   }
232   oldest_gen->steps[0].to = &oldest_gen->steps[0];
233   
234   for (s = 0; s < n_nurseries; s++) {
235       nurseries[s].to = generations[0].steps[0].to;
236   }
237   
238   /* The oldest generation has one step. */
239   if (RtsFlags.GcFlags.compact || RtsFlags.GcFlags.sweep) {
240       if (RtsFlags.GcFlags.generations == 1) {
241           errorBelch("WARNING: compact/sweep is incompatible with -G1; disabled");
242       } else {
243           oldest_gen->steps[0].mark = 1;
244           if (RtsFlags.GcFlags.compact)
245               oldest_gen->steps[0].compact = 1;
246       }
247   }
248
249   generations[0].max_blocks = 0;
250   g0s0 = &generations[0].steps[0];
251
252   /* The allocation area.  Policy: keep the allocation area
253    * small to begin with, even if we have a large suggested heap
254    * size.  Reason: we're going to do a major collection first, and we
255    * don't want it to be a big one.  This vague idea is borne out by 
256    * rigorous experimental evidence.
257    */
258   allocNurseries();
259
260   weak_ptr_list = NULL;
261   caf_list = NULL;
262   revertible_caf_list = NULL;
263    
264   /* initialise the allocate() interface */
265   alloc_blocks = 0;
266   alloc_blocks_lim = RtsFlags.GcFlags.minAllocAreaSize;
267
268   exec_block = NULL;
269
270   /* Tell GNU multi-precision pkg about our custom alloc functions */
271   mp_set_memory_functions(stgAllocForGMP, stgReallocForGMP, stgDeallocForGMP);
272
273 #ifdef THREADED_RTS
274   initSpinLock(&gc_alloc_block_sync);
275   initSpinLock(&recordMutableGen_sync);
276   whitehole_spin = 0;
277 #endif
278
279   N = 0;
280
281   initGcThreads();
282
283   IF_DEBUG(gc, statDescribeGens());
284
285   RELEASE_SM_LOCK;
286 }
287
288 void
289 exitStorage (void)
290 {
291     stat_exit(calcAllocated());
292 }
293
294 void
295 freeStorage (void)
296 {
297     stgFree(g0s0); // frees all the steps
298     stgFree(generations);
299     freeAllMBlocks();
300 #if defined(THREADED_RTS)
301     closeMutex(&sm_mutex);
302     closeMutex(&atomic_modify_mutvar_mutex);
303 #endif
304     stgFree(nurseries);
305 }
306
307 /* -----------------------------------------------------------------------------
308    CAF management.
309
310    The entry code for every CAF does the following:
311      
312       - builds a CAF_BLACKHOLE in the heap
313       - pushes an update frame pointing to the CAF_BLACKHOLE
314       - invokes UPD_CAF(), which:
315           - calls newCaf, below
316           - updates the CAF with a static indirection to the CAF_BLACKHOLE
317       
318    Why do we build a BLACKHOLE in the heap rather than just updating
319    the thunk directly?  It's so that we only need one kind of update
320    frame - otherwise we'd need a static version of the update frame too.
321
322    newCaf() does the following:
323        
324       - it puts the CAF on the oldest generation's mut-once list.
325         This is so that we can treat the CAF as a root when collecting
326         younger generations.
327
328    For GHCI, we have additional requirements when dealing with CAFs:
329
330       - we must *retain* all dynamically-loaded CAFs ever entered,
331         just in case we need them again.
332       - we must be able to *revert* CAFs that have been evaluated, to
333         their pre-evaluated form.
334
335       To do this, we use an additional CAF list.  When newCaf() is
336       called on a dynamically-loaded CAF, we add it to the CAF list
337       instead of the old-generation mutable list, and save away its
338       old info pointer (in caf->saved_info) for later reversion.
339
340       To revert all the CAFs, we traverse the CAF list and reset the
341       info pointer to caf->saved_info, then throw away the CAF list.
342       (see GC.c:revertCAFs()).
343
344       -- SDM 29/1/01
345
346    -------------------------------------------------------------------------- */
347
348 void
349 newCAF(StgClosure* caf)
350 {
351   ACQUIRE_SM_LOCK;
352
353   if(keepCAFs)
354   {
355     // HACK:
356     // If we are in GHCi _and_ we are using dynamic libraries,
357     // then we can't redirect newCAF calls to newDynCAF (see below),
358     // so we make newCAF behave almost like newDynCAF.
359     // The dynamic libraries might be used by both the interpreted
360     // program and GHCi itself, so they must not be reverted.
361     // This also means that in GHCi with dynamic libraries, CAFs are not
362     // garbage collected. If this turns out to be a problem, we could
363     // do another hack here and do an address range test on caf to figure
364     // out whether it is from a dynamic library.
365     ((StgIndStatic *)caf)->saved_info  = (StgInfoTable *)caf->header.info;
366     ((StgIndStatic *)caf)->static_link = caf_list;
367     caf_list = caf;
368   }
369   else
370   {
371     /* Put this CAF on the mutable list for the old generation.
372     * This is a HACK - the IND_STATIC closure doesn't really have
373     * a mut_link field, but we pretend it has - in fact we re-use
374     * the STATIC_LINK field for the time being, because when we
375     * come to do a major GC we won't need the mut_link field
376     * any more and can use it as a STATIC_LINK.
377     */
378     ((StgIndStatic *)caf)->saved_info = NULL;
379     recordMutableGen(caf, oldest_gen);
380   }
381   
382   RELEASE_SM_LOCK;
383 }
384
385 // An alternate version of newCaf which is used for dynamically loaded
386 // object code in GHCi.  In this case we want to retain *all* CAFs in
387 // the object code, because they might be demanded at any time from an
388 // expression evaluated on the command line.
389 // Also, GHCi might want to revert CAFs, so we add these to the
390 // revertible_caf_list.
391 //
392 // The linker hackily arranges that references to newCaf from dynamic
393 // code end up pointing to newDynCAF.
394 void
395 newDynCAF(StgClosure *caf)
396 {
397     ACQUIRE_SM_LOCK;
398
399     ((StgIndStatic *)caf)->saved_info  = (StgInfoTable *)caf->header.info;
400     ((StgIndStatic *)caf)->static_link = revertible_caf_list;
401     revertible_caf_list = caf;
402
403     RELEASE_SM_LOCK;
404 }
405
406 /* -----------------------------------------------------------------------------
407    Nursery management.
408    -------------------------------------------------------------------------- */
409
410 static bdescr *
411 allocNursery (step *stp, bdescr *tail, nat blocks)
412 {
413     bdescr *bd;
414     nat i;
415
416     // Allocate a nursery: we allocate fresh blocks one at a time and
417     // cons them on to the front of the list, not forgetting to update
418     // the back pointer on the tail of the list to point to the new block.
419     for (i=0; i < blocks; i++) {
420         // @LDV profiling
421         /*
422           processNursery() in LdvProfile.c assumes that every block group in
423           the nursery contains only a single block. So, if a block group is
424           given multiple blocks, change processNursery() accordingly.
425         */
426         bd = allocBlock();
427         bd->link = tail;
428         // double-link the nursery: we might need to insert blocks
429         if (tail != NULL) {
430             tail->u.back = bd;
431         }
432         bd->step = stp;
433         bd->gen_no = 0;
434         bd->flags = 0;
435         bd->free = bd->start;
436         tail = bd;
437     }
438     tail->u.back = NULL;
439     return tail;
440 }
441
442 static void
443 assignNurseriesToCapabilities (void)
444 {
445 #ifdef THREADED_RTS
446     nat i;
447
448     for (i = 0; i < n_nurseries; i++) {
449         capabilities[i].r.rNursery        = &nurseries[i];
450         capabilities[i].r.rCurrentNursery = nurseries[i].blocks;
451         capabilities[i].r.rCurrentAlloc   = NULL;
452     }
453 #else /* THREADED_RTS */
454     MainCapability.r.rNursery        = &nurseries[0];
455     MainCapability.r.rCurrentNursery = nurseries[0].blocks;
456     MainCapability.r.rCurrentAlloc   = NULL;
457 #endif
458 }
459
460 void
461 allocNurseries( void )
462
463     nat i;
464
465     for (i = 0; i < n_nurseries; i++) {
466         nurseries[i].blocks = 
467             allocNursery(&nurseries[i], NULL, 
468                          RtsFlags.GcFlags.minAllocAreaSize);
469         nurseries[i].n_blocks    = RtsFlags.GcFlags.minAllocAreaSize;
470         nurseries[i].old_blocks   = NULL;
471         nurseries[i].n_old_blocks = 0;
472     }
473     assignNurseriesToCapabilities();
474 }
475       
476 void
477 resetNurseries( void )
478 {
479     nat i;
480     bdescr *bd;
481     step *stp;
482
483     for (i = 0; i < n_nurseries; i++) {
484         stp = &nurseries[i];
485         for (bd = stp->blocks; bd; bd = bd->link) {
486             bd->free = bd->start;
487             ASSERT(bd->gen_no == 0);
488             ASSERT(bd->step == stp);
489             IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
490         }
491     }
492     assignNurseriesToCapabilities();
493 }
494
495 lnat
496 countNurseryBlocks (void)
497 {
498     nat i;
499     lnat blocks = 0;
500
501     for (i = 0; i < n_nurseries; i++) {
502         blocks += nurseries[i].n_blocks;
503     }
504     return blocks;
505 }
506
507 static void
508 resizeNursery ( step *stp, nat blocks )
509 {
510   bdescr *bd;
511   nat nursery_blocks;
512
513   nursery_blocks = stp->n_blocks;
514   if (nursery_blocks == blocks) return;
515
516   if (nursery_blocks < blocks) {
517       debugTrace(DEBUG_gc, "increasing size of nursery to %d blocks", 
518                  blocks);
519     stp->blocks = allocNursery(stp, stp->blocks, blocks-nursery_blocks);
520   } 
521   else {
522     bdescr *next_bd;
523     
524     debugTrace(DEBUG_gc, "decreasing size of nursery to %d blocks", 
525                blocks);
526
527     bd = stp->blocks;
528     while (nursery_blocks > blocks) {
529         next_bd = bd->link;
530         next_bd->u.back = NULL;
531         nursery_blocks -= bd->blocks; // might be a large block
532         freeGroup(bd);
533         bd = next_bd;
534     }
535     stp->blocks = bd;
536     // might have gone just under, by freeing a large block, so make
537     // up the difference.
538     if (nursery_blocks < blocks) {
539         stp->blocks = allocNursery(stp, stp->blocks, blocks-nursery_blocks);
540     }
541   }
542   
543   stp->n_blocks = blocks;
544   ASSERT(countBlocks(stp->blocks) == stp->n_blocks);
545 }
546
547 // 
548 // Resize each of the nurseries to the specified size.
549 //
550 void
551 resizeNurseriesFixed (nat blocks)
552 {
553     nat i;
554     for (i = 0; i < n_nurseries; i++) {
555         resizeNursery(&nurseries[i], blocks);
556     }
557 }
558
559 // 
560 // Resize the nurseries to the total specified size.
561 //
562 void
563 resizeNurseries (nat blocks)
564 {
565     // If there are multiple nurseries, then we just divide the number
566     // of available blocks between them.
567     resizeNurseriesFixed(blocks / n_nurseries);
568 }
569
570
571 /* -----------------------------------------------------------------------------
572    move_TSO is called to update the TSO structure after it has been
573    moved from one place to another.
574    -------------------------------------------------------------------------- */
575
576 void
577 move_TSO (StgTSO *src, StgTSO *dest)
578 {
579     ptrdiff_t diff;
580
581     // relocate the stack pointer... 
582     diff = (StgPtr)dest - (StgPtr)src; // In *words* 
583     dest->sp = (StgPtr)dest->sp + diff;
584 }
585
586 /* -----------------------------------------------------------------------------
587    The allocate() interface
588
589    allocateInGen() function allocates memory directly into a specific
590    generation.  It always succeeds, and returns a chunk of memory n
591    words long.  n can be larger than the size of a block if necessary,
592    in which case a contiguous block group will be allocated.
593
594    allocate(n) is equivalent to allocateInGen(g0).
595    -------------------------------------------------------------------------- */
596
597 StgPtr
598 allocateInGen (generation *g, lnat n)
599 {
600     step *stp;
601     bdescr *bd;
602     StgPtr ret;
603
604     ACQUIRE_SM_LOCK;
605     
606     TICK_ALLOC_HEAP_NOCTR(n);
607     CCS_ALLOC(CCCS,n);
608
609     stp = &g->steps[0];
610
611     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_))
612     {
613         lnat req_blocks =  (lnat)BLOCK_ROUND_UP(n*sizeof(W_)) / BLOCK_SIZE;
614
615         // Attempting to allocate an object larger than maxHeapSize
616         // should definitely be disallowed.  (bug #1791)
617         if (RtsFlags.GcFlags.maxHeapSize > 0 && 
618             req_blocks >= RtsFlags.GcFlags.maxHeapSize) {
619             heapOverflow();
620         }
621
622         bd = allocGroup(req_blocks);
623         dbl_link_onto(bd, &stp->large_objects);
624         stp->n_large_blocks += bd->blocks; // might be larger than req_blocks
625         alloc_blocks += bd->blocks;
626         bd->gen_no  = g->no;
627         bd->step = stp;
628         bd->flags = BF_LARGE;
629         bd->free = bd->start + n;
630         ret = bd->start;
631     }
632     else
633     {
634         // small allocation (<LARGE_OBJECT_THRESHOLD) */
635         bd = stp->blocks;
636         if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
637             bd = allocBlock();
638             bd->gen_no = g->no;
639             bd->step = stp;
640             bd->flags = 0;
641             bd->link = stp->blocks;
642             stp->blocks = bd;
643             stp->n_blocks++;
644             alloc_blocks++;
645         }
646         ret = bd->free;
647         bd->free += n;
648     }
649
650     RELEASE_SM_LOCK;
651
652     return ret;
653 }
654
655 StgPtr
656 allocate (lnat n)
657 {
658     return allocateInGen(g0,n);
659 }
660
661 lnat
662 allocatedBytes( void )
663 {
664     lnat allocated;
665
666     allocated = alloc_blocks * BLOCK_SIZE_W;
667     if (pinned_object_block != NULL) {
668         allocated -= (pinned_object_block->start + BLOCK_SIZE_W) - 
669             pinned_object_block->free;
670     }
671         
672     return allocated;
673 }
674
675 // split N blocks off the front of the given bdescr, returning the
676 // new block group.  We treat the remainder as if it
677 // had been freshly allocated in generation 0.
678 bdescr *
679 splitLargeBlock (bdescr *bd, nat blocks)
680 {
681     bdescr *new_bd;
682
683     // subtract the original number of blocks from the counter first
684     bd->step->n_large_blocks -= bd->blocks;
685
686     new_bd = splitBlockGroup (bd, blocks);
687
688     dbl_link_onto(new_bd, &g0s0->large_objects);
689     g0s0->n_large_blocks += new_bd->blocks;
690     new_bd->gen_no  = g0s0->no;
691     new_bd->step    = g0s0;
692     new_bd->flags   = BF_LARGE;
693     new_bd->free    = bd->free;
694     ASSERT(new_bd->free <= new_bd->start + new_bd->blocks * BLOCK_SIZE_W);
695
696     // add the new number of blocks to the counter.  Due to the gaps
697     // for block descriptor, new_bd->blocks + bd->blocks might not be
698     // equal to the original bd->blocks, which is why we do it this way.
699     bd->step->n_large_blocks += bd->blocks;
700
701     return new_bd;
702 }
703
704 /* -----------------------------------------------------------------------------
705    allocateLocal()
706
707    This allocates memory in the current thread - it is intended for
708    use primarily from STG-land where we have a Capability.  It is
709    better than allocate() because it doesn't require taking the
710    sm_mutex lock in the common case.
711
712    Memory is allocated directly from the nursery if possible (but not
713    from the current nursery block, so as not to interfere with
714    Hp/HpLim).
715    -------------------------------------------------------------------------- */
716
717 StgPtr
718 allocateLocal (Capability *cap, lnat n)
719 {
720     bdescr *bd;
721     StgPtr p;
722
723     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
724         return allocateInGen(g0,n);
725     }
726
727     /* small allocation (<LARGE_OBJECT_THRESHOLD) */
728
729     TICK_ALLOC_HEAP_NOCTR(n);
730     CCS_ALLOC(CCCS,n);
731     
732     bd = cap->r.rCurrentAlloc;
733     if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
734         
735         // The CurrentAlloc block is full, we need to find another
736         // one.  First, we try taking the next block from the
737         // nursery:
738         bd = cap->r.rCurrentNursery->link;
739         
740         if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
741             // The nursery is empty, or the next block is already
742             // full: allocate a fresh block (we can't fail here).
743             ACQUIRE_SM_LOCK;
744             bd = allocBlock();
745             cap->r.rNursery->n_blocks++;
746             RELEASE_SM_LOCK;
747             bd->gen_no = 0;
748             bd->step = cap->r.rNursery;
749             bd->flags = 0;
750             // NO: alloc_blocks++;
751             // calcAllocated() uses the size of the nursery, and we've
752             // already bumpted nursery->n_blocks above.  We'll GC
753             // pretty quickly now anyway, because MAYBE_GC() will
754             // notice that CurrentNursery->link is NULL.
755         } else {
756             // we have a block in the nursery: take it and put
757             // it at the *front* of the nursery list, and use it
758             // to allocate() from.
759             cap->r.rCurrentNursery->link = bd->link;
760             if (bd->link != NULL) {
761                 bd->link->u.back = cap->r.rCurrentNursery;
762             }
763         }
764         dbl_link_onto(bd, &cap->r.rNursery->blocks);
765         cap->r.rCurrentAlloc = bd;
766         IF_DEBUG(sanity, checkNurserySanity(cap->r.rNursery));
767     }
768     p = bd->free;
769     bd->free += n;
770     return p;
771 }
772
773 /* ---------------------------------------------------------------------------
774    Allocate a fixed/pinned object.
775
776    We allocate small pinned objects into a single block, allocating a
777    new block when the current one overflows.  The block is chained
778    onto the large_object_list of generation 0 step 0.
779
780    NOTE: The GC can't in general handle pinned objects.  This
781    interface is only safe to use for ByteArrays, which have no
782    pointers and don't require scavenging.  It works because the
783    block's descriptor has the BF_LARGE flag set, so the block is
784    treated as a large object and chained onto various lists, rather
785    than the individual objects being copied.  However, when it comes
786    to scavenge the block, the GC will only scavenge the first object.
787    The reason is that the GC can't linearly scan a block of pinned
788    objects at the moment (doing so would require using the
789    mostly-copying techniques).  But since we're restricting ourselves
790    to pinned ByteArrays, not scavenging is ok.
791
792    This function is called by newPinnedByteArray# which immediately
793    fills the allocated memory with a MutableByteArray#.
794    ------------------------------------------------------------------------- */
795
796 StgPtr
797 allocatePinned( lnat n )
798 {
799     StgPtr p;
800     bdescr *bd = pinned_object_block;
801
802     // If the request is for a large object, then allocate()
803     // will give us a pinned object anyway.
804     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
805         return allocate(n);
806     }
807
808     ACQUIRE_SM_LOCK;
809     
810     TICK_ALLOC_HEAP_NOCTR(n);
811     CCS_ALLOC(CCCS,n);
812
813     // we always return 8-byte aligned memory.  bd->free must be
814     // 8-byte aligned to begin with, so we just round up n to
815     // the nearest multiple of 8 bytes.
816     if (sizeof(StgWord) == 4) {
817         n = (n+1) & ~1;
818     }
819
820     // If we don't have a block of pinned objects yet, or the current
821     // one isn't large enough to hold the new object, allocate a new one.
822     if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) {
823         pinned_object_block = bd = allocBlock();
824         dbl_link_onto(bd, &g0s0->large_objects);
825         g0s0->n_large_blocks++;
826         bd->gen_no = 0;
827         bd->step   = g0s0;
828         bd->flags  = BF_PINNED | BF_LARGE;
829         bd->free   = bd->start;
830         alloc_blocks++;
831     }
832
833     p = bd->free;
834     bd->free += n;
835     RELEASE_SM_LOCK;
836     return p;
837 }
838
839 /* -----------------------------------------------------------------------------
840    Write Barriers
841    -------------------------------------------------------------------------- */
842
843 /*
844    This is the write barrier for MUT_VARs, a.k.a. IORefs.  A
845    MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
846    is.  When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
847    and is put on the mutable list.
848 */
849 void
850 dirty_MUT_VAR(StgRegTable *reg, StgClosure *p)
851 {
852     Capability *cap = regTableToCapability(reg);
853     bdescr *bd;
854     if (p->header.info == &stg_MUT_VAR_CLEAN_info) {
855         p->header.info = &stg_MUT_VAR_DIRTY_info;
856         bd = Bdescr((StgPtr)p);
857         if (bd->gen_no > 0) recordMutableCap(p,cap,bd->gen_no);
858     }
859 }
860
861 // Setting a TSO's link field with a write barrier.
862 // It is *not* necessary to call this function when
863 //    * setting the link field to END_TSO_QUEUE
864 //    * putting a TSO on the blackhole_queue
865 //    * setting the link field of the currently running TSO, as it
866 //      will already be dirty.
867 void
868 setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target)
869 {
870     bdescr *bd;
871     if ((tso->flags & (TSO_DIRTY|TSO_LINK_DIRTY)) == 0) {
872         tso->flags |= TSO_LINK_DIRTY;
873         bd = Bdescr((StgPtr)tso);
874         if (bd->gen_no > 0) recordMutableCap((StgClosure*)tso,cap,bd->gen_no);
875     }
876     tso->_link = target;
877 }
878
879 void
880 dirty_TSO (Capability *cap, StgTSO *tso)
881 {
882     bdescr *bd;
883     if ((tso->flags & (TSO_DIRTY|TSO_LINK_DIRTY)) == 0) {
884         bd = Bdescr((StgPtr)tso);
885         if (bd->gen_no > 0) recordMutableCap((StgClosure*)tso,cap,bd->gen_no);
886     }
887     tso->flags |= TSO_DIRTY;
888 }
889
890 /*
891    This is the write barrier for MVARs.  An MVAR_CLEAN objects is not
892    on the mutable list; a MVAR_DIRTY is.  When written to, a
893    MVAR_CLEAN turns into a MVAR_DIRTY and is put on the mutable list.
894    The check for MVAR_CLEAN is inlined at the call site for speed,
895    this really does make a difference on concurrency-heavy benchmarks
896    such as Chaneneos and cheap-concurrency.
897 */
898 void
899 dirty_MVAR(StgRegTable *reg, StgClosure *p)
900 {
901     Capability *cap = regTableToCapability(reg);
902     bdescr *bd;
903     bd = Bdescr((StgPtr)p);
904     if (bd->gen_no > 0) recordMutableCap(p,cap,bd->gen_no);
905 }
906
907 /* -----------------------------------------------------------------------------
908    Allocation functions for GMP.
909
910    These all use the allocate() interface - we can't have any garbage
911    collection going on during a gmp operation, so we use allocate()
912    which always succeeds.  The gmp operations which might need to
913    allocate will ask the storage manager (via doYouWantToGC()) whether
914    a garbage collection is required, in case we get into a loop doing
915    only allocate() style allocation.
916    -------------------------------------------------------------------------- */
917
918 static void *
919 stgAllocForGMP (size_t size_in_bytes)
920 {
921   StgArrWords* arr;
922   nat data_size_in_words, total_size_in_words;
923   
924   /* round up to a whole number of words */
925   data_size_in_words  = (size_in_bytes + sizeof(W_) + 1) / sizeof(W_);
926   total_size_in_words = sizeofW(StgArrWords) + data_size_in_words;
927   
928   /* allocate and fill it in. */
929 #if defined(THREADED_RTS)
930   arr = (StgArrWords *)allocateLocal(myTask()->cap, total_size_in_words);
931 #else
932   arr = (StgArrWords *)allocateLocal(&MainCapability, total_size_in_words);
933 #endif
934   SET_ARR_HDR(arr, &stg_ARR_WORDS_info, CCCS, data_size_in_words);
935   
936   /* and return a ptr to the goods inside the array */
937   return arr->payload;
938 }
939
940 static void *
941 stgReallocForGMP (void *ptr, size_t old_size, size_t new_size)
942 {
943     size_t min_size;
944     void *new_stuff_ptr = stgAllocForGMP(new_size);
945     nat i = 0;
946     char *p = (char *) ptr;
947     char *q = (char *) new_stuff_ptr;
948
949     min_size = old_size < new_size ? old_size : new_size;
950     for (; i < min_size; i++, p++, q++) {
951         *q = *p;
952     }
953
954     return(new_stuff_ptr);
955 }
956
957 static void
958 stgDeallocForGMP (void *ptr STG_UNUSED, 
959                   size_t size STG_UNUSED)
960 {
961     /* easy for us: the garbage collector does the dealloc'n */
962 }
963
964 /* -----------------------------------------------------------------------------
965  * Stats and stuff
966  * -------------------------------------------------------------------------- */
967
968 /* -----------------------------------------------------------------------------
969  * calcAllocated()
970  *
971  * Approximate how much we've allocated: number of blocks in the
972  * nursery + blocks allocated via allocate() - unused nusery blocks.
973  * This leaves a little slop at the end of each block, and doesn't
974  * take into account large objects (ToDo).
975  * -------------------------------------------------------------------------- */
976
977 lnat
978 calcAllocated( void )
979 {
980   nat allocated;
981   bdescr *bd;
982
983   allocated = allocatedBytes();
984   allocated += countNurseryBlocks() * BLOCK_SIZE_W;
985   
986   {
987 #ifdef THREADED_RTS
988   nat i;
989   for (i = 0; i < n_nurseries; i++) {
990       Capability *cap;
991       for ( bd = capabilities[i].r.rCurrentNursery->link; 
992             bd != NULL; bd = bd->link ) {
993           allocated -= BLOCK_SIZE_W;
994       }
995       cap = &capabilities[i];
996       if (cap->r.rCurrentNursery->free < 
997           cap->r.rCurrentNursery->start + BLOCK_SIZE_W) {
998           allocated -= (cap->r.rCurrentNursery->start + BLOCK_SIZE_W)
999               - cap->r.rCurrentNursery->free;
1000       }
1001   }
1002 #else
1003   bdescr *current_nursery = MainCapability.r.rCurrentNursery;
1004
1005   for ( bd = current_nursery->link; bd != NULL; bd = bd->link ) {
1006       allocated -= BLOCK_SIZE_W;
1007   }
1008   if (current_nursery->free < current_nursery->start + BLOCK_SIZE_W) {
1009       allocated -= (current_nursery->start + BLOCK_SIZE_W)
1010           - current_nursery->free;
1011   }
1012 #endif
1013   }
1014
1015   total_allocated += allocated;
1016   return allocated;
1017 }  
1018
1019 /* Approximate the amount of live data in the heap.  To be called just
1020  * after garbage collection (see GarbageCollect()).
1021  */
1022 lnat 
1023 calcLiveBlocks(void)
1024 {
1025   nat g, s;
1026   lnat live = 0;
1027   step *stp;
1028
1029   if (RtsFlags.GcFlags.generations == 1) {
1030       return g0s0->n_large_blocks + g0s0->n_blocks;
1031   }
1032
1033   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1034     for (s = 0; s < generations[g].n_steps; s++) {
1035       /* approximate amount of live data (doesn't take into account slop
1036        * at end of each block).
1037        */
1038       if (g == 0 && s == 0) { 
1039           continue; 
1040       }
1041       stp = &generations[g].steps[s];
1042       live += stp->n_large_blocks + stp->n_blocks;
1043     }
1044   }
1045   return live;
1046 }
1047
1048 lnat
1049 countOccupied(bdescr *bd)
1050 {
1051     lnat words;
1052
1053     words = 0;
1054     for (; bd != NULL; bd = bd->link) {
1055         ASSERT(bd->free <= bd->start + bd->blocks * BLOCK_SIZE_W);
1056         words += bd->free - bd->start;
1057     }
1058     return words;
1059 }
1060
1061 // Return an accurate count of the live data in the heap, excluding
1062 // generation 0.
1063 lnat
1064 calcLiveWords(void)
1065 {
1066     nat g, s;
1067     lnat live;
1068     step *stp;
1069     
1070     if (RtsFlags.GcFlags.generations == 1) {
1071         return g0s0->n_words + countOccupied(g0s0->large_objects);
1072     }
1073     
1074     live = 0;
1075     for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1076         for (s = 0; s < generations[g].n_steps; s++) {
1077             if (g == 0 && s == 0) continue; 
1078             stp = &generations[g].steps[s];
1079             live += stp->n_words + countOccupied(stp->large_objects);
1080         } 
1081     }
1082     return live;
1083 }
1084
1085 /* Approximate the number of blocks that will be needed at the next
1086  * garbage collection.
1087  *
1088  * Assume: all data currently live will remain live.  Steps that will
1089  * be collected next time will therefore need twice as many blocks
1090  * since all the data will be copied.
1091  */
1092 extern lnat 
1093 calcNeeded(void)
1094 {
1095     lnat needed = 0;
1096     nat g, s;
1097     step *stp;
1098     
1099     for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1100         for (s = 0; s < generations[g].n_steps; s++) {
1101             if (g == 0 && s == 0) { continue; }
1102             stp = &generations[g].steps[s];
1103
1104             // we need at least this much space
1105             needed += stp->n_blocks + stp->n_large_blocks;
1106
1107             // any additional space needed to collect this gen next time?
1108             if (g == 0 || // always collect gen 0
1109                 (generations[g].steps[0].n_blocks +
1110                  generations[g].steps[0].n_large_blocks 
1111                  > generations[g].max_blocks)) {
1112                 // we will collect this gen next time
1113                 if (stp->mark) {
1114                     //  bitmap:
1115                     needed += stp->n_blocks / BITS_IN(W_);
1116                     //  mark stack:
1117                     needed += stp->n_blocks / 100;
1118                 }
1119                 if (stp->compact) {
1120                     continue; // no additional space needed for compaction
1121                 } else {
1122                     needed += stp->n_blocks;
1123                 }
1124             }
1125         }
1126     }
1127     return needed;
1128 }
1129
1130 /* ----------------------------------------------------------------------------
1131    Executable memory
1132
1133    Executable memory must be managed separately from non-executable
1134    memory.  Most OSs these days require you to jump through hoops to
1135    dynamically allocate executable memory, due to various security
1136    measures.
1137
1138    Here we provide a small memory allocator for executable memory.
1139    Memory is managed with a page granularity; we allocate linearly
1140    in the page, and when the page is emptied (all objects on the page
1141    are free) we free the page again, not forgetting to make it
1142    non-executable.
1143
1144    TODO: The inability to handle objects bigger than BLOCK_SIZE_W means that
1145          the linker cannot use allocateExec for loading object code files
1146          on Windows. Once allocateExec can handle larger objects, the linker
1147          should be modified to use allocateExec instead of VirtualAlloc.
1148    ------------------------------------------------------------------------- */
1149
1150 #if defined(linux_HOST_OS)
1151
1152 // On Linux we need to use libffi for allocating executable memory,
1153 // because it knows how to work around the restrictions put in place
1154 // by SELinux.
1155
1156 void *allocateExec (nat bytes, void **exec_ret)
1157 {
1158     void **ret, **exec;
1159     ACQUIRE_SM_LOCK;
1160     ret = ffi_closure_alloc (sizeof(void *) + (size_t)bytes, (void**)&exec);
1161     RELEASE_SM_LOCK;
1162     if (ret == NULL) return ret;
1163     *ret = ret; // save the address of the writable mapping, for freeExec().
1164     *exec_ret = exec + 1;
1165     return (ret + 1);
1166 }
1167
1168 // freeExec gets passed the executable address, not the writable address. 
1169 void freeExec (void *addr)
1170 {
1171     void *writable;
1172     writable = *((void**)addr - 1);
1173     ACQUIRE_SM_LOCK;
1174     ffi_closure_free (writable);
1175     RELEASE_SM_LOCK
1176 }
1177
1178 #else
1179
1180 void *allocateExec (nat bytes, void **exec_ret)
1181 {
1182     void *ret;
1183     nat n;
1184
1185     ACQUIRE_SM_LOCK;
1186
1187     // round up to words.
1188     n  = (bytes + sizeof(W_) + 1) / sizeof(W_);
1189
1190     if (n+1 > BLOCK_SIZE_W) {
1191         barf("allocateExec: can't handle large objects");
1192     }
1193
1194     if (exec_block == NULL || 
1195         exec_block->free + n + 1 > exec_block->start + BLOCK_SIZE_W) {
1196         bdescr *bd;
1197         lnat pagesize = getPageSize();
1198         bd = allocGroup(stg_max(1, pagesize / BLOCK_SIZE));
1199         debugTrace(DEBUG_gc, "allocate exec block %p", bd->start);
1200         bd->gen_no = 0;
1201         bd->flags = BF_EXEC;
1202         bd->link = exec_block;
1203         if (exec_block != NULL) {
1204             exec_block->u.back = bd;
1205         }
1206         bd->u.back = NULL;
1207         setExecutable(bd->start, bd->blocks * BLOCK_SIZE, rtsTrue);
1208         exec_block = bd;
1209     }
1210     *(exec_block->free) = n;  // store the size of this chunk
1211     exec_block->gen_no += n;  // gen_no stores the number of words allocated
1212     ret = exec_block->free + 1;
1213     exec_block->free += n + 1;
1214
1215     RELEASE_SM_LOCK
1216     *exec_ret = ret;
1217     return ret;
1218 }
1219
1220 void freeExec (void *addr)
1221 {
1222     StgPtr p = (StgPtr)addr - 1;
1223     bdescr *bd = Bdescr((StgPtr)p);
1224
1225     if ((bd->flags & BF_EXEC) == 0) {
1226         barf("freeExec: not executable");
1227     }
1228
1229     if (*(StgPtr)p == 0) {
1230         barf("freeExec: already free?");
1231     }
1232
1233     ACQUIRE_SM_LOCK;
1234
1235     bd->gen_no -= *(StgPtr)p;
1236     *(StgPtr)p = 0;
1237
1238     if (bd->gen_no == 0) {
1239         // Free the block if it is empty, but not if it is the block at
1240         // the head of the queue.
1241         if (bd != exec_block) {
1242             debugTrace(DEBUG_gc, "free exec block %p", bd->start);
1243             dbl_link_remove(bd, &exec_block);
1244             setExecutable(bd->start, bd->blocks * BLOCK_SIZE, rtsFalse);
1245             freeGroup(bd);
1246         } else {
1247             bd->free = bd->start;
1248         }
1249     }
1250
1251     RELEASE_SM_LOCK
1252 }    
1253
1254 #endif /* mingw32_HOST_OS */
1255
1256 /* -----------------------------------------------------------------------------
1257    Debugging
1258
1259    memInventory() checks for memory leaks by counting up all the
1260    blocks we know about and comparing that to the number of blocks
1261    allegedly floating around in the system.
1262    -------------------------------------------------------------------------- */
1263
1264 #ifdef DEBUG
1265
1266 // Useful for finding partially full blocks in gdb
1267 void findSlop(bdescr *bd);
1268 void findSlop(bdescr *bd)
1269 {
1270     lnat slop;
1271
1272     for (; bd != NULL; bd = bd->link) {
1273         slop = (bd->blocks * BLOCK_SIZE_W) - (bd->free - bd->start);
1274         if (slop > (1024/sizeof(W_))) {
1275             debugBelch("block at %p (bdescr %p) has %ldKB slop\n",
1276                        bd->start, bd, slop / (1024/sizeof(W_)));
1277         }
1278     }
1279 }
1280
1281 nat
1282 countBlocks(bdescr *bd)
1283 {
1284     nat n;
1285     for (n=0; bd != NULL; bd=bd->link) {
1286         n += bd->blocks;
1287     }
1288     return n;
1289 }
1290
1291 // (*1) Just like countBlocks, except that we adjust the count for a
1292 // megablock group so that it doesn't include the extra few blocks
1293 // that would be taken up by block descriptors in the second and
1294 // subsequent megablock.  This is so we can tally the count with the
1295 // number of blocks allocated in the system, for memInventory().
1296 static nat
1297 countAllocdBlocks(bdescr *bd)
1298 {
1299     nat n;
1300     for (n=0; bd != NULL; bd=bd->link) {
1301         n += bd->blocks;
1302         // hack for megablock groups: see (*1) above
1303         if (bd->blocks > BLOCKS_PER_MBLOCK) {
1304             n -= (MBLOCK_SIZE / BLOCK_SIZE - BLOCKS_PER_MBLOCK)
1305                 * (bd->blocks/(MBLOCK_SIZE/BLOCK_SIZE));
1306         }
1307     }
1308     return n;
1309 }
1310
1311 static lnat
1312 stepBlocks (step *stp)
1313 {
1314     ASSERT(countBlocks(stp->blocks) == stp->n_blocks);
1315     ASSERT(countBlocks(stp->large_objects) == stp->n_large_blocks);
1316     return stp->n_blocks + stp->n_old_blocks + 
1317             countAllocdBlocks(stp->large_objects);
1318 }
1319
1320 // If memInventory() calculates that we have a memory leak, this
1321 // function will try to find the block(s) that are leaking by marking
1322 // all the ones that we know about, and search through memory to find
1323 // blocks that are not marked.  In the debugger this can help to give
1324 // us a clue about what kind of block leaked.  In the future we might
1325 // annotate blocks with their allocation site to give more helpful
1326 // info.
1327 static void
1328 findMemoryLeak (void)
1329 {
1330   nat g, s, i;
1331   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1332       for (i = 0; i < n_capabilities; i++) {
1333           markBlocks(capabilities[i].mut_lists[g]);
1334       }
1335       markBlocks(generations[g].mut_list);
1336       for (s = 0; s < generations[g].n_steps; s++) {
1337           markBlocks(generations[g].steps[s].blocks);
1338           markBlocks(generations[g].steps[s].large_objects);
1339       }
1340   }
1341
1342   for (i = 0; i < n_nurseries; i++) {
1343       markBlocks(nurseries[i].blocks);
1344       markBlocks(nurseries[i].large_objects);
1345   }
1346
1347 #ifdef PROFILING
1348   // TODO:
1349   // if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER) {
1350   //    markRetainerBlocks();
1351   // }
1352 #endif
1353
1354   // count the blocks allocated by the arena allocator
1355   // TODO:
1356   // markArenaBlocks();
1357
1358   // count the blocks containing executable memory
1359   markBlocks(exec_block);
1360
1361   reportUnmarkedBlocks();
1362 }
1363
1364
1365 void
1366 memInventory (rtsBool show)
1367 {
1368   nat g, s, i;
1369   step *stp;
1370   lnat gen_blocks[RtsFlags.GcFlags.generations];
1371   lnat nursery_blocks, retainer_blocks,
1372        arena_blocks, exec_blocks;
1373   lnat live_blocks = 0, free_blocks = 0;
1374   rtsBool leak;
1375
1376   // count the blocks we current have
1377
1378   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1379       gen_blocks[g] = 0;
1380       for (i = 0; i < n_capabilities; i++) {
1381           gen_blocks[g] += countBlocks(capabilities[i].mut_lists[g]);
1382       }   
1383       gen_blocks[g] += countAllocdBlocks(generations[g].mut_list);
1384       for (s = 0; s < generations[g].n_steps; s++) {
1385           stp = &generations[g].steps[s];
1386           gen_blocks[g] += stepBlocks(stp);
1387       }
1388   }
1389
1390   nursery_blocks = 0;
1391   for (i = 0; i < n_nurseries; i++) {
1392       nursery_blocks += stepBlocks(&nurseries[i]);
1393   }
1394
1395   retainer_blocks = 0;
1396 #ifdef PROFILING
1397   if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER) {
1398       retainer_blocks = retainerStackBlocks();
1399   }
1400 #endif
1401
1402   // count the blocks allocated by the arena allocator
1403   arena_blocks = arenaBlocks();
1404
1405   // count the blocks containing executable memory
1406   exec_blocks = countAllocdBlocks(exec_block);
1407
1408   /* count the blocks on the free list */
1409   free_blocks = countFreeList();
1410
1411   live_blocks = 0;
1412   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1413       live_blocks += gen_blocks[g];
1414   }
1415   live_blocks += nursery_blocks + 
1416                + retainer_blocks + arena_blocks + exec_blocks;
1417
1418 #define MB(n) (((n) * BLOCK_SIZE_W) / ((1024*1024)/sizeof(W_)))
1419
1420   leak = live_blocks + free_blocks != mblocks_allocated * BLOCKS_PER_MBLOCK;
1421
1422   if (show || leak)
1423   {
1424       if (leak) { 
1425           debugBelch("Memory leak detected:\n");
1426       } else {
1427           debugBelch("Memory inventory:\n");
1428       }
1429       for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1430           debugBelch("  gen %d blocks : %5lu blocks (%lu MB)\n", g, 
1431                      gen_blocks[g], MB(gen_blocks[g]));
1432       }
1433       debugBelch("  nursery      : %5lu blocks (%lu MB)\n", 
1434                  nursery_blocks, MB(nursery_blocks));
1435       debugBelch("  retainer     : %5lu blocks (%lu MB)\n", 
1436                  retainer_blocks, MB(retainer_blocks));
1437       debugBelch("  arena blocks : %5lu blocks (%lu MB)\n", 
1438                  arena_blocks, MB(arena_blocks));
1439       debugBelch("  exec         : %5lu blocks (%lu MB)\n", 
1440                  exec_blocks, MB(exec_blocks));
1441       debugBelch("  free         : %5lu blocks (%lu MB)\n", 
1442                  free_blocks, MB(free_blocks));
1443       debugBelch("  total        : %5lu blocks (%lu MB)\n",
1444                  live_blocks + free_blocks, MB(live_blocks+free_blocks));
1445       if (leak) {
1446           debugBelch("\n  in system    : %5lu blocks (%lu MB)\n", 
1447                      mblocks_allocated * BLOCKS_PER_MBLOCK, mblocks_allocated);
1448       }
1449   }
1450
1451   if (leak) {
1452       debugBelch("\n");
1453       findMemoryLeak();
1454   }
1455   ASSERT(n_alloc_blocks == live_blocks);
1456   ASSERT(!leak);
1457 }
1458
1459
1460 /* Full heap sanity check. */
1461 void
1462 checkSanity( void )
1463 {
1464     nat g, s;
1465
1466     if (RtsFlags.GcFlags.generations == 1) {
1467         checkHeap(g0s0->blocks);
1468         checkChain(g0s0->large_objects);
1469     } else {
1470         
1471         for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1472             for (s = 0; s < generations[g].n_steps; s++) {
1473                 if (g == 0 && s == 0) { continue; }
1474                 ASSERT(countBlocks(generations[g].steps[s].blocks)
1475                        == generations[g].steps[s].n_blocks);
1476                 ASSERT(countBlocks(generations[g].steps[s].large_objects)
1477                        == generations[g].steps[s].n_large_blocks);
1478                 checkHeap(generations[g].steps[s].blocks);
1479                 checkChain(generations[g].steps[s].large_objects);
1480                 if (g > 0) {
1481                     checkMutableList(generations[g].mut_list, g);
1482                 }
1483             }
1484         }
1485
1486         for (s = 0; s < n_nurseries; s++) {
1487             ASSERT(countBlocks(nurseries[s].blocks)
1488                    == nurseries[s].n_blocks);
1489             ASSERT(countBlocks(nurseries[s].large_objects)
1490                    == nurseries[s].n_large_blocks);
1491         }
1492             
1493         checkFreeListSanity();
1494     }
1495
1496 #if defined(THREADED_RTS)
1497     // check the stacks too in threaded mode, because we don't do a
1498     // full heap sanity check in this case (see checkHeap())
1499     checkGlobalTSOList(rtsTrue);
1500 #else
1501     checkGlobalTSOList(rtsFalse);
1502 #endif
1503 }
1504
1505 /* Nursery sanity check */
1506 void
1507 checkNurserySanity( step *stp )
1508 {
1509     bdescr *bd, *prev;
1510     nat blocks = 0;
1511
1512     prev = NULL;
1513     for (bd = stp->blocks; bd != NULL; bd = bd->link) {
1514         ASSERT(bd->u.back == prev);
1515         prev = bd;
1516         blocks += bd->blocks;
1517     }
1518     ASSERT(blocks == stp->n_blocks);
1519 }
1520
1521 // handy function for use in gdb, because Bdescr() is inlined.
1522 extern bdescr *_bdescr( StgPtr p );
1523
1524 bdescr *
1525 _bdescr( StgPtr p )
1526 {
1527     return Bdescr(p);
1528 }
1529
1530 #endif