~ubuntu-branches/ubuntu/precise/ghc/precise

« back to all changes in this revision

Viewing changes to rts/sm/Storage.c

  • Committer: Bazaar Package Importer
  • Author(s): Joachim Breitner
  • Date: 2011-01-17 12:49:24 UTC
  • Revision ID: james.westby@ubuntu.com-20110117124924-do1pym1jlf5o636m
Tags: upstream-7.0.1
ImportĀ upstreamĀ versionĀ 7.0.1

Show diffs side-by-side

added added

removed removed

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