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