f3929ee36f740b613e5bf70453003e526402284d
[ghc-hetmet.git] / includes / rts / storage / Closures.h
1 /* ----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2004
4  *
5  * Closures
6  *
7  * -------------------------------------------------------------------------- */
8
9 #ifndef RTS_STORAGE_CLOSURES_H
10 #define RTS_STORAGE_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 SMP header
31    
32    A thunk has a padding word to take the updated value.  This is so
33    that the update doesn't overwrite the payload, so we can avoid
34    needing to lock the thunk during entry and update.
35    
36    Note: this doesn't apply to THUNK_STATICs, which have no payload.
37
38    Note: we leave this padding word in all ways, rather than just SMP,
39    so that we don't have to recompile all our libraries for SMP.
40    -------------------------------------------------------------------------- */
41
42 typedef struct {
43     StgWord pad;
44 } StgSMPThunkHeader;
45
46 /* -----------------------------------------------------------------------------
47    The full fixed-size closure header
48
49    The size of the fixed header is the sum of the optional parts plus a single
50    word for the entry code pointer.
51    -------------------------------------------------------------------------- */
52
53 typedef struct {
54     const StgInfoTable* info;
55 #ifdef PROFILING
56     StgProfHeader         prof;
57 #endif
58 } StgHeader;
59
60 typedef struct {
61     const StgInfoTable* info;
62 #ifdef PROFILING
63     StgProfHeader         prof;
64 #endif
65     StgSMPThunkHeader     smp;
66 } StgThunkHeader;
67
68 #define THUNK_EXTRA_HEADER_W (sizeofW(StgThunkHeader)-sizeofW(StgHeader))
69
70 /* -----------------------------------------------------------------------------
71    Closure Types
72
73    For any given closure type (defined in InfoTables.h), there is a
74    corresponding structure defined below.  The name of the structure
75    is obtained by concatenating the closure type with '_closure'
76    -------------------------------------------------------------------------- */
77
78 /* All closures follow the generic format */
79
80 typedef struct StgClosure_ {
81     StgHeader   header;
82     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
83 } *StgClosurePtr; // StgClosure defined in Rts.h
84
85 typedef struct {
86     StgThunkHeader  header;
87     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
88 } StgThunk;
89
90 typedef struct {
91     StgThunkHeader   header;
92     StgClosure *selectee;
93 } StgSelector;
94
95 typedef struct {
96     StgHeader   header;
97     StgHalfWord arity;          /* zero if it is an AP */
98     StgHalfWord n_args;
99     StgClosure *fun;            /* really points to a fun */
100     StgClosure *payload[FLEXIBLE_ARRAY];
101 } StgPAP;
102
103 typedef struct {
104     StgThunkHeader   header;
105     StgHalfWord arity;          /* zero if it is an AP */
106     StgHalfWord n_args;
107     StgClosure *fun;            /* really points to a fun */
108     StgClosure *payload[FLEXIBLE_ARRAY];
109 } StgAP;
110
111 typedef struct {
112     StgThunkHeader   header;
113     StgWord     size;                    /* number of words in payload */
114     StgClosure *fun;
115     StgClosure *payload[FLEXIBLE_ARRAY]; /* contains a chunk of *stack* */
116 } StgAP_STACK;
117
118 typedef struct {
119     StgHeader   header;
120     StgClosure *indirectee;
121 } StgInd;
122
123 typedef struct {
124     StgHeader     header;
125     StgClosure   *indirectee;
126     StgClosure   *static_link;
127     StgInfoTable *saved_info;
128 } StgIndStatic;
129
130 typedef struct StgBlockingQueue_ {
131     StgHeader   header;
132     struct StgBlockingQueue_ *link; // here so it looks like an IND
133     StgClosure *bh;  // the BLACKHOLE
134     StgTSO     *owner;
135     struct MessageBlackHole_ *queue;
136 } StgBlockingQueue;
137
138 typedef struct {
139     StgHeader  header;
140     StgWord    bytes;
141     StgWord    payload[FLEXIBLE_ARRAY];
142 } StgArrWords;
143
144 typedef struct {
145     StgHeader   header;
146     StgWord     ptrs;
147     StgWord     size; // ptrs plus card table
148     StgClosure *payload[FLEXIBLE_ARRAY];
149     // see also: StgMutArrPtrs macros in ClosureMacros.h
150 } StgMutArrPtrs;
151
152 typedef struct {
153     StgHeader   header;
154     StgClosure *var;
155 } StgMutVar;
156
157 typedef struct _StgUpdateFrame {
158     StgHeader  header;
159     StgClosure *updatee;
160 } StgUpdateFrame;
161
162 typedef struct {
163     StgHeader  header;
164     StgWord    exceptions_blocked;
165     StgClosure *handler;
166 } StgCatchFrame;
167
168 typedef struct {
169     const StgInfoTable* info;
170     struct StgStack_ *next_chunk;
171 } StgUnderflowFrame;
172
173 typedef struct {
174     StgHeader  header;
175 } StgStopFrame;  
176
177 typedef struct {
178   StgHeader header;
179   StgWord data;
180 } StgIntCharlikeClosure;
181
182 /* statically allocated */
183 typedef struct {
184   StgHeader  header;
185 } StgRetry;
186
187 typedef struct _StgStableName {
188   StgHeader      header;
189   StgWord        sn;
190 } StgStableName;
191
192 typedef struct _StgWeak {       /* Weak v */
193   StgHeader header;
194   StgClosure *cfinalizer;
195   StgClosure *key;
196   StgClosure *value;            /* v */
197   StgClosure *finalizer;
198   struct _StgWeak *link;
199 } StgWeak;
200
201 typedef struct _StgDeadWeak {   /* Weak v */
202   StgHeader header;
203   struct _StgWeak *link;
204 } StgDeadWeak;
205
206 /* Byte code objects.  These are fixed size objects with pointers to
207  * four arrays, designed so that a BCO can be easily "re-linked" to
208  * other BCOs, to facilitate GHC's intelligent recompilation.  The
209  * array of instructions is static and not re-generated when the BCO
210  * is re-linked, but the other 3 arrays will be regenerated.
211  *
212  * A BCO represents either a function or a stack frame.  In each case,
213  * it needs a bitmap to describe to the garbage collector the
214  * pointerhood of its arguments/free variables respectively, and in
215  * the case of a function it also needs an arity.  These are stored
216  * directly in the BCO, rather than in the instrs array, for two
217  * reasons:
218  * (a) speed: we need to get at the bitmap info quickly when
219  *     the GC is examining APs and PAPs that point to this BCO
220  * (b) a subtle interaction with the compacting GC.  In compacting
221  *     GC, the info that describes the size/layout of a closure
222  *     cannot be in an object more than one level of indirection
223  *     away from the current object, because of the order in
224  *     which pointers are updated to point to their new locations.
225  */
226
227 typedef struct {
228     StgHeader      header;
229     StgArrWords   *instrs;      /* a pointer to an ArrWords */
230     StgArrWords   *literals;    /* a pointer to an ArrWords */
231     StgMutArrPtrs *ptrs;        /* a pointer to a  MutArrPtrs */
232     StgHalfWord   arity;        /* arity of this BCO */
233     StgHalfWord   size;         /* size of this BCO (in words) */
234     StgWord       bitmap[FLEXIBLE_ARRAY];  /* an StgLargeBitmap */
235 } StgBCO;
236
237 #define BCO_BITMAP(bco)      ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
238 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
239 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
240 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
241                                 / BITS_IN(StgWord))
242
243 /* -----------------------------------------------------------------------------
244    Dynamic stack frames for generic heap checks.
245
246    These generic heap checks are slow, but have the advantage of being
247    usable in a variety of situations.
248
249    The one restriction is that any relevant SRTs must already be pointed
250    to from the stack.  The return address doesn't need to have an info
251    table attached: hence it can be any old code pointer.
252
253    The liveness mask contains a 1 at bit n, if register Rn contains a
254    non-pointer.  The contents of all 8 vanilla registers are always saved
255    on the stack; the liveness mask tells the GC which ones contain
256    pointers.
257
258    Good places to use a generic heap check: 
259
260         - case alternatives (the return address with an SRT is already
261           on the stack).
262
263         - primitives (no SRT required).
264
265    The stack frame layout for a RET_DYN is like this:
266
267           some pointers         |-- RET_DYN_PTRS(liveness) words
268           some nonpointers      |-- RET_DYN_NONPTRS(liveness) words
269                                
270           L1                    \
271           D1-2                  |-- RET_DYN_NONPTR_REGS_SIZE words
272           F1-4                  /
273                                
274           R1-8                  |-- RET_DYN_BITMAP_SIZE words
275                                
276           return address        \
277           liveness mask         |-- StgRetDyn structure
278           stg_gen_chk_info      /
279
280    we assume that the size of a double is always 2 pointers (wasting a
281    word when it is only one pointer, but avoiding lots of #ifdefs).
282
283    See Liveness.h for the macros (RET_DYN_PTRS() etc.).
284
285    NOTE: if you change the layout of RET_DYN stack frames, then you
286    might also need to adjust the value of RESERVED_STACK_WORDS in
287    Constants.h.
288    -------------------------------------------------------------------------- */
289
290 typedef struct {
291     const StgInfoTable* info;
292     StgWord        liveness;
293     StgWord        ret_addr;
294     StgClosure *   payload[FLEXIBLE_ARRAY];
295 } StgRetDyn;
296
297 /* A function return stack frame: used when saving the state for a
298  * garbage collection at a function entry point.  The function
299  * arguments are on the stack, and we also save the function (its
300  * info table describes the pointerhood of the arguments).
301  *
302  * The stack frame size is also cached in the frame for convenience.
303  */
304 typedef struct {
305     const StgInfoTable* info;
306     StgWord        size;
307     StgClosure *   fun;
308     StgClosure *   payload[FLEXIBLE_ARRAY];
309 } StgRetFun;
310
311 /* Concurrent communication objects */
312
313 typedef struct StgMVarTSOQueue_ {
314     StgHeader                header;
315     struct StgMVarTSOQueue_ *link;
316     struct StgTSO_          *tso;
317 } StgMVarTSOQueue;
318
319 typedef struct {
320     StgHeader                header;
321     struct StgMVarTSOQueue_ *head;
322     struct StgMVarTSOQueue_ *tail;
323     StgClosure*              value;
324 } StgMVar;
325
326
327 /* STM data structures
328  *
329  *  StgTVar defines the only type that can be updated through the STM
330  *  interface.
331  * 
332  *  Note that various optimisations may be possible in order to use less
333  *  space for these data structures at the cost of more complexity in the
334  *  implementation:
335  *
336  *   - In StgTVar, current_value and first_watch_queue_entry could be held in
337  *     the same field: if any thread is waiting then its expected_value for
338  *     the tvar is the current value.  
339  *
340  *   - In StgTRecHeader, it might be worthwhile having separate chunks
341  *     of read-only and read-write locations.  This would save a
342  *     new_value field in the read-only locations.
343  *
344  *   - In StgAtomicallyFrame, we could combine the waiting bit into
345  *     the header (maybe a different info tbl for a waiting transaction).
346  *     This means we can specialise the code for the atomically frame
347  *     (it immediately switches on frame->waiting anyway).
348  */
349
350 typedef struct StgTRecHeader_ StgTRecHeader;
351
352 typedef struct StgTVarWatchQueue_ {
353   StgHeader                  header;
354   StgClosure                *closure; // StgTSO or StgAtomicInvariant
355   struct StgTVarWatchQueue_ *next_queue_entry;
356   struct StgTVarWatchQueue_ *prev_queue_entry;
357 } StgTVarWatchQueue;
358
359 typedef struct {
360   StgHeader                  header;
361   StgClosure                *volatile current_value;
362   StgTVarWatchQueue         *volatile first_watch_queue_entry;
363 #if defined(THREADED_RTS)
364   StgInt                     volatile num_updates;
365 #endif
366 } StgTVar;
367
368 typedef struct {
369   StgHeader      header;
370   StgClosure    *code;
371   StgTRecHeader *last_execution;
372   StgWord        lock;
373 } StgAtomicInvariant;
374
375 /* new_value == expected_value for read-only accesses */
376 /* new_value is a StgTVarWatchQueue entry when trec in state TREC_WAITING */
377 typedef struct {
378   StgTVar                   *tvar;
379   StgClosure                *expected_value;
380   StgClosure                *new_value; 
381 #if defined(THREADED_RTS)
382   StgInt                     num_updates;
383 #endif
384 } TRecEntry;
385
386 #define TREC_CHUNK_NUM_ENTRIES 16
387
388 typedef struct StgTRecChunk_ {
389   StgHeader                  header;
390   struct StgTRecChunk_      *prev_chunk;
391   StgWord                    next_entry_idx;
392   TRecEntry                  entries[TREC_CHUNK_NUM_ENTRIES];
393 } StgTRecChunk;
394
395 typedef enum { 
396   TREC_ACTIVE,        /* Transaction in progress, outcome undecided */
397   TREC_CONDEMNED,     /* Transaction in progress, inconsistent / out of date reads */
398   TREC_COMMITTED,     /* Transaction has committed, now updating tvars */
399   TREC_ABORTED,       /* Transaction has aborted, now reverting tvars */
400   TREC_WAITING,       /* Transaction currently waiting */
401 } TRecState;
402
403 typedef struct StgInvariantCheckQueue_ {
404   StgHeader                       header;
405   StgAtomicInvariant             *invariant;
406   StgTRecHeader                  *my_execution;
407   struct StgInvariantCheckQueue_ *next_queue_entry;
408 } StgInvariantCheckQueue;
409
410 struct StgTRecHeader_ {
411   StgHeader                  header;
412   struct StgTRecHeader_     *enclosing_trec;
413   StgTRecChunk              *current_chunk;
414   StgInvariantCheckQueue    *invariants_to_check;
415   TRecState                  state;
416 };
417
418 typedef struct {
419   StgHeader   header;
420   StgClosure *code;
421   StgTVarWatchQueue *next_invariant_to_check;
422   StgClosure *result;
423 } StgAtomicallyFrame;
424
425 typedef struct {
426   StgHeader   header;
427   StgClosure *code;
428   StgClosure *handler;
429 } StgCatchSTMFrame;
430
431 typedef struct {
432   StgHeader      header;
433   StgBool        running_alt_code;
434   StgClosure    *first_code;
435   StgClosure    *alt_code;
436 } StgCatchRetryFrame;
437
438 /* ----------------------------------------------------------------------------
439    Messages
440    ------------------------------------------------------------------------- */
441
442 typedef struct Message_ {
443     StgHeader        header;
444     struct Message_ *link;
445 } Message;
446
447 typedef struct MessageWakeup_ {
448     StgHeader header;
449     Message  *link;
450     StgTSO   *tso;
451 } MessageWakeup;
452
453 typedef struct MessageThrowTo_ {
454     StgHeader   header;
455     struct MessageThrowTo_ *link;
456     StgTSO     *source;
457     StgTSO     *target;
458     StgClosure *exception;
459 } MessageThrowTo;
460
461 typedef struct MessageBlackHole_ {
462     StgHeader   header;
463     struct MessageBlackHole_ *link;
464     StgTSO     *tso;
465     StgClosure *bh;
466 } MessageBlackHole;
467
468 #endif /* RTS_STORAGE_CLOSURES_H */