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