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