[project @ 2005-06-06 08:49:07 by tharris]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2004
4  *
5  * Closures
6  *
7  * -------------------------------------------------------------------------- */
8
9 #ifndef CLOSURES_H
10 #define CLOSURES_H
11
12 /*
13  * The Layout of a closure header depends on which kind of system we're
14  * compiling for: profiling, parallel, ticky, etc.
15  */
16
17 /* -----------------------------------------------------------------------------
18    The profiling header
19    -------------------------------------------------------------------------- */
20
21 typedef struct {
22   CostCentreStack *ccs;
23   union {
24     struct _RetainerSet *rs;  /* Retainer Set */
25     StgWord ldvw;             /* Lag/Drag/Void Word */
26   } hp;
27 } StgProfHeader;
28
29 /* -----------------------------------------------------------------------------
30    The GranSim header
31    -------------------------------------------------------------------------- */
32
33 typedef struct {
34   StgWord procs; /* bitmask indicating on which PEs this closure resides */
35 } StgGranHeader;
36
37 /* -----------------------------------------------------------------------------
38    The SMP header
39
40    In SMP mode, we have an extra word of padding in a thunk's header.
41    (Note: thunks only; other closures do not have this padding word).
42    -------------------------------------------------------------------------- */
43
44 typedef struct {
45     StgWord pad;
46 } StgSMPThunkHeader;
47
48 /* -----------------------------------------------------------------------------
49    The full fixed-size closure header
50
51    The size of the fixed header is the sum of the optional parts plus a single
52    word for the entry code pointer.
53    -------------------------------------------------------------------------- */
54
55 typedef struct {
56     const struct _StgInfoTable* info;
57 #ifdef PROFILING
58     StgProfHeader         prof;
59 #endif
60 #ifdef GRAN
61     StgGranHeader         gran;
62 #endif
63 } StgHeader;
64
65 /*
66  * In SMP mode, a thunk has a padding word to take the updated value.
67  * This is so that the update doesn't overwrite the payload, so we can
68  * avoid needing to lock the thunk during entry and update.
69  *
70  * Note: this doesn't apply to THUNK_STATICs, which have no payload.
71  */
72 typedef struct {
73     const struct _StgInfoTable* info;
74 #ifdef PROFILING
75     StgProfHeader         prof;
76 #endif
77 #ifdef GRAN
78     StgGranHeader         gran;
79 #endif
80 #ifdef SMP
81     StgSMPThunkHeader     smp;
82 #endif
83 } StgThunkHeader;
84
85 /* -----------------------------------------------------------------------------
86    Closure Types
87
88    For any given closure type (defined in InfoTables.h), there is a
89    corresponding structure defined below.  The name of the structure
90    is obtained by concatenating the closure type with '_closure'
91    -------------------------------------------------------------------------- */
92
93 /* All closures follow the generic format */
94
95 struct StgClosure_ {
96     StgHeader   header;
97     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
98 };
99
100 typedef struct {
101     StgThunkHeader  header;
102     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
103 } StgThunk;
104
105 typedef struct {
106     StgThunkHeader   header;
107     StgClosure *selectee;
108 } StgSelector;
109
110 typedef struct {
111     StgHeader   header;
112     StgHalfWord arity;          /* zero if it is an AP */
113     StgHalfWord n_args;
114     StgClosure *fun;            /* really points to a fun */
115     StgClosure *payload[FLEXIBLE_ARRAY];
116 } StgPAP;
117
118 typedef struct {
119     StgThunkHeader   header;
120     StgHalfWord arity;          /* zero if it is an AP */
121     StgHalfWord n_args;
122     StgClosure *fun;            /* really points to a fun */
123     StgClosure *payload[FLEXIBLE_ARRAY];
124 } StgAP;
125
126 typedef struct {
127     StgThunkHeader   header;
128     StgWord     size;                    /* number of words in payload */
129     StgClosure *fun;
130     StgClosure *payload[FLEXIBLE_ARRAY]; /* contains a chunk of *stack* */
131 } StgAP_STACK;
132
133 typedef struct {
134     StgHeader   header;
135     StgClosure *indirectee;
136 } StgInd;
137
138 typedef struct {
139     StgHeader     header;
140     StgClosure   *indirectee;
141     StgClosure   *static_link;
142     struct _StgInfoTable *saved_info;
143 } StgIndStatic;
144
145 typedef struct {
146     StgHeader  header;
147     StgWord    words;
148     StgWord    payload[FLEXIBLE_ARRAY];
149 } StgArrWords;
150
151 typedef struct {
152     StgHeader   header;
153     StgWord     ptrs;
154     StgClosure *payload[FLEXIBLE_ARRAY];
155 } StgMutArrPtrs;
156
157 typedef struct {
158     StgHeader   header;
159     StgClosure *var;
160 } StgMutVar;
161
162 typedef struct _StgUpdateFrame {
163     StgHeader  header;
164     StgClosure *updatee;
165 } StgUpdateFrame;
166
167 typedef struct {
168     StgHeader  header;
169     StgInt      exceptions_blocked;
170     StgClosure *handler;
171 } StgCatchFrame;
172
173 typedef struct {
174     StgHeader  header;
175 } StgStopFrame;  
176
177 typedef struct {
178     StgHeader   header;
179     StgClosure *evacuee;
180 } StgEvacuated;
181
182 typedef struct {
183   StgHeader header;
184   StgWord data;
185 } StgIntCharlikeClosure;
186
187 /* statically allocated */
188 typedef struct {
189   StgHeader  header;
190 } StgRetry;
191
192 typedef struct _StgForeignObj {
193   StgHeader      header;
194   StgAddr        data;          /* pointer to data in non-haskell-land */
195 } StgForeignObj;
196   
197 typedef struct _StgStableName {
198   StgHeader      header;
199   StgWord        sn;
200 } StgStableName;
201
202 typedef struct _StgWeak {       /* Weak v */
203   StgHeader header;
204   StgClosure *key;
205   StgClosure *value;            /* v */
206   StgClosure *finalizer;
207   struct _StgWeak *link;
208 } StgWeak;
209
210 typedef struct _StgDeadWeak {   /* Weak v */
211   StgHeader header;
212   struct _StgWeak *link;
213 } StgDeadWeak;
214
215 /* Byte code objects.  These are fixed size objects with pointers to
216  * four arrays, designed so that a BCO can be easily "re-linked" to
217  * other BCOs, to facilitate GHC's intelligent recompilation.  The
218  * array of instructions is static and not re-generated when the BCO
219  * is re-linked, but the other 3 arrays will be regenerated.
220  *
221  * A BCO represents either a function or a stack frame.  In each case,
222  * it needs a bitmap to describe to the garbage collector the
223  * pointerhood of its arguments/free variables respectively, and in
224  * the case of a function it also needs an arity.  These are stored
225  * directly in the BCO, rather than in the instrs array, for two
226  * reasons:
227  * (a) speed: we need to get at the bitmap info quickly when
228  *     the GC is examining APs and PAPs that point to this BCO
229  * (b) a subtle interaction with the compacting GC.  In compacting
230  *     GC, the info that describes the size/layout of a closure
231  *     cannot be in an object more than one level of indirection
232  *     away from the current object, because of the order in
233  *     which pointers are updated to point to their new locations.
234  */
235
236 typedef struct {
237     StgHeader      header;
238     StgArrWords   *instrs;      /* a pointer to an ArrWords */
239     StgArrWords   *literals;    /* a pointer to an ArrWords */
240     StgMutArrPtrs *ptrs;        /* a pointer to a  MutArrPtrs */
241     StgArrWords   *itbls;       /* a pointer to an ArrWords */
242     StgHalfWord   arity;        /* arity of this BCO */
243     StgHalfWord   size;         /* size of this BCO (in words) */
244     StgWord       bitmap[FLEXIBLE_ARRAY];  /* an StgLargeBitmap */
245 } StgBCO;
246
247 #define BCO_BITMAP(bco)      ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
248 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
249 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
250 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
251                                 / BITS_IN(StgWord))
252
253 /* -----------------------------------------------------------------------------
254    Dynamic stack frames for generic heap checks.
255
256    These generic heap checks are slow, but have the advantage of being
257    usable in a variety of situations.
258
259    The one restriction is that any relevant SRTs must already be pointed
260    to from the stack.  The return address doesn't need to have an info
261    table attached: hence it can be any old code pointer.
262
263    The liveness mask contains a 1 at bit n, if register Rn contains a
264    non-pointer.  The contents of all 8 vanilla registers are always saved
265    on the stack; the liveness mask tells the GC which ones contain
266    pointers.
267
268    Good places to use a generic heap check: 
269
270         - case alternatives (the return address with an SRT is already
271           on the stack).
272
273         - primitives (no SRT required).
274
275    The stack frame layout for a RET_DYN is like this:
276
277           some pointers         |-- RET_DYN_PTRS(liveness) words
278           some nonpointers      |-- RET_DYN_NONPTRS(liveness) words
279                                
280           L1                    \
281           D1-2                  |-- RET_DYN_NONPTR_REGS_SIZE words
282           F1-4                  /
283                                
284           R1-8                  |-- RET_DYN_BITMAP_SIZE words
285                                
286           return address        \
287           liveness mask         |-- StgRetDyn structure
288           stg_gen_chk_info      /
289
290    we assume that the size of a double is always 2 pointers (wasting a
291    word when it is only one pointer, but avoiding lots of #ifdefs).
292
293    See Liveness.h for the macros (RET_DYN_PTRS() etc.).
294
295    NOTE: if you change the layout of RET_DYN stack frames, then you
296    might also need to adjust the value of RESERVED_STACK_WORDS in
297    Constants.h.
298    -------------------------------------------------------------------------- */
299
300 typedef struct {
301     const struct _StgInfoTable* info;
302     StgWord        liveness;
303     StgWord        ret_addr;
304     StgClosure *   payload[FLEXIBLE_ARRAY];
305 } StgRetDyn;
306
307 /* A function return stack frame: used when saving the state for a
308  * garbage collection at a function entry point.  The function
309  * arguments are on the stack, and we also save the function (its
310  * info table describes the pointerhood of the arguments).
311  *
312  * The stack frame size is also cached in the frame for convenience.
313  */
314 typedef struct {
315     const struct _StgInfoTable* info;
316     StgWord        size;
317     StgClosure *   fun;
318     StgClosure *   payload[FLEXIBLE_ARRAY];
319 } StgRetFun;
320
321 /* Concurrent communication objects */
322
323 typedef struct {
324   StgHeader       header;
325   struct StgTSO_ *head;
326   struct StgTSO_ *tail;
327   StgClosure*     value;
328 } StgMVar;
329
330
331 /* STM data structures
332  *
333  *  StgTVar defines the only type that can be updated through the STM
334  *  interface.
335  * 
336  *  Note that various optimisations may be possible in order to use less
337  *  space for these data structures at the cost of more complexity in the
338  *  implementation:
339  *
340  *   - In StgTVar, current_value and first_wait_queue_entry could be held in
341  *     the same field: if any thread is waiting then its expected_value for
342  *     the tvar is the current value.  
343  *
344  *   - In StgTRecHeader, it might be worthwhile having separate chunks
345  *     of read-only and read-write locations.  This would save a
346  *     new_value field in the read-only locations.
347  */
348
349 typedef struct StgTVarWaitQueue_ {
350   StgHeader                  header;
351   struct StgTSO_            *waiting_tso;
352   struct StgTVarWaitQueue_  *next_queue_entry;
353   struct StgTVarWaitQueue_  *prev_queue_entry;
354 } StgTVarWaitQueue;
355
356 typedef struct {
357   StgHeader                  header;
358   StgClosure                *volatile current_value;
359   StgTVarWaitQueue          *volatile first_wait_queue_entry;
360 #if defined(SMP)
361   struct StgTRecHeader_     *volatile last_update_by;
362 #endif
363 } StgTVar;
364
365 /* new_value == expected_value for read-only accesses */
366 /* new_value is a StgTVarWaitQueue entry when trec in state TREC_WAITING */
367 typedef struct {
368   StgTVar                   *tvar;
369   StgClosure                *expected_value;
370   StgClosure                *new_value; 
371 #if defined(SMP)
372   struct StgTRecHeader_     *saw_update_by;
373 #endif
374 } TRecEntry;
375
376 #define TREC_CHUNK_NUM_ENTRIES 256
377
378 typedef struct StgTRecChunk_ {
379   StgHeader                  header;
380   struct StgTRecChunk_      *prev_chunk;
381   StgWord                    next_entry_idx;
382   TRecEntry                  entries[TREC_CHUNK_NUM_ENTRIES];
383 } StgTRecChunk;
384
385 typedef enum { 
386   TREC_ACTIVE,        /* Transaction in progress, outcome undecided */
387   TREC_CONDEMNED,     /* Transaction in progress, inconsistent / out of date reads */
388   TREC_COMMITTED,     /* Transaction has committed, now updating tvars */
389   TREC_ABORTED,       /* Transaction has aborted, now reverting tvars */
390   TREC_WAITING,       /* Transaction currently waiting */
391 } TRecState;
392
393 typedef struct StgTRecHeader_ {
394   StgHeader                  header;
395   TRecState                  state;
396   struct StgTRecHeader_     *enclosing_trec;
397   StgTRecChunk              *current_chunk;
398 } StgTRecHeader;
399
400 typedef struct {
401     StgHeader   header;
402     StgBool     waiting;
403     StgClosure *code;
404 } StgAtomicallyFrame;
405
406 typedef struct {
407     StgHeader   header;
408     StgClosure *handler;
409 } StgCatchSTMFrame;
410
411 typedef struct {
412     StgHeader      header;
413     StgBool        running_alt_code;
414     StgClosure    *first_code;
415     StgClosure    *alt_code;
416     StgTRecHeader *first_code_trec;
417 } StgCatchRetryFrame;
418
419 #if defined(PAR) || defined(GRAN)
420 /*
421   StgBlockingQueueElement is a ``collective type'' representing the types
422   of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
423   StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
424   queue).  Logically, this is a union type, but defining another struct
425   with a common layout is easier to handle in the code.  
426   Note that in the standard setup only StgTSOs can be on a blocking queue.
427   This is one of the main reasons for slightly different code in files
428   such as Schedule.c.
429 */
430 typedef struct StgBlockingQueueElement_ {
431   StgHeader                         header;
432   struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
433   struct StgClosure_               *payload[FLEXIBLE_ARRAY];/* contents of the closure */
434 } StgBlockingQueueElement;
435
436 /* only difference to std code is type of the elem in the BQ */
437 typedef struct StgBlockingQueue_ {
438   StgHeader                 header;
439   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
440 } StgBlockingQueue;
441
442 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
443 typedef struct StgRBHSave_ {
444   StgHeader    header;
445   StgClosure  *payload[FLEXIBLE_ARRAY];     /* 2 words ripped out of the guts of the */
446 } StgRBHSave;                  /*  closure holding the blocking queue */
447  
448 typedef struct StgRBH_ {
449   StgHeader                         header;
450   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
451 } StgRBH;
452
453 #endif
454
455 #if defined(PAR)
456 /* global indirections aka FETCH_ME closures */
457 typedef struct StgFetchMe_ {
458   StgHeader              header;
459   globalAddr            *ga;        /* ptr to unique id for a closure */
460 } StgFetchMe;
461
462 /* same contents as an ordinary StgBlockingQueue */
463 typedef struct StgFetchMeBlockingQueue_ {
464   StgHeader                          header;
465   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
466 } StgFetchMeBlockingQueue;
467
468 /* This is an entry in a blocking queue. It indicates a fetch request from a 
469    TSO on another PE demanding the value of this closur. Note that a
470    StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
471    updated with the result, the result will be sent back (the PE is encoded
472    in the globalAddr) and the StgBlockedFetch closure will be nuked.
473 */
474 typedef struct StgBlockedFetch_ {
475   StgHeader                         header;
476   struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
477   StgClosure                       *node;     /* node to fetch */
478   globalAddr                        ga;       /* where to send the result to */
479 } StgBlockedFetch;                            /* NB: not just a ptr to a GA */
480 #endif
481
482 #endif /* CLOSURES_H */