[project @ 2003-02-21 05:34:12 by sof]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.32 2002/12/11 15:36:37 simonmar 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 pieces of
208  * information are stored at the beginning of the instruction array.
209  */
210
211 typedef struct {
212     StgHeader      header;
213     StgArrWords   *instrs;      /* a pointer to an ArrWords */
214     StgArrWords   *literals;    /* a pointer to an ArrWords */
215     StgMutArrPtrs *ptrs;        /* a pointer to a MutArrPtrs */
216     StgArrWords   *itbls;       /* a pointer to an ArrWords */
217 } StgBCO;
218
219 typedef struct {
220     StgWord arity;
221     StgWord bitmap[FLEXIBLE_ARRAY];  // really an StgLargeBitmap
222 } StgBCOInfo;
223
224 #define BCO_INFO(bco)  ((StgBCOInfo *)(((StgBCO *)(bco))->instrs->payload))
225 #define BCO_ARITY(bco) (BCO_INFO(bco)->arity)
226 #define BCO_BITMAP(bco) ((StgLargeBitmap *)BCO_INFO(bco)->bitmap)
227 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
228 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
229 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
230                                 / BITS_IN(StgWord))
231 #define BCO_INSTRS(bco) ((StgWord16 *)(BCO_BITMAP_BITS(bco) + \
232                                        BCO_BITMAP_SIZEW(bco)))
233
234 /* Dynamic stack frames - these have a liveness mask in the object
235  * itself, rather than in the info table.  Useful for generic heap
236  * check code.  See StgMacros.h, HEAP_CHK_GEN().
237  */
238  
239 typedef struct {
240     const struct _StgInfoTable* info;
241     StgWord        liveness;
242     StgWord        ret_addr;
243     StgClosure *   payload[FLEXIBLE_ARRAY];
244 } StgRetDyn;
245
246 /* A function return stack frame: used when saving the state for a
247  * garbage collection at a function entry point.  The function
248  * arguments are on the stack, and we also save the function (its
249  * info table describes the pointerhood of the arguments).
250  *
251  * The stack frame size is also cached in the frame for convenience.
252  */
253 typedef struct {
254     const struct _StgInfoTable* info;
255     StgWord        size;
256     StgClosure *   fun;
257     StgClosure *   payload[FLEXIBLE_ARRAY];
258 } StgRetFun;
259
260 /* Concurrent communication objects */
261
262 typedef struct {
263   StgHeader       header;
264   struct StgTSO_ *head;
265   StgMutClosure  *mut_link;
266   struct StgTSO_ *tail;
267   StgClosure*     value;
268 } StgMVar;
269
270 #if defined(PAR) || defined(GRAN)
271 /*
272   StgBlockingQueueElement is a ``collective type'' representing the types
273   of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
274   StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
275   queue).  Logically, this is a union type, but defining another struct
276   with a common layout is easier to handle in the code (same as for
277   StgMutClosures).  
278   Note that in the standard setup only StgTSOs can be on a blocking queue.
279   This is one of the main reasons for slightly different code in files
280   such as Schedule.c.
281 */
282 typedef struct StgBlockingQueueElement_ {
283   StgHeader                         header;
284   struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
285   StgMutClosure                    *mut_link;  /* next elem in mutable list */
286   struct StgClosure_               *payload[FLEXIBLE_ARRAY];/* contents of the closure */
287 } StgBlockingQueueElement;
288
289 /* only difference to std code is type of the elem in the BQ */
290 typedef struct StgBlockingQueue_ {
291   StgHeader                 header;
292   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
293   StgMutClosure            *mut_link;              /* next elem in mutable list */
294 } StgBlockingQueue;
295
296 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
297 typedef struct StgRBHSave_ {
298   StgHeader    header;
299   StgClosure  *payload[FLEXIBLE_ARRAY];     /* 2 words ripped out of the guts of the */
300 } StgRBHSave;                  /*  closure holding the blocking queue */
301  
302 typedef struct StgRBH_ {
303   StgHeader                         header;
304   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
305   StgMutClosure                    *mut_link;       /* next elem in mutable list */
306 } StgRBH;
307
308 #else
309
310 typedef struct StgBlockingQueue_ {
311   StgHeader          header;
312   struct StgTSO_    *blocking_queue;
313   StgMutClosure     *mut_link;
314 } StgBlockingQueue;
315
316 #endif
317
318 #if defined(PAR)
319 /* global indirections aka FETCH_ME closures */
320 typedef struct StgFetchMe_ {
321   StgHeader              header;
322   globalAddr            *ga;        /* ptr to unique id for a closure */
323   StgMutClosure         *mut_link;  /* next elem in mutable list */
324 } StgFetchMe;
325
326 /* same contents as an ordinary StgBlockingQueue */
327 typedef struct StgFetchMeBlockingQueue_ {
328   StgHeader                          header;
329   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
330   StgMutClosure                     *mut_link;       /* next elem in mutable list */
331 } StgFetchMeBlockingQueue;
332
333 /* This is an entry in a blocking queue. It indicates a fetch request from a 
334    TSO on another PE demanding the value of this closur. Note that a
335    StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
336    updated with the result, the result will be sent back (the PE is encoded
337    in the globalAddr) and the StgBlockedFetch closure will be nuked.
338 */
339 typedef struct StgBlockedFetch_ {
340   StgHeader                         header;
341   struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
342   StgMutClosure                    *mut_link; /* next elem in mutable list */
343   StgClosure                       *node;     /* node to fetch */
344   globalAddr                        ga;       /* where to send the result to */
345 } StgBlockedFetch;                            /* NB: not just a ptr to a GA */
346 #endif
347
348 #endif /* CLOSURES_H */