[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / rts / Storage.c
1 /* -----------------------------------------------------------------------------
2  * $Id: Storage.c,v 1.84 2004/08/13 13:11:01 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Storage manager front end
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "PosixSource.h"
11 #include "Rts.h"
12 #include "RtsUtils.h"
13 #include "RtsFlags.h"
14 #include "Stats.h"
15 #include "Hooks.h"
16 #include "BlockAlloc.h"
17 #include "MBlock.h"
18 #include "Weak.h"
19 #include "Sanity.h"
20 #include "Arena.h"
21
22 #include "Storage.h"
23 #include "Schedule.h"
24 #include "OSThreads.h"
25
26 #include "RetainerProfile.h"    // for counting memory blocks (memInventory)
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 StgClosure    *caf_list         = NULL;
32
33 bdescr *small_alloc_list;       /* allocate()d small objects */
34 bdescr *pinned_object_block;    /* allocate pinned objects into this block */
35 nat alloc_blocks;               /* number of allocate()d blocks since GC */
36 nat alloc_blocks_lim;           /* approximate limit on alloc_blocks */
37
38 StgPtr alloc_Hp    = NULL;      /* next free byte in small_alloc_list */
39 StgPtr alloc_HpLim = NULL;      /* end of block at small_alloc_list   */
40
41 generation *generations = NULL; /* all the generations */
42 generation *g0          = NULL; /* generation 0, for convenience */
43 generation *oldest_gen  = NULL; /* oldest generation, for convenience */
44 step *g0s0              = NULL; /* generation 0, step 0, for convenience */
45
46 ullong total_allocated = 0;     /* total memory allocated during run */
47
48 /*
49  * Storage manager mutex:  protects all the above state from
50  * simultaneous access by two STG threads.
51  */
52 #ifdef SMP
53 Mutex sm_mutex = INIT_MUTEX_VAR;
54 #endif
55
56 /*
57  * Forward references
58  */
59 static void *stgAllocForGMP   (size_t size_in_bytes);
60 static void *stgReallocForGMP (void *ptr, size_t old_size, size_t new_size);
61 static void  stgDeallocForGMP (void *ptr, size_t size);
62
63 void
64 initStorage( void )
65 {
66   nat g, s;
67   step *stp;
68   generation *gen;
69
70   if (generations != NULL) {
71       // multi-init protection
72       return;
73   }
74
75   /* Sanity check to make sure the LOOKS_LIKE_ macros appear to be
76    * doing something reasonable.
77    */
78   ASSERT(LOOKS_LIKE_INFO_PTR(&stg_BLACKHOLE_info));
79   ASSERT(LOOKS_LIKE_CLOSURE_PTR(&stg_dummy_ret_closure));
80   ASSERT(!HEAP_ALLOCED(&stg_dummy_ret_closure));
81   
82   if (RtsFlags.GcFlags.maxHeapSize != 0 &&
83       RtsFlags.GcFlags.heapSizeSuggestion > 
84       RtsFlags.GcFlags.maxHeapSize) {
85     RtsFlags.GcFlags.maxHeapSize = RtsFlags.GcFlags.heapSizeSuggestion;
86   }
87
88   if (RtsFlags.GcFlags.maxHeapSize != 0 &&
89       RtsFlags.GcFlags.minAllocAreaSize > 
90       RtsFlags.GcFlags.maxHeapSize) {
91       prog_belch("maximum heap size (-M) is smaller than minimum alloc area size (-A)");
92       exit(1);
93   }
94
95   initBlockAllocator();
96   
97 #if defined(SMP)
98   initMutex(&sm_mutex);
99 #endif
100
101   /* allocate generation info array */
102   generations = (generation *)stgMallocBytes(RtsFlags.GcFlags.generations 
103                                              * sizeof(struct _generation),
104                                              "initStorage: gens");
105
106   /* Initialise all generations */
107   for(g = 0; g < RtsFlags.GcFlags.generations; g++) {
108     gen = &generations[g];
109     gen->no = g;
110     gen->mut_list = END_MUT_LIST;
111     gen->mut_once_list = END_MUT_LIST;
112     gen->collections = 0;
113     gen->failed_promotions = 0;
114     gen->max_blocks = 0;
115   }
116
117   /* A couple of convenience pointers */
118   g0 = &generations[0];
119   oldest_gen = &generations[RtsFlags.GcFlags.generations-1];
120
121   /* Allocate step structures in each generation */
122   if (RtsFlags.GcFlags.generations > 1) {
123     /* Only for multiple-generations */
124
125     /* Oldest generation: one step */
126     oldest_gen->n_steps = 1;
127     oldest_gen->steps = 
128       stgMallocBytes(1 * sizeof(struct _step), "initStorage: last step");
129
130     /* set up all except the oldest generation with 2 steps */
131     for(g = 0; g < RtsFlags.GcFlags.generations-1; g++) {
132       generations[g].n_steps = RtsFlags.GcFlags.steps;
133       generations[g].steps  = 
134         stgMallocBytes (RtsFlags.GcFlags.steps * sizeof(struct _step),
135                         "initStorage: steps");
136     }
137     
138   } else {
139     /* single generation, i.e. a two-space collector */
140     g0->n_steps = 1;
141     g0->steps = stgMallocBytes (sizeof(struct _step), "initStorage: steps");
142   }
143
144   /* Initialise all steps */
145   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
146     for (s = 0; s < generations[g].n_steps; s++) {
147       stp = &generations[g].steps[s];
148       stp->no = s;
149       stp->blocks = NULL;
150       stp->n_to_blocks = 0;
151       stp->n_blocks = 0;
152       stp->gen = &generations[g];
153       stp->gen_no = g;
154       stp->hp = NULL;
155       stp->hpLim = NULL;
156       stp->hp_bd = NULL;
157       stp->scan = NULL;
158       stp->scan_bd = NULL;
159       stp->large_objects = NULL;
160       stp->n_large_blocks = 0;
161       stp->new_large_objects = NULL;
162       stp->scavenged_large_objects = NULL;
163       stp->n_scavenged_large_blocks = 0;
164       stp->is_compacted = 0;
165       stp->bitmap = NULL;
166     }
167   }
168   
169   /* Set up the destination pointers in each younger gen. step */
170   for (g = 0; g < RtsFlags.GcFlags.generations-1; g++) {
171     for (s = 0; s < generations[g].n_steps-1; s++) {
172       generations[g].steps[s].to = &generations[g].steps[s+1];
173     }
174     generations[g].steps[s].to = &generations[g+1].steps[0];
175   }
176   
177   /* The oldest generation has one step and it is compacted. */
178   if (RtsFlags.GcFlags.compact) {
179       if (RtsFlags.GcFlags.generations == 1) {
180           belch("WARNING: compaction is incompatible with -G1; disabled");
181       } else {
182           oldest_gen->steps[0].is_compacted = 1;
183       }
184   }
185   oldest_gen->steps[0].to = &oldest_gen->steps[0];
186
187   /* generation 0 is special: that's the nursery */
188   generations[0].max_blocks = 0;
189
190   /* G0S0: the allocation area.  Policy: keep the allocation area
191    * small to begin with, even if we have a large suggested heap
192    * size.  Reason: we're going to do a major collection first, and we
193    * don't want it to be a big one.  This vague idea is borne out by 
194    * rigorous experimental evidence.
195    */
196   g0s0 = &generations[0].steps[0];
197
198   allocNurseries();
199
200   weak_ptr_list = NULL;
201   caf_list = NULL;
202    
203   /* initialise the allocate() interface */
204   small_alloc_list = NULL;
205   alloc_blocks = 0;
206   alloc_blocks_lim = RtsFlags.GcFlags.minAllocAreaSize;
207
208   /* Tell GNU multi-precision pkg about our custom alloc functions */
209   mp_set_memory_functions(stgAllocForGMP, stgReallocForGMP, stgDeallocForGMP);
210
211   IF_DEBUG(gc, statDescribeGens());
212 }
213
214 void
215 exitStorage (void)
216 {
217     stat_exit(calcAllocated());
218 }
219
220 /* -----------------------------------------------------------------------------
221    CAF management.
222
223    The entry code for every CAF does the following:
224      
225       - builds a CAF_BLACKHOLE in the heap
226       - pushes an update frame pointing to the CAF_BLACKHOLE
227       - invokes UPD_CAF(), which:
228           - calls newCaf, below
229           - updates the CAF with a static indirection to the CAF_BLACKHOLE
230       
231    Why do we build a BLACKHOLE in the heap rather than just updating
232    the thunk directly?  It's so that we only need one kind of update
233    frame - otherwise we'd need a static version of the update frame too.
234
235    newCaf() does the following:
236        
237       - it puts the CAF on the oldest generation's mut-once list.
238         This is so that we can treat the CAF as a root when collecting
239         younger generations.
240
241    For GHCI, we have additional requirements when dealing with CAFs:
242
243       - we must *retain* all dynamically-loaded CAFs ever entered,
244         just in case we need them again.
245       - we must be able to *revert* CAFs that have been evaluated, to
246         their pre-evaluated form.
247
248       To do this, we use an additional CAF list.  When newCaf() is
249       called on a dynamically-loaded CAF, we add it to the CAF list
250       instead of the old-generation mutable list, and save away its
251       old info pointer (in caf->saved_info) for later reversion.
252
253       To revert all the CAFs, we traverse the CAF list and reset the
254       info pointer to caf->saved_info, then throw away the CAF list.
255       (see GC.c:revertCAFs()).
256
257       -- SDM 29/1/01
258
259    -------------------------------------------------------------------------- */
260
261 void
262 newCAF(StgClosure* caf)
263 {
264   /* Put this CAF on the mutable list for the old generation.
265    * This is a HACK - the IND_STATIC closure doesn't really have
266    * a mut_link field, but we pretend it has - in fact we re-use
267    * the STATIC_LINK field for the time being, because when we
268    * come to do a major GC we won't need the mut_link field
269    * any more and can use it as a STATIC_LINK.
270    */
271   ACQUIRE_SM_LOCK;
272
273   ((StgIndStatic *)caf)->saved_info = NULL;
274   ((StgMutClosure *)caf)->mut_link = oldest_gen->mut_once_list;
275   oldest_gen->mut_once_list = (StgMutClosure *)caf;
276
277   RELEASE_SM_LOCK;
278
279 #ifdef PAR
280   /* If we are PAR or DIST then  we never forget a CAF */
281   { globalAddr *newGA;
282     //belch("<##> Globalising CAF %08x %s",caf,info_type(caf));
283     newGA=makeGlobal(caf,rtsTrue); /*given full weight*/
284     ASSERT(newGA);
285   } 
286 #endif /* PAR */
287 }
288
289 // An alternate version of newCaf which is used for dynamically loaded
290 // object code in GHCi.  In this case we want to retain *all* CAFs in
291 // the object code, because they might be demanded at any time from an
292 // expression evaluated on the command line.
293 //
294 // The linker hackily arranges that references to newCaf from dynamic
295 // code end up pointing to newDynCAF.
296 void
297 newDynCAF(StgClosure *caf)
298 {
299     ACQUIRE_SM_LOCK;
300
301     ((StgIndStatic *)caf)->saved_info  = (StgInfoTable *)caf->header.info;
302     ((StgIndStatic *)caf)->static_link = caf_list;
303     caf_list = caf;
304
305     RELEASE_SM_LOCK;
306 }
307
308 /* -----------------------------------------------------------------------------
309    Nursery management.
310    -------------------------------------------------------------------------- */
311
312 void
313 allocNurseries( void )
314
315 #ifdef SMP
316   Capability *cap;
317   bdescr *bd;
318
319   g0s0->blocks = NULL;
320   g0s0->n_blocks = 0;
321   for (cap = free_capabilities; cap != NULL; cap = cap->link) {
322     cap->r.rNursery = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
323     cap->r.rCurrentNursery = cap->r.rNursery;
324     /* Set the back links to be equal to the Capability,
325      * so we can do slightly better informed locking.
326      */
327     for (bd = cap->r.rNursery; bd != NULL; bd = bd->link) {
328       bd->u.back = (bdescr *)cap;
329     }
330   }
331 #else /* SMP */
332   g0s0->blocks      = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
333   g0s0->n_blocks    = RtsFlags.GcFlags.minAllocAreaSize;
334   g0s0->to_blocks   = NULL;
335   g0s0->n_to_blocks = 0;
336   MainCapability.r.rNursery        = g0s0->blocks;
337   MainCapability.r.rCurrentNursery = g0s0->blocks;
338   /* hp, hpLim, hp_bd, to_space etc. aren't used in G0S0 */
339 #endif
340 }
341       
342 void
343 resetNurseries( void )
344 {
345   bdescr *bd;
346 #ifdef SMP
347   Capability *cap;
348   
349   /* All tasks must be stopped */
350   ASSERT(n_free_capabilities == RtsFlags.ParFlags.nNodes);
351
352   for (cap = free_capabilities; cap != NULL; cap = cap->link) {
353     for (bd = cap->r.rNursery; bd; bd = bd->link) {
354       bd->free = bd->start;
355       ASSERT(bd->gen_no == 0);
356       ASSERT(bd->step == g0s0);
357       IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
358     }
359     cap->r.rCurrentNursery = cap->r.rNursery;
360   }
361 #else
362   for (bd = g0s0->blocks; bd; bd = bd->link) {
363     bd->free = bd->start;
364     ASSERT(bd->gen_no == 0);
365     ASSERT(bd->step == g0s0);
366     IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
367   }
368   MainCapability.r.rNursery = g0s0->blocks;
369   MainCapability.r.rCurrentNursery = g0s0->blocks;
370 #endif
371 }
372
373 bdescr *
374 allocNursery (bdescr *tail, nat blocks)
375 {
376   bdescr *bd;
377   nat i;
378
379   // Allocate a nursery: we allocate fresh blocks one at a time and
380   // cons them on to the front of the list, not forgetting to update
381   // the back pointer on the tail of the list to point to the new block.
382   for (i=0; i < blocks; i++) {
383     // @LDV profiling
384     /*
385       processNursery() in LdvProfile.c assumes that every block group in
386       the nursery contains only a single block. So, if a block group is
387       given multiple blocks, change processNursery() accordingly.
388      */
389     bd = allocBlock();
390     bd->link = tail;
391     // double-link the nursery: we might need to insert blocks
392     if (tail != NULL) {
393         tail->u.back = bd;
394     }
395     bd->step = g0s0;
396     bd->gen_no = 0;
397     bd->flags = 0;
398     bd->free = bd->start;
399     tail = bd;
400   }
401   tail->u.back = NULL;
402   return tail;
403 }
404
405 void
406 resizeNursery ( nat blocks )
407 {
408   bdescr *bd;
409   nat nursery_blocks;
410
411 #ifdef SMP
412   barf("resizeNursery: can't resize in SMP mode");
413 #endif
414
415   nursery_blocks = g0s0->n_blocks;
416   if (nursery_blocks == blocks) {
417     return;
418   }
419
420   else if (nursery_blocks < blocks) {
421     IF_DEBUG(gc, fprintf(stderr, "Increasing size of nursery to %d blocks\n", 
422                          blocks));
423     g0s0->blocks = allocNursery(g0s0->blocks, blocks-nursery_blocks);
424   } 
425
426   else {
427     bdescr *next_bd;
428     
429     IF_DEBUG(gc, fprintf(stderr, "Decreasing size of nursery to %d blocks\n", 
430                          blocks));
431
432     bd = g0s0->blocks;
433     while (nursery_blocks > blocks) {
434         next_bd = bd->link;
435         next_bd->u.back = NULL;
436         nursery_blocks -= bd->blocks; // might be a large block
437         freeGroup(bd);
438         bd = next_bd;
439     }
440     g0s0->blocks = bd;
441     // might have gone just under, by freeing a large block, so make
442     // up the difference.
443     if (nursery_blocks < blocks) {
444         g0s0->blocks = allocNursery(g0s0->blocks, blocks-nursery_blocks);
445     }
446   }
447   
448   g0s0->n_blocks = blocks;
449   ASSERT(countBlocks(g0s0->blocks) == g0s0->n_blocks);
450 }
451
452 /* -----------------------------------------------------------------------------
453    The allocate() interface
454
455    allocate(n) always succeeds, and returns a chunk of memory n words
456    long.  n can be larger than the size of a block if necessary, in
457    which case a contiguous block group will be allocated.
458    -------------------------------------------------------------------------- */
459
460 StgPtr
461 allocate( nat n )
462 {
463   bdescr *bd;
464   StgPtr p;
465
466   ACQUIRE_SM_LOCK;
467
468   TICK_ALLOC_HEAP_NOCTR(n);
469   CCS_ALLOC(CCCS,n);
470
471   /* big allocation (>LARGE_OBJECT_THRESHOLD) */
472   /* ToDo: allocate directly into generation 1 */
473   if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
474     nat req_blocks =  (lnat)BLOCK_ROUND_UP(n*sizeof(W_)) / BLOCK_SIZE;
475     bd = allocGroup(req_blocks);
476     dbl_link_onto(bd, &g0s0->large_objects);
477     g0s0->n_large_blocks += req_blocks;
478     bd->gen_no  = 0;
479     bd->step = g0s0;
480     bd->flags = BF_LARGE;
481     bd->free = bd->start + n;
482     alloc_blocks += req_blocks;
483     RELEASE_SM_LOCK;
484     return bd->start;
485
486   /* small allocation (<LARGE_OBJECT_THRESHOLD) */
487   } else if (small_alloc_list == NULL || alloc_Hp + n > alloc_HpLim) {
488     if (small_alloc_list) {
489       small_alloc_list->free = alloc_Hp;
490     }
491     bd = allocBlock();
492     bd->link = small_alloc_list;
493     small_alloc_list = bd;
494     bd->gen_no = 0;
495     bd->step = g0s0;
496     bd->flags = 0;
497     alloc_Hp = bd->start;
498     alloc_HpLim = bd->start + BLOCK_SIZE_W;
499     alloc_blocks++;
500   }
501
502   p = alloc_Hp;
503   alloc_Hp += n;
504   RELEASE_SM_LOCK;
505   return p;
506 }
507
508 lnat
509 allocated_bytes( void )
510 {
511     lnat allocated;
512
513     allocated = alloc_blocks * BLOCK_SIZE_W - (alloc_HpLim - alloc_Hp);
514     if (pinned_object_block != NULL) {
515         allocated -= (pinned_object_block->start + BLOCK_SIZE_W) - 
516             pinned_object_block->free;
517     }
518         
519     return allocated;
520 }
521
522 void
523 tidyAllocateLists (void)
524 {
525     if (small_alloc_list != NULL) {
526         ASSERT(alloc_Hp >= small_alloc_list->start && 
527                alloc_Hp <= small_alloc_list->start + BLOCK_SIZE);
528         small_alloc_list->free = alloc_Hp;
529     }
530 }
531
532 /* ---------------------------------------------------------------------------
533    Allocate a fixed/pinned object.
534
535    We allocate small pinned objects into a single block, allocating a
536    new block when the current one overflows.  The block is chained
537    onto the large_object_list of generation 0 step 0.
538
539    NOTE: The GC can't in general handle pinned objects.  This
540    interface is only safe to use for ByteArrays, which have no
541    pointers and don't require scavenging.  It works because the
542    block's descriptor has the BF_LARGE flag set, so the block is
543    treated as a large object and chained onto various lists, rather
544    than the individual objects being copied.  However, when it comes
545    to scavenge the block, the GC will only scavenge the first object.
546    The reason is that the GC can't linearly scan a block of pinned
547    objects at the moment (doing so would require using the
548    mostly-copying techniques).  But since we're restricting ourselves
549    to pinned ByteArrays, not scavenging is ok.
550
551    This function is called by newPinnedByteArray# which immediately
552    fills the allocated memory with a MutableByteArray#.
553    ------------------------------------------------------------------------- */
554
555 StgPtr
556 allocatePinned( nat n )
557 {
558     StgPtr p;
559     bdescr *bd = pinned_object_block;
560
561     // If the request is for a large object, then allocate()
562     // will give us a pinned object anyway.
563     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
564         return allocate(n);
565     }
566
567     ACQUIRE_SM_LOCK;
568     
569     TICK_ALLOC_HEAP_NOCTR(n);
570     CCS_ALLOC(CCCS,n);
571
572     // we always return 8-byte aligned memory.  bd->free must be
573     // 8-byte aligned to begin with, so we just round up n to
574     // the nearest multiple of 8 bytes.
575     if (sizeof(StgWord) == 4) {
576         n = (n+1) & ~1;
577     }
578
579     // If we don't have a block of pinned objects yet, or the current
580     // one isn't large enough to hold the new object, allocate a new one.
581     if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) {
582         pinned_object_block = bd = allocBlock();
583         dbl_link_onto(bd, &g0s0->large_objects);
584         bd->gen_no = 0;
585         bd->step   = g0s0;
586         bd->flags  = BF_PINNED | BF_LARGE;
587         bd->free   = bd->start;
588         alloc_blocks++;
589     }
590
591     p = bd->free;
592     bd->free += n;
593     RELEASE_SM_LOCK;
594     return p;
595 }
596
597 /* -----------------------------------------------------------------------------
598    Allocation functions for GMP.
599
600    These all use the allocate() interface - we can't have any garbage
601    collection going on during a gmp operation, so we use allocate()
602    which always succeeds.  The gmp operations which might need to
603    allocate will ask the storage manager (via doYouWantToGC()) whether
604    a garbage collection is required, in case we get into a loop doing
605    only allocate() style allocation.
606    -------------------------------------------------------------------------- */
607
608 static void *
609 stgAllocForGMP (size_t size_in_bytes)
610 {
611   StgArrWords* arr;
612   nat data_size_in_words, total_size_in_words;
613   
614   /* round up to a whole number of words */
615   data_size_in_words  = (size_in_bytes + sizeof(W_) + 1) / sizeof(W_);
616   total_size_in_words = sizeofW(StgArrWords) + data_size_in_words;
617   
618   /* allocate and fill it in. */
619   arr = (StgArrWords *)allocate(total_size_in_words);
620   SET_ARR_HDR(arr, &stg_ARR_WORDS_info, CCCS, data_size_in_words);
621   
622   /* and return a ptr to the goods inside the array */
623   return arr->payload;
624 }
625
626 static void *
627 stgReallocForGMP (void *ptr, size_t old_size, size_t new_size)
628 {
629     void *new_stuff_ptr = stgAllocForGMP(new_size);
630     nat i = 0;
631     char *p = (char *) ptr;
632     char *q = (char *) new_stuff_ptr;
633
634     for (; i < old_size; i++, p++, q++) {
635         *q = *p;
636     }
637
638     return(new_stuff_ptr);
639 }
640
641 static void
642 stgDeallocForGMP (void *ptr STG_UNUSED, 
643                   size_t size STG_UNUSED)
644 {
645     /* easy for us: the garbage collector does the dealloc'n */
646 }
647
648 /* -----------------------------------------------------------------------------
649  * Stats and stuff
650  * -------------------------------------------------------------------------- */
651
652 /* -----------------------------------------------------------------------------
653  * calcAllocated()
654  *
655  * Approximate how much we've allocated: number of blocks in the
656  * nursery + blocks allocated via allocate() - unused nusery blocks.
657  * This leaves a little slop at the end of each block, and doesn't
658  * take into account large objects (ToDo).
659  * -------------------------------------------------------------------------- */
660
661 lnat
662 calcAllocated( void )
663 {
664   nat allocated;
665   bdescr *bd;
666
667 #ifdef SMP
668   Capability *cap;
669
670   /* All tasks must be stopped.  Can't assert that all the
671      capabilities are owned by the scheduler, though: one or more
672      tasks might have been stopped while they were running (non-main)
673      threads. */
674   /*  ASSERT(n_free_capabilities == RtsFlags.ParFlags.nNodes); */
675
676   allocated = 
677     n_free_capabilities * RtsFlags.GcFlags.minAllocAreaSize * BLOCK_SIZE_W
678     + allocated_bytes();
679
680   for (cap = free_capabilities; cap != NULL; cap = cap->link) {
681     for ( bd = cap->r.rCurrentNursery->link; bd != NULL; bd = bd->link ) {
682       allocated -= BLOCK_SIZE_W;
683     }
684     if (cap->r.rCurrentNursery->free < cap->r.rCurrentNursery->start 
685         + BLOCK_SIZE_W) {
686       allocated -= (cap->r.rCurrentNursery->start + BLOCK_SIZE_W)
687         - cap->r.rCurrentNursery->free;
688     }
689   }
690
691 #else /* !SMP */
692   bdescr *current_nursery = MainCapability.r.rCurrentNursery;
693
694   allocated = (g0s0->n_blocks * BLOCK_SIZE_W) + allocated_bytes();
695   for ( bd = current_nursery->link; bd != NULL; bd = bd->link ) {
696     allocated -= BLOCK_SIZE_W;
697   }
698   if (current_nursery->free < current_nursery->start + BLOCK_SIZE_W) {
699     allocated -= (current_nursery->start + BLOCK_SIZE_W)
700       - current_nursery->free;
701   }
702 #endif
703
704   total_allocated += allocated;
705   return allocated;
706 }  
707
708 /* Approximate the amount of live data in the heap.  To be called just
709  * after garbage collection (see GarbageCollect()).
710  */
711 extern lnat 
712 calcLive(void)
713 {
714   nat g, s;
715   lnat live = 0;
716   step *stp;
717
718   if (RtsFlags.GcFlags.generations == 1) {
719     live = (g0s0->n_to_blocks - 1) * BLOCK_SIZE_W + 
720       ((lnat)g0s0->hp_bd->free - (lnat)g0s0->hp_bd->start) / sizeof(W_);
721     return live;
722   }
723
724   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
725     for (s = 0; s < generations[g].n_steps; s++) {
726       /* approximate amount of live data (doesn't take into account slop
727        * at end of each block).
728        */
729       if (g == 0 && s == 0) { 
730           continue; 
731       }
732       stp = &generations[g].steps[s];
733       live += (stp->n_large_blocks + stp->n_blocks - 1) * BLOCK_SIZE_W;
734       if (stp->hp_bd != NULL) {
735           live += ((lnat)stp->hp_bd->free - (lnat)stp->hp_bd->start) 
736               / sizeof(W_);
737       }
738     }
739   }
740   return live;
741 }
742
743 /* Approximate the number of blocks that will be needed at the next
744  * garbage collection.
745  *
746  * Assume: all data currently live will remain live.  Steps that will
747  * be collected next time will therefore need twice as many blocks
748  * since all the data will be copied.
749  */
750 extern lnat 
751 calcNeeded(void)
752 {
753     lnat needed = 0;
754     nat g, s;
755     step *stp;
756     
757     for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
758         for (s = 0; s < generations[g].n_steps; s++) {
759             if (g == 0 && s == 0) { continue; }
760             stp = &generations[g].steps[s];
761             if (generations[g].steps[0].n_blocks +
762                 generations[g].steps[0].n_large_blocks 
763                 > generations[g].max_blocks
764                 && stp->is_compacted == 0) {
765                 needed += 2 * stp->n_blocks;
766             } else {
767                 needed += stp->n_blocks;
768             }
769         }
770     }
771     return needed;
772 }
773
774 /* -----------------------------------------------------------------------------
775    Debugging
776
777    memInventory() checks for memory leaks by counting up all the
778    blocks we know about and comparing that to the number of blocks
779    allegedly floating around in the system.
780    -------------------------------------------------------------------------- */
781
782 #ifdef DEBUG
783
784 void
785 memInventory(void)
786 {
787   nat g, s;
788   step *stp;
789   bdescr *bd;
790   lnat total_blocks = 0, free_blocks = 0;
791
792   /* count the blocks we current have */
793
794   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
795     for (s = 0; s < generations[g].n_steps; s++) {
796       stp = &generations[g].steps[s];
797       total_blocks += stp->n_blocks;
798       if (RtsFlags.GcFlags.generations == 1) {
799         /* two-space collector has a to-space too :-) */
800         total_blocks += g0s0->n_to_blocks;
801       }
802       for (bd = stp->large_objects; bd; bd = bd->link) {
803         total_blocks += bd->blocks;
804         /* hack for megablock groups: they have an extra block or two in
805            the second and subsequent megablocks where the block
806            descriptors would normally go.
807         */
808         if (bd->blocks > BLOCKS_PER_MBLOCK) {
809           total_blocks -= (MBLOCK_SIZE / BLOCK_SIZE - BLOCKS_PER_MBLOCK)
810                           * (bd->blocks/(MBLOCK_SIZE/BLOCK_SIZE));
811         }
812       }
813     }
814   }
815
816   /* any blocks held by allocate() */
817   for (bd = small_alloc_list; bd; bd = bd->link) {
818     total_blocks += bd->blocks;
819   }
820
821 #ifdef PROFILING
822   if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER) {
823       total_blocks += retainerStackBlocks();
824   }
825 #endif
826
827   // count the blocks allocated by the arena allocator
828   total_blocks += arenaBlocks();
829
830   /* count the blocks on the free list */
831   free_blocks = countFreeList();
832
833   if (total_blocks + free_blocks != mblocks_allocated *
834       BLOCKS_PER_MBLOCK) {
835     fprintf(stderr, "Blocks: %ld live + %ld free  = %ld total (%ld around)\n",
836             total_blocks, free_blocks, total_blocks + free_blocks,
837             mblocks_allocated * BLOCKS_PER_MBLOCK);
838   }
839
840   ASSERT(total_blocks + free_blocks == mblocks_allocated * BLOCKS_PER_MBLOCK);
841 }
842
843
844 nat
845 countBlocks(bdescr *bd)
846 {
847     nat n;
848     for (n=0; bd != NULL; bd=bd->link) {
849         n += bd->blocks;
850     }
851     return n;
852 }
853
854 /* Full heap sanity check. */
855 void
856 checkSanity( void )
857 {
858     nat g, s;
859
860     if (RtsFlags.GcFlags.generations == 1) {
861         checkHeap(g0s0->to_blocks);
862         checkChain(g0s0->large_objects);
863     } else {
864         
865         for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
866             for (s = 0; s < generations[g].n_steps; s++) {
867                 ASSERT(countBlocks(generations[g].steps[s].blocks)
868                        == generations[g].steps[s].n_blocks);
869                 ASSERT(countBlocks(generations[g].steps[s].large_objects)
870                        == generations[g].steps[s].n_large_blocks);
871                 if (g == 0 && s == 0) { continue; }
872                 checkHeap(generations[g].steps[s].blocks);
873                 checkChain(generations[g].steps[s].large_objects);
874                 if (g > 0) {
875                     checkMutableList(generations[g].mut_list, g);
876                     checkMutOnceList(generations[g].mut_once_list, g);
877                 }
878             }
879         }
880         checkFreeListSanity();
881     }
882 }
883
884 // handy function for use in gdb, because Bdescr() is inlined.
885 extern bdescr *_bdescr( StgPtr p );
886
887 bdescr *
888 _bdescr( StgPtr p )
889 {
890     return Bdescr(p);
891 }
892
893 #endif