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