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