[project @ 1999-01-18 15:21:37 by simonm]
[ghc-hetmet.git] / ghc / rts / StoragePriv.h
1 /* -----------------------------------------------------------------------------
2  * $Id: StoragePriv.h,v 1.4 1999/01/18 15:21:40 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
75   /* temporary use during GC: */
76   StgMutClosure *saved_mut_list;
77
78   /* stats information */
79   nat collections;
80   nat failed_promotions;
81 } generation;
82
83 #define END_OF_STATIC_LIST stgCast(StgClosure*,1)
84
85 extern generation *generations;
86
87 extern generation *g0;
88 extern step *g0s0;
89 extern generation *oldest_gen;
90
91 extern void newCAF(StgClosure*);
92 extern StgTSO *relocate_TSO(StgTSO *src, StgTSO *dest);
93
94 extern StgWeak    *weak_ptr_list;
95 extern StgClosure *caf_list;
96
97 extern bdescr *small_alloc_list;
98 extern bdescr *large_alloc_list;
99
100 extern StgPtr alloc_Hp;
101 extern StgPtr alloc_HpLim;
102
103 extern bdescr *nursery;
104
105 extern nat nursery_blocks;
106 extern nat alloc_blocks;
107 extern nat alloc_blocks_lim;
108
109 static inline void
110 dbl_link_onto(bdescr *bd, bdescr **list)
111 {
112   bd->link = *list;
113   bd->back = NULL;
114   if (*list) {
115     (*list)->back = bd; /* double-link the list */
116   }
117   *list = bd;
118 }
119
120 /* MUTABLE LISTS
121  * A mutable list is ended with END_MUT_LIST, so that we can use NULL
122  * as an indication that an object is not on a mutable list.
123  */
124 #define END_MUT_LIST ((StgMutClosure *)(void *)&END_MUT_LIST_closure)
125
126 #ifdef DEBUG
127 extern void memInventory(void);
128 #endif
129
130 #endif /* STORAGEPRIV_H */