[project @ 2004-08-13 10:45:16 by simonmar]
[ghc-hetmet.git] / ghc / includes / StgStorage.h
1 /* -----------------------------------------------------------------------------
2  * $Id: StgStorage.h,v 1.12 2003/03/26 17:40:58 sof Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * STG Storage Manager Interface
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #ifndef STGSTORAGE_H
11 #define STGSTORAGE_H
12
13 /* GENERATION GC NOTES
14  *
15  * We support an arbitrary number of generations, with an arbitrary number
16  * of steps per generation.  Notes (in no particular order):
17  *
18  *       - all generations except the oldest should have two steps.  This gives
19  *         objects a decent chance to age before being promoted, and in
20  *         particular will ensure that we don't end up with too many
21  *         thunks being updated in older generations.
22  *
23  *       - the oldest generation has one step.  There's no point in aging
24  *         objects in the oldest generation.
25  *
26  *       - generation 0, step 0 (G0S0) is the allocation area.  It is given
27  *         a fixed set of blocks during initialisation, and these blocks
28  *         are never freed.
29  *
30  *       - during garbage collection, each step which is an evacuation
31  *         destination (i.e. all steps except G0S0) is allocated a to-space.
32  *         evacuated objects are allocated into the step's to-space until
33  *         GC is finished, when the original step's contents may be freed
34  *         and replaced by the to-space.
35  *
36  *       - the mutable-list is per-generation (not per-step).  G0 doesn't 
37  *         have one (since every garbage collection collects at least G0).
38  * 
39  *       - block descriptors contain pointers to both the step and the
40  *         generation that the block belongs to, for convenience.
41  *
42  *       - static objects are stored in per-generation lists.  See GC.c for
43  *         details of how we collect CAFs in the generational scheme.
44  *
45  *       - large objects are per-step, and are promoted in the same way
46  *         as small objects, except that we may allocate large objects into
47  *         generation 1 initially.
48  */
49
50 typedef struct _step {
51   unsigned int         no;              /* step number */
52   bdescr *             blocks;          /* blocks in this step */
53   unsigned int         n_blocks;        /* number of blocks */
54   struct _step *       to;              /* destination step for live objects */
55   struct _generation * gen;             /* generation this step belongs to */
56   unsigned int         gen_no;          /* generation number (cached) */
57   bdescr *             large_objects;   /* large objects (doubly linked) */
58   unsigned int         n_large_blocks;  /* no. of blocks used by large objs */
59   int                  is_compacted;    /* compact this step? (old gen only) */
60
61   /* temporary use during GC: */
62   StgPtr       hp;                      /* next free locn in to-space */
63   StgPtr       hpLim;                   /* end of current to-space block */
64   bdescr *     hp_bd;                   /* bdescr of current to-space block */
65   bdescr *     to_blocks;               /* bdescr of first to-space block */
66   unsigned int n_to_blocks;             /* number of blocks in to-space */
67   bdescr *     scan_bd;                 /* block currently being scanned */
68   StgPtr       scan;                    /* scan pointer in current block */
69   bdescr *     new_large_objects;       /* large objects collected so far */
70   bdescr *     scavenged_large_objects; /* live large objs after GC (d-link) */
71   unsigned int n_scavenged_large_blocks;/* size of above */
72   bdescr *     bitmap;                  /* bitmap for compacting collection */
73 } step;
74
75 typedef struct _generation {
76   unsigned int   no;                    /* generation number */
77   step *         steps;                 /* steps */
78   unsigned int   n_steps;               /* number of steps */
79   unsigned int   max_blocks;            /* max blocks in step 0 */
80   StgMutClosure *mut_list;              /* mut objects in this gen (not G0)*/
81   StgMutClosure *mut_once_list;         /* objects that point to younger gens */
82
83   /* temporary use during GC: */
84   StgMutClosure * saved_mut_list;
85
86   /* stats information */
87   unsigned int collections;
88   unsigned int failed_promotions;
89 } generation;
90
91 /* -----------------------------------------------------------------------------
92    Allocation area for compiled code
93
94    OpenNursery(hp,hplim)        Opens the allocation area, and sets hp
95                                 and hplim appropriately.
96
97    CloseNursery(hp)             Closes the allocation area.
98
99    -------------------------------------------------------------------------- */
100
101 #define OpenNursery(hp,hplim)                           \
102   (hp    = CurrentNursery->free-1,                      \
103    hplim = CurrentNursery->start + CurrentNursery->blocks*BLOCK_SIZE_W - 1)
104   
105 #define CloseNursery(hp)  (CurrentNursery->free = (P_)(hp)+1)
106
107 /* -----------------------------------------------------------------------------
108    Prototype for an evacuate-like function
109    -------------------------------------------------------------------------- */
110
111 typedef void (*evac_fn)(StgClosure **);
112
113 /* -----------------------------------------------------------------------------
114    Trigger a GC from Haskell land.
115    -------------------------------------------------------------------------- */
116
117 extern void performGC(void);
118 extern void performMajorGC(void);
119 extern void performGCWithRoots(void (*get_roots)(evac_fn));
120
121 #endif /* STGSTORAGE_H */