[project @ 1999-02-05 16:02:18 by simonm]
[ghc-hetmet.git] / ghc / rts / StoragePriv.h
1 /* -----------------------------------------------------------------------------
2  * $Id: StoragePriv.h,v 1.8 1999/02/05 16:03:02 simonm Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Internal Storage Manger Interface
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #ifndef STORAGEPRIV_H
11 #define STORAGEPRIV_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   nat no;                       /* step number */
52   bdescr *blocks;               /* blocks in this step */
53   nat n_blocks;                 /* number of blocks */
54   struct _step *to;             /* where collected objects from this step go */
55   struct _generation *gen;      /* generation this step belongs to */
56   bdescr *large_objects;        /* large objects (doubly linked) */
57
58   /* temporary use during GC: */
59   StgPtr  hp;                   /* next free locn in to-space */
60   StgPtr  hpLim;                /* end of current to-space block */
61   bdescr *hp_bd;                /* bdescr of current to-space block */
62   bdescr *to_space;             /* bdescr of first to-space block */
63   nat     to_blocks;            /* number of blocks in to-space */
64   bdescr *scan_bd;              /* block currently being scanned */
65   StgPtr  scan;                 /* scan pointer in current block */
66   bdescr *new_large_objects;    /* large objects collected so far */
67   bdescr *scavenged_large_objects; /* live large objects after GC (dbl link) */
68 } step;
69
70 typedef struct _generation {
71   nat no;                       /* generation number */
72   step *steps;                  /* steps */
73   nat n_steps;                  /* number of steps */
74   nat max_blocks;               /* max blocks in step 0 */
75   StgMutClosure *mut_list;      /* mutable objects in this generation (not G0)*/
76   StgMutClosure *mut_once_list; /* objects that point to younger generations */
77
78   /* temporary use during GC: */
79   StgMutClosure *saved_mut_list;
80
81   /* stats information */
82   nat collections;
83   nat failed_promotions;
84 } generation;
85
86 #define END_OF_STATIC_LIST stgCast(StgClosure*,1)
87
88 extern generation *generations;
89
90 extern generation *g0;
91 extern step *g0s0;
92 extern generation *oldest_gen;
93
94 extern void newCAF(StgClosure*);
95 extern StgTSO *relocate_TSO(StgTSO *src, StgTSO *dest);
96
97 extern StgWeak    *weak_ptr_list;
98 extern StgClosure *caf_list;
99
100 extern bdescr *small_alloc_list;
101 extern bdescr *large_alloc_list;
102
103 extern StgPtr alloc_Hp;
104 extern StgPtr alloc_HpLim;
105
106 extern bdescr *nursery;
107
108 extern nat nursery_blocks;
109 extern nat alloc_blocks;
110 extern nat alloc_blocks_lim;
111
112 extern bdescr *allocNursery ( bdescr *last_bd, nat blocks );
113 extern void resizeNursery ( nat blocks );
114
115 extern lnat calcLive( void );
116 extern lnat calcNeeded( void );
117
118 static inline void
119 dbl_link_onto(bdescr *bd, bdescr **list)
120 {
121   bd->link = *list;
122   bd->back = NULL;
123   if (*list) {
124     (*list)->back = bd; /* double-link the list */
125   }
126   *list = bd;
127 }
128
129 /* MUTABLE LISTS
130  * A mutable list is ended with END_MUT_LIST, so that we can use NULL
131  * as an indication that an object is not on a mutable list.
132  */
133 #define END_MUT_LIST ((StgMutClosure *)(void *)&END_MUT_LIST_closure)
134
135 #ifdef DEBUG
136 extern void memInventory(void);
137 extern void checkSanity(nat N);
138 #endif
139
140 #endif /* STORAGEPRIV_H */