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