summaryrefslogtreecommitdiff
path: root/rts/sm/GCUtils.c
blob: 61b72b6c0af8baea35bbbebb8cb1909257908342 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* -----------------------------------------------------------------------------
 *
 * (c) The GHC Team 1998-2006
 *
 * Generational garbage collector: utilities
 *
 * Documentation on the architecture of the Garbage Collector can be
 * found in the online commentary:
 * 
 *   http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
 *
 * ---------------------------------------------------------------------------*/

#include "Rts.h"
#include "Storage.h"
#include "GC.h"
#include "GCUtils.h"

/* -----------------------------------------------------------------------------
   Allocate a new to-space block in the given step.
   -------------------------------------------------------------------------- */

bdescr *
gc_alloc_block(step *stp)
{
    bdescr *bd = allocBlock();
    bd->gen_no = stp->gen_no;
    bd->step = stp;
    bd->link = NULL;

    // blocks in to-space in generations up to and including N
    // get the BF_EVACUATED flag.
    if (stp->gen_no <= N) {
	bd->flags = BF_EVACUATED;
    } else {
	bd->flags = 0;
    }

    // Start a new to-space block, chain it on after the previous one.
    if (stp->hp_bd != NULL) {
	stp->hp_bd->free = stp->hp;
	stp->hp_bd->link = bd;
    }

    stp->hp_bd = bd;
    stp->hp    = bd->start;
    stp->hpLim = stp->hp + BLOCK_SIZE_W;

    stp->n_blocks++;
    new_blocks++;

    return bd;
}

bdescr *
gc_alloc_scavd_block(step *stp)
{
    bdescr *bd = allocBlock();
    bd->gen_no = stp->gen_no;
    bd->step = stp;

    // blocks in to-space in generations up to and including N
    // get the BF_EVACUATED flag.
    if (stp->gen_no <= N) {
	bd->flags = BF_EVACUATED;
    } else {
	bd->flags = 0;
    }

    bd->link = stp->blocks;
    stp->blocks = bd;

    if (stp->scavd_hp != NULL) {
	Bdescr(stp->scavd_hp)->free = stp->scavd_hp;
    }
    stp->scavd_hp    = bd->start;
    stp->scavd_hpLim = stp->scavd_hp + BLOCK_SIZE_W;

    stp->n_blocks++;
    new_scavd_blocks++;

    return bd;
}