GC refactoring, remove "steps"
[ghc-hetmet.git] / rts / sm / Storage.c
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2008
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
17 #include "Storage.h"
18 #include "RtsUtils.h"
19 #include "Stats.h"
20 #include "BlockAlloc.h"
21 #include "Weak.h"
22 #include "Sanity.h"
23 #include "Arena.h"
24 #include "Capability.h"
25 #include "Schedule.h"
26 #include "RetainerProfile.h"    // for counting memory blocks (memInventory)
27 #include "OSMem.h"
28 #include "Trace.h"
29 #include "GC.h"
30 #include "Evac.h"
31
32 #include <string.h>
33
34 #include "ffi.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 nat alloc_blocks_lim;    /* GC if n_large_blocks in any nursery
44                           * reaches this. */
45
46 bdescr *exec_block;
47
48 generation *generations = NULL; /* all the generations */
49 generation *g0          = NULL; /* generation 0, for convenience */
50 generation *oldest_gen  = NULL; /* oldest generation, for convenience */
51
52 ullong total_allocated = 0;     /* total memory allocated during run */
53
54 nursery *nurseries = NULL;     /* array of nurseries, size == n_capabilities */
55
56 #ifdef THREADED_RTS
57 /*
58  * Storage manager mutex:  protects all the above state from
59  * simultaneous access by two STG threads.
60  */
61 Mutex sm_mutex;
62 #endif
63
64 static void allocNurseries ( void );
65
66 static void
67 initGeneration (generation *gen, int g)
68 {
69     gen->no = g;
70     gen->collections = 0;
71     gen->par_collections = 0;
72     gen->failed_promotions = 0;
73     gen->max_blocks = 0;
74     gen->blocks = NULL;
75     gen->n_blocks = 0;
76     gen->n_words = 0;
77     gen->live_estimate = 0;
78     gen->old_blocks = NULL;
79     gen->n_old_blocks = 0;
80     gen->large_objects = NULL;
81     gen->n_large_blocks = 0;
82     gen->mut_list = allocBlock();
83     gen->scavenged_large_objects = NULL;
84     gen->n_scavenged_large_blocks = 0;
85     gen->mark = 0;
86     gen->compact = 0;
87     gen->bitmap = NULL;
88 #ifdef THREADED_RTS
89     initSpinLock(&gen->sync_large_objects);
90 #endif
91     gen->threads = END_TSO_QUEUE;
92     gen->old_threads = END_TSO_QUEUE;
93 }
94
95 void
96 initStorage( void )
97 {
98   nat g;
99
100   if (generations != NULL) {
101       // multi-init protection
102       return;
103   }
104
105   initMBlocks();
106
107   /* Sanity check to make sure the LOOKS_LIKE_ macros appear to be
108    * doing something reasonable.
109    */
110   /* We use the NOT_NULL variant or gcc warns that the test is always true */
111   ASSERT(LOOKS_LIKE_INFO_PTR_NOT_NULL((StgWord)&stg_BLACKHOLE_info));
112   ASSERT(LOOKS_LIKE_CLOSURE_PTR(&stg_dummy_ret_closure));
113   ASSERT(!HEAP_ALLOCED(&stg_dummy_ret_closure));
114   
115   if (RtsFlags.GcFlags.maxHeapSize != 0 &&
116       RtsFlags.GcFlags.heapSizeSuggestion > 
117       RtsFlags.GcFlags.maxHeapSize) {
118     RtsFlags.GcFlags.maxHeapSize = RtsFlags.GcFlags.heapSizeSuggestion;
119   }
120
121   if (RtsFlags.GcFlags.maxHeapSize != 0 &&
122       RtsFlags.GcFlags.minAllocAreaSize > 
123       RtsFlags.GcFlags.maxHeapSize) {
124       errorBelch("maximum heap size (-M) is smaller than minimum alloc area size (-A)");
125       RtsFlags.GcFlags.minAllocAreaSize = RtsFlags.GcFlags.maxHeapSize;
126   }
127
128   initBlockAllocator();
129   
130 #if defined(THREADED_RTS)
131   initMutex(&sm_mutex);
132 #endif
133
134   ACQUIRE_SM_LOCK;
135
136   /* allocate generation info array */
137   generations = (generation *)stgMallocBytes(RtsFlags.GcFlags.generations 
138                                              * sizeof(struct generation_),
139                                              "initStorage: gens");
140
141   /* Initialise all generations */
142   for(g = 0; g < RtsFlags.GcFlags.generations; g++) {
143       initGeneration(&generations[g], g);
144   }
145
146   /* A couple of convenience pointers */
147   g0 = &generations[0];
148   oldest_gen = &generations[RtsFlags.GcFlags.generations-1];
149
150   nurseries = stgMallocBytes(n_capabilities * sizeof(struct nursery_),
151                              "initStorage: nurseries");
152   
153   /* Set up the destination pointers in each younger gen. step */
154   for (g = 0; g < RtsFlags.GcFlags.generations-1; g++) {
155       generations[g].to = &generations[g+1];
156   }
157   oldest_gen->to = oldest_gen;
158   
159   /* The oldest generation has one step. */
160   if (RtsFlags.GcFlags.compact || RtsFlags.GcFlags.sweep) {
161       if (RtsFlags.GcFlags.generations == 1) {
162           errorBelch("WARNING: compact/sweep is incompatible with -G1; disabled");
163       } else {
164           oldest_gen->mark = 1;
165           if (RtsFlags.GcFlags.compact)
166               oldest_gen->compact = 1;
167       }
168   }
169
170   generations[0].max_blocks = 0;
171
172   /* The allocation area.  Policy: keep the allocation area
173    * small to begin with, even if we have a large suggested heap
174    * size.  Reason: we're going to do a major collection first, and we
175    * don't want it to be a big one.  This vague idea is borne out by 
176    * rigorous experimental evidence.
177    */
178   allocNurseries();
179
180   weak_ptr_list = NULL;
181   caf_list = NULL;
182   revertible_caf_list = NULL;
183    
184   /* initialise the allocate() interface */
185   alloc_blocks_lim = RtsFlags.GcFlags.minAllocAreaSize;
186
187   exec_block = NULL;
188
189 #ifdef THREADED_RTS
190   initSpinLock(&gc_alloc_block_sync);
191   whitehole_spin = 0;
192 #endif
193
194   N = 0;
195
196   initGcThreads();
197
198   IF_DEBUG(gc, statDescribeGens());
199
200   RELEASE_SM_LOCK;
201 }
202
203 void
204 exitStorage (void)
205 {
206     stat_exit(calcAllocated());
207 }
208
209 void
210 freeStorage (void)
211 {
212     stgFree(generations);
213     freeAllMBlocks();
214 #if defined(THREADED_RTS)
215     closeMutex(&sm_mutex);
216 #endif
217     stgFree(nurseries);
218     freeGcThreads();
219 }
220
221 /* -----------------------------------------------------------------------------
222    CAF management.
223
224    The entry code for every CAF does the following:
225      
226       - builds a CAF_BLACKHOLE in the heap
227       - pushes an update frame pointing to the CAF_BLACKHOLE
228       - invokes UPD_CAF(), which:
229           - calls newCaf, below
230           - updates the CAF with a static indirection to the CAF_BLACKHOLE
231       
232    Why do we build a BLACKHOLE in the heap rather than just updating
233    the thunk directly?  It's so that we only need one kind of update
234    frame - otherwise we'd need a static version of the update frame too.
235
236    newCaf() does the following:
237        
238       - it puts the CAF on the oldest generation's mut-once list.
239         This is so that we can treat the CAF as a root when collecting
240         younger generations.
241
242    For GHCI, we have additional requirements when dealing with CAFs:
243
244       - we must *retain* all dynamically-loaded CAFs ever entered,
245         just in case we need them again.
246       - we must be able to *revert* CAFs that have been evaluated, to
247         their pre-evaluated form.
248
249       To do this, we use an additional CAF list.  When newCaf() is
250       called on a dynamically-loaded CAF, we add it to the CAF list
251       instead of the old-generation mutable list, and save away its
252       old info pointer (in caf->saved_info) for later reversion.
253
254       To revert all the CAFs, we traverse the CAF list and reset the
255       info pointer to caf->saved_info, then throw away the CAF list.
256       (see GC.c:revertCAFs()).
257
258       -- SDM 29/1/01
259
260    -------------------------------------------------------------------------- */
261
262 void
263 newCAF(StgClosure* caf)
264 {
265   ACQUIRE_SM_LOCK;
266
267 #ifdef DYNAMIC
268   if(keepCAFs)
269   {
270     // HACK:
271     // If we are in GHCi _and_ we are using dynamic libraries,
272     // then we can't redirect newCAF calls to newDynCAF (see below),
273     // so we make newCAF behave almost like newDynCAF.
274     // The dynamic libraries might be used by both the interpreted
275     // program and GHCi itself, so they must not be reverted.
276     // This also means that in GHCi with dynamic libraries, CAFs are not
277     // garbage collected. If this turns out to be a problem, we could
278     // do another hack here and do an address range test on caf to figure
279     // out whether it is from a dynamic library.
280     ((StgIndStatic *)caf)->saved_info  = (StgInfoTable *)caf->header.info;
281     ((StgIndStatic *)caf)->static_link = caf_list;
282     caf_list = caf;
283   }
284   else
285 #endif
286   {
287     /* Put this CAF on the mutable list for the old generation.
288     * This is a HACK - the IND_STATIC closure doesn't really have
289     * a mut_link field, but we pretend it has - in fact we re-use
290     * the STATIC_LINK field for the time being, because when we
291     * come to do a major GC we won't need the mut_link field
292     * any more and can use it as a STATIC_LINK.
293     */
294     ((StgIndStatic *)caf)->saved_info = NULL;
295     recordMutableGen(caf, oldest_gen->no);
296   }
297   
298   RELEASE_SM_LOCK;
299 }
300
301 // An alternate version of newCaf which is used for dynamically loaded
302 // object code in GHCi.  In this case we want to retain *all* CAFs in
303 // the object code, because they might be demanded at any time from an
304 // expression evaluated on the command line.
305 // Also, GHCi might want to revert CAFs, so we add these to the
306 // revertible_caf_list.
307 //
308 // The linker hackily arranges that references to newCaf from dynamic
309 // code end up pointing to newDynCAF.
310 void
311 newDynCAF(StgClosure *caf)
312 {
313     ACQUIRE_SM_LOCK;
314
315     ((StgIndStatic *)caf)->saved_info  = (StgInfoTable *)caf->header.info;
316     ((StgIndStatic *)caf)->static_link = revertible_caf_list;
317     revertible_caf_list = caf;
318
319     RELEASE_SM_LOCK;
320 }
321
322 /* -----------------------------------------------------------------------------
323    Nursery management.
324    -------------------------------------------------------------------------- */
325
326 static bdescr *
327 allocNursery (bdescr *tail, nat blocks)
328 {
329     bdescr *bd;
330     nat i;
331
332     // Allocate a nursery: we allocate fresh blocks one at a time and
333     // cons them on to the front of the list, not forgetting to update
334     // the back pointer on the tail of the list to point to the new block.
335     for (i=0; i < blocks; i++) {
336         // @LDV profiling
337         /*
338           processNursery() in LdvProfile.c assumes that every block group in
339           the nursery contains only a single block. So, if a block group is
340           given multiple blocks, change processNursery() accordingly.
341         */
342         bd = allocBlock();
343         bd->link = tail;
344         // double-link the nursery: we might need to insert blocks
345         if (tail != NULL) {
346             tail->u.back = bd;
347         }
348         initBdescr(bd, g0, g0);
349         bd->flags = 0;
350         bd->free = bd->start;
351         tail = bd;
352     }
353     tail->u.back = NULL;
354     return tail;
355 }
356
357 static void
358 assignNurseriesToCapabilities (void)
359 {
360     nat i;
361
362     for (i = 0; i < n_capabilities; i++) {
363         capabilities[i].r.rNursery        = &nurseries[i];
364         capabilities[i].r.rCurrentNursery = nurseries[i].blocks;
365         capabilities[i].r.rCurrentAlloc   = NULL;
366     }
367 }
368
369 static void
370 allocNurseries( void )
371
372     nat i;
373
374     for (i = 0; i < n_capabilities; i++) {
375         nurseries[i].blocks = 
376             allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
377         nurseries[i].n_blocks =
378             RtsFlags.GcFlags.minAllocAreaSize;
379     }
380     assignNurseriesToCapabilities();
381 }
382       
383 void
384 resetNurseries( void )
385 {
386     nat i;
387     bdescr *bd;
388
389     for (i = 0; i < n_capabilities; i++) {
390         for (bd = nurseries[i].blocks; bd; bd = bd->link) {
391             bd->free = bd->start;
392             ASSERT(bd->gen_no == 0);
393             ASSERT(bd->gen == g0);
394             IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
395         }
396     }
397     assignNurseriesToCapabilities();
398 }
399
400 lnat
401 countNurseryBlocks (void)
402 {
403     nat i;
404     lnat blocks = 0;
405
406     for (i = 0; i < n_capabilities; i++) {
407         blocks += nurseries[i].n_blocks;
408     }
409     return blocks;
410 }
411
412 static void
413 resizeNursery ( nursery *nursery, nat blocks )
414 {
415   bdescr *bd;
416   nat nursery_blocks;
417
418   nursery_blocks = nursery->n_blocks;
419   if (nursery_blocks == blocks) return;
420
421   if (nursery_blocks < blocks) {
422       debugTrace(DEBUG_gc, "increasing size of nursery to %d blocks", 
423                  blocks);
424     nursery->blocks = allocNursery(nursery->blocks, blocks-nursery_blocks);
425   } 
426   else {
427     bdescr *next_bd;
428     
429     debugTrace(DEBUG_gc, "decreasing size of nursery to %d blocks", 
430                blocks);
431
432     bd = nursery->blocks;
433     while (nursery_blocks > blocks) {
434         next_bd = bd->link;
435         next_bd->u.back = NULL;
436         nursery_blocks -= bd->blocks; // might be a large block
437         freeGroup(bd);
438         bd = next_bd;
439     }
440     nursery->blocks = bd;
441     // might have gone just under, by freeing a large block, so make
442     // up the difference.
443     if (nursery_blocks < blocks) {
444         nursery->blocks = allocNursery(nursery->blocks, blocks-nursery_blocks);
445     }
446   }
447   
448   nursery->n_blocks = blocks;
449   ASSERT(countBlocks(nursery->blocks) == nursery->n_blocks);
450 }
451
452 // 
453 // Resize each of the nurseries to the specified size.
454 //
455 void
456 resizeNurseriesFixed (nat blocks)
457 {
458     nat i;
459     for (i = 0; i < n_capabilities; i++) {
460         resizeNursery(&nurseries[i], blocks);
461     }
462 }
463
464 // 
465 // Resize the nurseries to the total specified size.
466 //
467 void
468 resizeNurseries (nat blocks)
469 {
470     // If there are multiple nurseries, then we just divide the number
471     // of available blocks between them.
472     resizeNurseriesFixed(blocks / n_capabilities);
473 }
474
475
476 /* -----------------------------------------------------------------------------
477    move_TSO is called to update the TSO structure after it has been
478    moved from one place to another.
479    -------------------------------------------------------------------------- */
480
481 void
482 move_TSO (StgTSO *src, StgTSO *dest)
483 {
484     ptrdiff_t diff;
485
486     // relocate the stack pointer... 
487     diff = (StgPtr)dest - (StgPtr)src; // In *words* 
488     dest->sp = (StgPtr)dest->sp + diff;
489 }
490
491 /* -----------------------------------------------------------------------------
492    split N blocks off the front of the given bdescr, returning the
493    new block group.  We add the remainder to the large_blocks list
494    in the same step as the original block.
495    -------------------------------------------------------------------------- */
496
497 bdescr *
498 splitLargeBlock (bdescr *bd, nat blocks)
499 {
500     bdescr *new_bd;
501
502     ACQUIRE_SM_LOCK;
503
504     ASSERT(countBlocks(bd->gen->large_objects) == bd->gen->n_large_blocks);
505
506     // subtract the original number of blocks from the counter first
507     bd->gen->n_large_blocks -= bd->blocks;
508
509     new_bd = splitBlockGroup (bd, blocks);
510     initBdescr(new_bd, bd->gen, bd->gen->to);
511     new_bd->flags   = BF_LARGE | (bd->flags & BF_EVACUATED); 
512     // if new_bd is in an old generation, we have to set BF_EVACUATED
513     new_bd->free    = bd->free;
514     dbl_link_onto(new_bd, &bd->gen->large_objects);
515
516     ASSERT(new_bd->free <= new_bd->start + new_bd->blocks * BLOCK_SIZE_W);
517
518     // add the new number of blocks to the counter.  Due to the gaps
519     // for block descriptors, new_bd->blocks + bd->blocks might not be
520     // equal to the original bd->blocks, which is why we do it this way.
521     bd->gen->n_large_blocks += bd->blocks + new_bd->blocks;
522
523     ASSERT(countBlocks(bd->gen->large_objects) == bd->gen->n_large_blocks);
524
525     RELEASE_SM_LOCK;
526
527     return new_bd;
528 }
529
530 /* -----------------------------------------------------------------------------
531    allocate()
532
533    This allocates memory in the current thread - it is intended for
534    use primarily from STG-land where we have a Capability.  It is
535    better than allocate() because it doesn't require taking the
536    sm_mutex lock in the common case.
537
538    Memory is allocated directly from the nursery if possible (but not
539    from the current nursery block, so as not to interfere with
540    Hp/HpLim).
541    -------------------------------------------------------------------------- */
542
543 StgPtr
544 allocate (Capability *cap, lnat n)
545 {
546     bdescr *bd;
547     StgPtr p;
548
549     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
550         lnat req_blocks =  (lnat)BLOCK_ROUND_UP(n*sizeof(W_)) / BLOCK_SIZE;
551
552         // Attempting to allocate an object larger than maxHeapSize
553         // should definitely be disallowed.  (bug #1791)
554         if (RtsFlags.GcFlags.maxHeapSize > 0 && 
555             req_blocks >= RtsFlags.GcFlags.maxHeapSize) {
556             heapOverflow();
557             // heapOverflow() doesn't exit (see #2592), but we aren't
558             // in a position to do a clean shutdown here: we
559             // either have to allocate the memory or exit now.
560             // Allocating the memory would be bad, because the user
561             // has requested that we not exceed maxHeapSize, so we
562             // just exit.
563             stg_exit(EXIT_HEAPOVERFLOW);
564         }
565
566         ACQUIRE_SM_LOCK
567         bd = allocGroup(req_blocks);
568         dbl_link_onto(bd, &g0->large_objects);
569         g0->n_large_blocks += bd->blocks; // might be larger than req_blocks
570         RELEASE_SM_LOCK;
571         initBdescr(bd, g0, g0);
572         bd->flags = BF_LARGE;
573         bd->free = bd->start + n;
574         return bd->start;
575     }
576
577     /* small allocation (<LARGE_OBJECT_THRESHOLD) */
578
579     TICK_ALLOC_HEAP_NOCTR(n);
580     CCS_ALLOC(CCCS,n);
581     
582     bd = cap->r.rCurrentAlloc;
583     if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
584         
585         // The CurrentAlloc block is full, we need to find another
586         // one.  First, we try taking the next block from the
587         // nursery:
588         bd = cap->r.rCurrentNursery->link;
589         
590         if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
591             // The nursery is empty, or the next block is already
592             // full: allocate a fresh block (we can't fail here).
593             ACQUIRE_SM_LOCK;
594             bd = allocBlock();
595             cap->r.rNursery->n_blocks++;
596             RELEASE_SM_LOCK;
597             initBdescr(bd, g0, g0);
598             bd->flags = 0;
599             // If we had to allocate a new block, then we'll GC
600             // pretty quickly now, because MAYBE_GC() will
601             // notice that CurrentNursery->link is NULL.
602         } else {
603             // we have a block in the nursery: take it and put
604             // it at the *front* of the nursery list, and use it
605             // to allocate() from.
606             cap->r.rCurrentNursery->link = bd->link;
607             if (bd->link != NULL) {
608                 bd->link->u.back = cap->r.rCurrentNursery;
609             }
610         }
611         dbl_link_onto(bd, &cap->r.rNursery->blocks);
612         cap->r.rCurrentAlloc = bd;
613         IF_DEBUG(sanity, checkNurserySanity(cap->r.rNursery));
614     }
615     p = bd->free;
616     bd->free += n;
617     return p;
618 }
619
620 /* ---------------------------------------------------------------------------
621    Allocate a fixed/pinned object.
622
623    We allocate small pinned objects into a single block, allocating a
624    new block when the current one overflows.  The block is chained
625    onto the large_object_list of generation 0.
626
627    NOTE: The GC can't in general handle pinned objects.  This
628    interface is only safe to use for ByteArrays, which have no
629    pointers and don't require scavenging.  It works because the
630    block's descriptor has the BF_LARGE flag set, so the block is
631    treated as a large object and chained onto various lists, rather
632    than the individual objects being copied.  However, when it comes
633    to scavenge the block, the GC will only scavenge the first object.
634    The reason is that the GC can't linearly scan a block of pinned
635    objects at the moment (doing so would require using the
636    mostly-copying techniques).  But since we're restricting ourselves
637    to pinned ByteArrays, not scavenging is ok.
638
639    This function is called by newPinnedByteArray# which immediately
640    fills the allocated memory with a MutableByteArray#.
641    ------------------------------------------------------------------------- */
642
643 StgPtr
644 allocatePinned (Capability *cap, lnat n)
645 {
646     StgPtr p;
647     bdescr *bd;
648
649     // If the request is for a large object, then allocate()
650     // will give us a pinned object anyway.
651     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
652         p = allocate(cap, n);
653         Bdescr(p)->flags |= BF_PINNED;
654         return p;
655     }
656
657     TICK_ALLOC_HEAP_NOCTR(n);
658     CCS_ALLOC(CCCS,n);
659
660     bd = cap->pinned_object_block;
661     
662     // If we don't have a block of pinned objects yet, or the current
663     // one isn't large enough to hold the new object, allocate a new one.
664     if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) {
665         ACQUIRE_SM_LOCK;
666         cap->pinned_object_block = bd = allocBlock();
667         dbl_link_onto(bd, &g0->large_objects);
668         g0->n_large_blocks++;
669         RELEASE_SM_LOCK;
670         initBdescr(bd, g0, g0);
671         bd->flags  = BF_PINNED | BF_LARGE;
672         bd->free   = bd->start;
673     }
674
675     p = bd->free;
676     bd->free += n;
677     return p;
678 }
679
680 /* -----------------------------------------------------------------------------
681    Write Barriers
682    -------------------------------------------------------------------------- */
683
684 /*
685    This is the write barrier for MUT_VARs, a.k.a. IORefs.  A
686    MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
687    is.  When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
688    and is put on the mutable list.
689 */
690 void
691 dirty_MUT_VAR(StgRegTable *reg, StgClosure *p)
692 {
693     Capability *cap = regTableToCapability(reg);
694     bdescr *bd;
695     if (p->header.info == &stg_MUT_VAR_CLEAN_info) {
696         p->header.info = &stg_MUT_VAR_DIRTY_info;
697         bd = Bdescr((StgPtr)p);
698         if (bd->gen_no > 0) recordMutableCap(p,cap,bd->gen_no);
699     }
700 }
701
702 // Setting a TSO's link field with a write barrier.
703 // It is *not* necessary to call this function when
704 //    * setting the link field to END_TSO_QUEUE
705 //    * putting a TSO on the blackhole_queue
706 //    * setting the link field of the currently running TSO, as it
707 //      will already be dirty.
708 void
709 setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target)
710 {
711     bdescr *bd;
712     if (tso->dirty == 0 && (tso->flags & TSO_LINK_DIRTY) == 0) {
713         tso->flags |= TSO_LINK_DIRTY;
714         bd = Bdescr((StgPtr)tso);
715         if (bd->gen_no > 0) recordMutableCap((StgClosure*)tso,cap,bd->gen_no);
716     }
717     tso->_link = target;
718 }
719
720 void
721 dirty_TSO (Capability *cap, StgTSO *tso)
722 {
723     bdescr *bd;
724     if (tso->dirty == 0 && (tso->flags & TSO_LINK_DIRTY) == 0) {
725         bd = Bdescr((StgPtr)tso);
726         if (bd->gen_no > 0) recordMutableCap((StgClosure*)tso,cap,bd->gen_no);
727     }
728     tso->dirty = 1;
729 }
730
731 /*
732    This is the write barrier for MVARs.  An MVAR_CLEAN objects is not
733    on the mutable list; a MVAR_DIRTY is.  When written to, a
734    MVAR_CLEAN turns into a MVAR_DIRTY and is put on the mutable list.
735    The check for MVAR_CLEAN is inlined at the call site for speed,
736    this really does make a difference on concurrency-heavy benchmarks
737    such as Chaneneos and cheap-concurrency.
738 */
739 void
740 dirty_MVAR(StgRegTable *reg, StgClosure *p)
741 {
742     Capability *cap = regTableToCapability(reg);
743     bdescr *bd;
744     bd = Bdescr((StgPtr)p);
745     if (bd->gen_no > 0) recordMutableCap(p,cap,bd->gen_no);
746 }
747
748 /* -----------------------------------------------------------------------------
749  * Stats and stuff
750  * -------------------------------------------------------------------------- */
751
752 /* -----------------------------------------------------------------------------
753  * calcAllocated()
754  *
755  * Approximate how much we've allocated: number of blocks in the
756  * nursery + blocks allocated via allocate() - unused nusery blocks.
757  * This leaves a little slop at the end of each block.
758  * -------------------------------------------------------------------------- */
759
760 lnat
761 calcAllocated( void )
762 {
763   nat allocated;
764   bdescr *bd;
765   nat i;
766
767   allocated = countNurseryBlocks() * BLOCK_SIZE_W;
768   
769   for (i = 0; i < n_capabilities; i++) {
770       Capability *cap;
771       for ( bd = capabilities[i].r.rCurrentNursery->link; 
772             bd != NULL; bd = bd->link ) {
773           allocated -= BLOCK_SIZE_W;
774       }
775       cap = &capabilities[i];
776       if (cap->r.rCurrentNursery->free < 
777           cap->r.rCurrentNursery->start + BLOCK_SIZE_W) {
778           allocated -= (cap->r.rCurrentNursery->start + BLOCK_SIZE_W)
779               - cap->r.rCurrentNursery->free;
780       }
781       if (cap->pinned_object_block != NULL) {
782           allocated -= (cap->pinned_object_block->start + BLOCK_SIZE_W) - 
783               cap->pinned_object_block->free;
784       }
785   }
786
787   total_allocated += allocated;
788   return allocated;
789 }  
790
791 /* Approximate the amount of live data in the heap.  To be called just
792  * after garbage collection (see GarbageCollect()).
793  */
794 lnat calcLiveBlocks (void)
795 {
796   nat g;
797   lnat live = 0;
798   generation *gen;
799
800   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
801       /* approximate amount of live data (doesn't take into account slop
802        * at end of each block).
803        */
804       gen = &generations[g];
805       live += gen->n_large_blocks + gen->n_blocks;
806   }
807   return live;
808 }
809
810 lnat countOccupied (bdescr *bd)
811 {
812     lnat words;
813
814     words = 0;
815     for (; bd != NULL; bd = bd->link) {
816         ASSERT(bd->free <= bd->start + bd->blocks * BLOCK_SIZE_W);
817         words += bd->free - bd->start;
818     }
819     return words;
820 }
821
822 // Return an accurate count of the live data in the heap, excluding
823 // generation 0.
824 lnat calcLiveWords (void)
825 {
826     nat g;
827     lnat live;
828     generation *gen;
829     
830     live = 0;
831     for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
832         gen = &generations[g];
833         live += gen->n_words + countOccupied(gen->large_objects);
834     }
835     return live;
836 }
837
838 /* Approximate the number of blocks that will be needed at the next
839  * garbage collection.
840  *
841  * Assume: all data currently live will remain live.  Generationss
842  * that will be collected next time will therefore need twice as many
843  * blocks since all the data will be copied.
844  */
845 extern lnat 
846 calcNeeded(void)
847 {
848     lnat needed = 0;
849     nat g;
850     generation *gen;
851     
852     for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
853         gen = &generations[g];
854
855         // we need at least this much space
856         needed += gen->n_blocks + gen->n_large_blocks;
857         
858         // any additional space needed to collect this gen next time?
859         if (g == 0 || // always collect gen 0
860             (gen->n_blocks + gen->n_large_blocks > gen->max_blocks)) {
861             // we will collect this gen next time
862             if (gen->mark) {
863                 //  bitmap:
864                 needed += gen->n_blocks / BITS_IN(W_);
865                 //  mark stack:
866                 needed += gen->n_blocks / 100;
867             }
868             if (gen->compact) {
869                 continue; // no additional space needed for compaction
870             } else {
871                 needed += gen->n_blocks;
872             }
873         }
874     }
875     return needed;
876 }
877
878 /* ----------------------------------------------------------------------------
879    Executable memory
880
881    Executable memory must be managed separately from non-executable
882    memory.  Most OSs these days require you to jump through hoops to
883    dynamically allocate executable memory, due to various security
884    measures.
885
886    Here we provide a small memory allocator for executable memory.
887    Memory is managed with a page granularity; we allocate linearly
888    in the page, and when the page is emptied (all objects on the page
889    are free) we free the page again, not forgetting to make it
890    non-executable.
891
892    TODO: The inability to handle objects bigger than BLOCK_SIZE_W means that
893          the linker cannot use allocateExec for loading object code files
894          on Windows. Once allocateExec can handle larger objects, the linker
895          should be modified to use allocateExec instead of VirtualAlloc.
896    ------------------------------------------------------------------------- */
897
898 #if defined(linux_HOST_OS)
899
900 // On Linux we need to use libffi for allocating executable memory,
901 // because it knows how to work around the restrictions put in place
902 // by SELinux.
903
904 void *allocateExec (nat bytes, void **exec_ret)
905 {
906     void **ret, **exec;
907     ACQUIRE_SM_LOCK;
908     ret = ffi_closure_alloc (sizeof(void *) + (size_t)bytes, (void**)&exec);
909     RELEASE_SM_LOCK;
910     if (ret == NULL) return ret;
911     *ret = ret; // save the address of the writable mapping, for freeExec().
912     *exec_ret = exec + 1;
913     return (ret + 1);
914 }
915
916 // freeExec gets passed the executable address, not the writable address. 
917 void freeExec (void *addr)
918 {
919     void *writable;
920     writable = *((void**)addr - 1);
921     ACQUIRE_SM_LOCK;
922     ffi_closure_free (writable);
923     RELEASE_SM_LOCK
924 }
925
926 #else
927
928 void *allocateExec (nat bytes, void **exec_ret)
929 {
930     void *ret;
931     nat n;
932
933     ACQUIRE_SM_LOCK;
934
935     // round up to words.
936     n  = (bytes + sizeof(W_) + 1) / sizeof(W_);
937
938     if (n+1 > BLOCK_SIZE_W) {
939         barf("allocateExec: can't handle large objects");
940     }
941
942     if (exec_block == NULL || 
943         exec_block->free + n + 1 > exec_block->start + BLOCK_SIZE_W) {
944         bdescr *bd;
945         lnat pagesize = getPageSize();
946         bd = allocGroup(stg_max(1, pagesize / BLOCK_SIZE));
947         debugTrace(DEBUG_gc, "allocate exec block %p", bd->start);
948         bd->gen_no = 0;
949         bd->flags = BF_EXEC;
950         bd->link = exec_block;
951         if (exec_block != NULL) {
952             exec_block->u.back = bd;
953         }
954         bd->u.back = NULL;
955         setExecutable(bd->start, bd->blocks * BLOCK_SIZE, rtsTrue);
956         exec_block = bd;
957     }
958     *(exec_block->free) = n;  // store the size of this chunk
959     exec_block->gen_no += n;  // gen_no stores the number of words allocated
960     ret = exec_block->free + 1;
961     exec_block->free += n + 1;
962
963     RELEASE_SM_LOCK
964     *exec_ret = ret;
965     return ret;
966 }
967
968 void freeExec (void *addr)
969 {
970     StgPtr p = (StgPtr)addr - 1;
971     bdescr *bd = Bdescr((StgPtr)p);
972
973     if ((bd->flags & BF_EXEC) == 0) {
974         barf("freeExec: not executable");
975     }
976
977     if (*(StgPtr)p == 0) {
978         barf("freeExec: already free?");
979     }
980
981     ACQUIRE_SM_LOCK;
982
983     bd->gen_no -= *(StgPtr)p;
984     *(StgPtr)p = 0;
985
986     if (bd->gen_no == 0) {
987         // Free the block if it is empty, but not if it is the block at
988         // the head of the queue.
989         if (bd != exec_block) {
990             debugTrace(DEBUG_gc, "free exec block %p", bd->start);
991             dbl_link_remove(bd, &exec_block);
992             setExecutable(bd->start, bd->blocks * BLOCK_SIZE, rtsFalse);
993             freeGroup(bd);
994         } else {
995             bd->free = bd->start;
996         }
997     }
998
999     RELEASE_SM_LOCK
1000 }    
1001
1002 #endif /* mingw32_HOST_OS */
1003
1004 #ifdef DEBUG
1005
1006 // handy function for use in gdb, because Bdescr() is inlined.
1007 extern bdescr *_bdescr( StgPtr p );
1008
1009 bdescr *
1010 _bdescr( StgPtr p )
1011 {
1012     return Bdescr(p);
1013 }
1014
1015 #endif