[project @ 2004-02-12 02:04:59 by mthomas]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.35 2003/11/14 14:28:07 stolz Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Closures
7  *
8  * -------------------------------------------------------------------------- */
9
10 #ifndef CLOSURES_H
11 #define CLOSURES_H
12
13 /*
14  * The Layout of a closure header depends on which kind of system we're
15  * compiling for: profiling, parallel, ticky, etc.
16  */
17
18 /* -----------------------------------------------------------------------------
19    The profiling header
20    -------------------------------------------------------------------------- */
21
22 typedef struct {
23   CostCentreStack *ccs;
24   union {
25     struct _RetainerSet *rs;  // Retainer Set
26     StgWord ldvw;             // Lag/Drag/Void Word
27   } hp;
28 } StgProfHeader;
29
30 /* -----------------------------------------------------------------------------
31    The GranSim header
32    -------------------------------------------------------------------------- */
33
34 typedef struct {
35   StgWord procs; /* bitmask indicating on which PEs this closure resides */
36 } StgGranHeader;
37
38 /* -----------------------------------------------------------------------------
39    The full fixed-size closure header
40
41    The size of the fixed header is the sum of the optional parts plus a single
42    word for the entry code pointer.
43    -------------------------------------------------------------------------- */
44
45 typedef struct {
46         const struct _StgInfoTable* info;
47 #ifdef PROFILING
48         StgProfHeader         prof;
49 #endif
50 #ifdef GRAN
51         StgGranHeader         gran;
52 #endif
53 } StgHeader;
54
55 #define FIXED_HS (sizeof(StgHeader))
56
57 /* -----------------------------------------------------------------------------
58    Closure Types
59
60    For any given closure type (defined in InfoTables.h), there is a
61    corresponding structure defined below.  The name of the structure
62    is obtained by concatenating the closure type with '_closure'
63    -------------------------------------------------------------------------- */
64
65 /* All closures follow the generic format */
66
67 struct StgClosure_ {
68     StgHeader   header;
69     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
70 };
71
72 /* What a stroke of luck - all our mutable closures follow the same
73  * basic layout, with the mutable link field as the second field after
74  * the header.  This means the following structure is the supertype of
75  * mutable closures.
76  */
77
78 typedef struct StgMutClosure_ {
79     StgHeader   header;
80     StgWord     padding;
81     struct StgMutClosure_ *mut_link;
82     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
83 } StgMutClosure;
84
85 typedef struct {
86     StgHeader   header;
87     StgClosure *selectee;
88 } StgSelector;
89
90 typedef struct {
91     StgHeader   header;
92     StgHalfWord arity;          /* zero if it is an AP */
93     StgHalfWord n_args;
94     StgClosure *fun;            /* really points to a fun */
95     StgClosure *payload[FLEXIBLE_ARRAY];
96 } StgPAP;
97
98 // AP closures have the same layout, for convenience
99 typedef StgPAP StgAP;
100
101 typedef struct {
102     StgHeader   header;
103     StgWord     size;                    // number of words in payload
104     StgClosure *fun;
105     StgClosure *payload[FLEXIBLE_ARRAY]; // contains a chunk of *stack*
106 } StgAP_STACK;
107
108 typedef struct {
109     StgHeader   header;
110     StgClosure *indirectee;
111 } StgInd;
112
113 typedef struct {
114     StgHeader   header;
115     StgClosure *indirectee;
116     StgMutClosure *mut_link;
117 } StgIndOldGen;
118
119 typedef struct {
120     StgHeader     header;
121     StgClosure   *indirectee;
122     StgClosure   *static_link;
123     struct _StgInfoTable *saved_info;
124 } StgIndStatic;
125
126 typedef struct {
127     StgHeader  header;
128     StgWord    words;
129     StgWord    payload[FLEXIBLE_ARRAY];
130 } StgArrWords;
131
132 typedef struct {
133     StgHeader   header;
134     StgWord     ptrs;
135     StgMutClosure *mut_link;    /* mutable list */
136     StgClosure *payload[FLEXIBLE_ARRAY];
137 } StgMutArrPtrs;
138
139 typedef struct {
140     StgHeader   header;
141     StgClosure *var;
142     StgMutClosure *mut_link;
143 } StgMutVar;
144
145 typedef struct _StgUpdateFrame {
146     StgHeader  header;
147     StgClosure *updatee;
148 } StgUpdateFrame;
149
150 typedef struct {
151     StgHeader  header;
152     StgInt      exceptions_blocked;
153     StgClosure *handler;
154 } StgCatchFrame;
155
156 typedef struct {
157     StgHeader  header;
158 } StgStopFrame;  
159
160 typedef struct {
161     StgHeader   header;
162     StgClosure *evacuee;
163 } StgEvacuated;
164
165 typedef struct {
166   StgHeader header;
167   StgWord data;
168 } StgIntCharlikeClosure;
169
170 /* statically allocated */
171 typedef struct {
172   StgHeader  header;
173 } StgRetry;
174
175 typedef struct _StgForeignObj {
176   StgHeader      header;
177   StgAddr        data;          /* pointer to data in non-haskell-land */
178 } StgForeignObj;
179   
180 typedef struct _StgStableName {
181   StgHeader      header;
182   StgWord        sn;
183 } StgStableName;
184
185 typedef struct _StgWeak {       /* Weak v */
186   StgHeader header;
187   StgClosure *key;
188   StgClosure *value;            /* v */
189   StgClosure *finalizer;
190   struct _StgWeak *link;
191 } StgWeak;
192
193 typedef struct _StgDeadWeak {   /* Weak v */
194   StgHeader header;
195   struct _StgWeak *link;
196 } StgDeadWeak;
197
198 /* Byte code objects.  These are fixed size objects with pointers to
199  * four arrays, designed so that a BCO can be easily "re-linked" to
200  * other BCOs, to facilitate GHC's intelligent recompilation.  The
201  * array of instructions is static and not re-generated when the BCO
202  * is re-linked, but the other 3 arrays will be regenerated.
203  *
204  * A BCO represents either a function or a stack frame.  In each case,
205  * it needs a bitmap to describe to the garbage collector the
206  * pointerhood of its arguments/free variables respectively, and in
207  * the case of a function it also needs an arity.  These are stored
208  * directly in the BCO, rather than in the instrs array, for two
209  * reasons:
210  * (a) speed: we need to get at the bitmap info quickly when
211  *     the GC is examining APs and PAPs that point to this BCO
212  * (b) a subtle interaction with the compacting GC.  In compacting
213  *     GC, the info that describes the size/layout of a closure
214  *     cannot be in an object more than one level of indirection
215  *     away from the current object, because of the order in
216  *     which pointers are updated to point to their new locations.
217  */
218
219 typedef struct {
220     StgHeader      header;
221     StgArrWords   *instrs;      // a pointer to an ArrWords
222     StgArrWords   *literals;    // a pointer to an ArrWords
223     StgMutArrPtrs *ptrs;        // a pointer to a  MutArrPtrs
224     StgArrWords   *itbls;       // a pointer to an ArrWords
225     StgHalfWord   arity;        // arity of this BCO
226     StgHalfWord   size;         // size of this BCO (in words)
227     StgWord       bitmap[FLEXIBLE_ARRAY];  // an StgLargeBitmap
228 } StgBCO;
229
230 #define BCO_BITMAP(bco)      ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
231 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
232 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
233 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
234                                 / BITS_IN(StgWord))
235
236 /* Dynamic stack frames - these have a liveness mask in the object
237  * itself, rather than in the info table.  Useful for generic heap
238  * check code.  See StgMacros.h, HEAP_CHK_GEN().
239  */
240  
241 typedef struct {
242     const struct _StgInfoTable* info;
243     StgWord        liveness;
244     StgWord        ret_addr;
245     StgClosure *   payload[FLEXIBLE_ARRAY];
246 } StgRetDyn;
247
248 /* A function return stack frame: used when saving the state for a
249  * garbage collection at a function entry point.  The function
250  * arguments are on the stack, and we also save the function (its
251  * info table describes the pointerhood of the arguments).
252  *
253  * The stack frame size is also cached in the frame for convenience.
254  */
255 typedef struct {
256     const struct _StgInfoTable* info;
257     StgWord        size;
258     StgClosure *   fun;
259     StgClosure *   payload[FLEXIBLE_ARRAY];
260 } StgRetFun;
261
262 /* Concurrent communication objects */
263
264 typedef struct {
265   StgHeader       header;
266   struct StgTSO_ *head;
267   StgMutClosure  *mut_link;
268   struct StgTSO_ *tail;
269   StgClosure*     value;
270 } StgMVar;
271
272 #if defined(PAR) || defined(GRAN)
273 /*
274   StgBlockingQueueElement is a ``collective type'' representing the types
275   of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
276   StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
277   queue).  Logically, this is a union type, but defining another struct
278   with a common layout is easier to handle in the code (same as for
279   StgMutClosures).  
280   Note that in the standard setup only StgTSOs can be on a blocking queue.
281   This is one of the main reasons for slightly different code in files
282   such as Schedule.c.
283 */
284 typedef struct StgBlockingQueueElement_ {
285   StgHeader                         header;
286   struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
287   StgMutClosure                    *mut_link;  /* next elem in mutable list */
288   struct StgClosure_               *payload[FLEXIBLE_ARRAY];/* contents of the closure */
289 } StgBlockingQueueElement;
290
291 /* only difference to std code is type of the elem in the BQ */
292 typedef struct StgBlockingQueue_ {
293   StgHeader                 header;
294   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
295   StgMutClosure            *mut_link;              /* next elem in mutable list */
296 } StgBlockingQueue;
297
298 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
299 typedef struct StgRBHSave_ {
300   StgHeader    header;
301   StgClosure  *payload[FLEXIBLE_ARRAY];     /* 2 words ripped out of the guts of the */
302 } StgRBHSave;                  /*  closure holding the blocking queue */
303  
304 typedef struct StgRBH_ {
305   StgHeader                         header;
306   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
307   StgMutClosure                    *mut_link;       /* next elem in mutable list */
308 } StgRBH;
309
310 #else
311
312 typedef struct StgBlockingQueue_ {
313   StgHeader          header;
314   struct StgTSO_    *blocking_queue;
315   StgMutClosure     *mut_link;
316 } StgBlockingQueue;
317
318 #endif
319
320 #if defined(PAR)
321 /* global indirections aka FETCH_ME closures */
322 typedef struct StgFetchMe_ {
323   StgHeader              header;
324   globalAddr            *ga;        /* ptr to unique id for a closure */
325   StgMutClosure         *mut_link;  /* next elem in mutable list */
326 } StgFetchMe;
327
328 /* same contents as an ordinary StgBlockingQueue */
329 typedef struct StgFetchMeBlockingQueue_ {
330   StgHeader                          header;
331   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
332   StgMutClosure                     *mut_link;       /* next elem in mutable list */
333 } StgFetchMeBlockingQueue;
334
335 /* This is an entry in a blocking queue. It indicates a fetch request from a 
336    TSO on another PE demanding the value of this closur. Note that a
337    StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
338    updated with the result, the result will be sent back (the PE is encoded
339    in the globalAddr) and the StgBlockedFetch closure will be nuked.
340 */
341 typedef struct StgBlockedFetch_ {
342   StgHeader                         header;
343   struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
344   StgMutClosure                    *mut_link; /* next elem in mutable list */
345   StgClosure                       *node;     /* node to fetch */
346   globalAddr                        ga;       /* where to send the result to */
347 } StgBlockedFetch;                            /* NB: not just a ptr to a GA */
348 #endif
349
350 #endif /* CLOSURES_H */