[project @ 1999-01-18 15:18:06 by simonm]
[ghc-hetmet.git] / ghc / rts / StoragePriv.h
1 /* -----------------------------------------------------------------------------
2  * $Id: StoragePriv.h,v 1.3 1999/01/13 17:25:48 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
67 #ifdef DEBUG
68   /* for sanity checking: */
69   bdescr *old_scan_bd;
70   StgPtr  old_scan;
71 #endif
72 } step;
73
74 typedef struct _generation {
75   nat no;                       /* generation number */
76   step *steps;                  /* steps */
77   nat n_steps;                  /* number of steps */
78   nat max_blocks;               /* max blocks in step 0 */
79   StgMutClosure *mut_list;      /* mutable objects in this generation (not G0)*/
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 static inline void
113 dbl_link_onto(bdescr *bd, bdescr **list)
114 {
115   bd->link = *list;
116   bd->back = NULL;
117   if (*list) {
118     (*list)->back = bd; /* double-link the list */
119   }
120   *list = bd;
121 }
122
123 /* MUTABLE LISTS
124  * A mutable list is ended with END_MUT_LIST, so that we can use NULL
125  * as an indication that an object is not on a mutable list.
126  */
127 #define END_MUT_LIST ((StgMutClosure *)(void *)&END_MUT_LIST_closure)
128
129 #ifdef DEBUG
130 extern void memInventory(void);
131 #endif
132
133 #endif /* STORAGEPRIV_H */