[project @ 1999-02-02 14:21:28 by simonm]
[ghc-hetmet.git] / ghc / rts / StoragePriv.h
1 /* -----------------------------------------------------------------------------
2  * $Id: StoragePriv.h,v 1.7 1999/02/02 14:21:34 simonm Exp $
3  *
4  * Internal Storage Manger Interface
5  *
6  * ---------------------------------------------------------------------------*/
7
8 #ifndef STORAGEPRIV_H
9 #define STORAGEPRIV_H
10
11 /* GENERATION GC NOTES
12  *
13  * We support an arbitrary number of generations, with an arbitrary number
14  * of steps per generation.  Notes (in no particular order):
15  *
16  *       - all generations except the oldest should have two steps.  This gives
17  *         objects a decent chance to age before being promoted, and in
18  *         particular will ensure that we don't end up with too many
19  *         thunks being updated in older generations.
20  *
21  *       - the oldest generation has one step.  There's no point in aging
22  *         objects in the oldest generation.
23  *
24  *       - generation 0, step 0 (G0S0) is the allocation area.  It is given
25  *         a fixed set of blocks during initialisation, and these blocks
26  *         are never freed.
27  *
28  *       - during garbage collection, each step which is an evacuation
29  *         destination (i.e. all steps except G0S0) is allocated a to-space.
30  *         evacuated objects are allocated into the step's to-space until
31  *         GC is finished, when the original step's contents may be freed
32  *         and replaced by the to-space.
33  *
34  *       - the mutable-list is per-generation (not per-step).  G0 doesn't 
35  *         have one (since every garbage collection collects at least G0).
36  * 
37  *       - block descriptors contain pointers to both the step and the
38  *         generation that the block belongs to, for convenience.
39  *
40  *       - static objects are stored in per-generation lists.  See GC.c for
41  *         details of how we collect CAFs in the generational scheme.
42  *
43  *       - large objects are per-step, and are promoted in the same way
44  *         as small objects, except that we may allocate large objects into
45  *         generation 1 initially.
46  */
47
48 typedef struct _step {
49   nat no;                       /* step number */
50   bdescr *blocks;               /* blocks in this step */
51   nat n_blocks;                 /* number of blocks */
52   struct _step *to;             /* where collected objects from this step go */
53   struct _generation *gen;      /* generation this step belongs to */
54   bdescr *large_objects;        /* large objects (doubly linked) */
55
56   /* temporary use during GC: */
57   StgPtr  hp;                   /* next free locn in to-space */
58   StgPtr  hpLim;                /* end of current to-space block */
59   bdescr *hp_bd;                /* bdescr of current to-space block */
60   bdescr *to_space;             /* bdescr of first to-space block */
61   nat     to_blocks;            /* number of blocks in to-space */
62   bdescr *scan_bd;              /* block currently being scanned */
63   StgPtr  scan;                 /* scan pointer in current block */
64   bdescr *new_large_objects;    /* large objects collected so far */
65   bdescr *scavenged_large_objects; /* live large objects after GC (dbl link) */
66 } step;
67
68 typedef struct _generation {
69   nat no;                       /* generation number */
70   step *steps;                  /* steps */
71   nat n_steps;                  /* number of steps */
72   nat max_blocks;               /* max blocks in step 0 */
73   StgMutClosure *mut_list;      /* mutable objects in this generation (not G0)*/
74   StgMutClosure *mut_once_list; /* objects that point to younger generations */
75
76   /* temporary use during GC: */
77   StgMutClosure *saved_mut_list;
78
79   /* stats information */
80   nat collections;
81   nat failed_promotions;
82 } generation;
83
84 #define END_OF_STATIC_LIST stgCast(StgClosure*,1)
85
86 extern generation *generations;
87
88 extern generation *g0;
89 extern step *g0s0;
90 extern generation *oldest_gen;
91
92 extern void newCAF(StgClosure*);
93 extern StgTSO *relocate_TSO(StgTSO *src, StgTSO *dest);
94
95 extern StgWeak    *weak_ptr_list;
96 extern StgClosure *caf_list;
97
98 extern bdescr *small_alloc_list;
99 extern bdescr *large_alloc_list;
100
101 extern StgPtr alloc_Hp;
102 extern StgPtr alloc_HpLim;
103
104 extern bdescr *nursery;
105
106 extern nat nursery_blocks;
107 extern nat alloc_blocks;
108 extern nat alloc_blocks_lim;
109
110 extern bdescr *allocNursery ( bdescr *last_bd, nat blocks );
111 extern void resizeNursery ( nat blocks );
112
113 extern lnat calcLive( void );
114 extern lnat calcNeeded( void );
115
116 static inline void
117 dbl_link_onto(bdescr *bd, bdescr **list)
118 {
119   bd->link = *list;
120   bd->back = NULL;
121   if (*list) {
122     (*list)->back = bd; /* double-link the list */
123   }
124   *list = bd;
125 }
126
127 /* MUTABLE LISTS
128  * A mutable list is ended with END_MUT_LIST, so that we can use NULL
129  * as an indication that an object is not on a mutable list.
130  */
131 #define END_MUT_LIST ((StgMutClosure *)(void *)&END_MUT_LIST_closure)
132
133 #ifdef DEBUG
134 extern void memInventory(void);
135 extern void checkSanity(nat N);
136 #endif
137
138 #endif /* STORAGEPRIV_H */