root/includes/rts/storage/Closures.h

Revision d0bfe30b668d5be86c00fe3635ef4f4dfe13a1f0, 14.0 KB (checked in by Simon Marlow <marlowsd@…>, 16 months ago)

add a const

  • Property mode set to 100644
Line 
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
21typedef 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
42typedef 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
53typedef struct {
54    const StgInfoTable* info;
55#ifdef PROFILING
56    StgProfHeader         prof;
57#endif
58} StgHeader;
59
60typedef 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
80typedef struct StgClosure_ {
81    StgHeader   header;
82    struct StgClosure_ *payload[FLEXIBLE_ARRAY];
83} *StgClosurePtr; // StgClosure defined in Rts.h
84
85typedef struct {
86    StgThunkHeader  header;
87    struct StgClosure_ *payload[FLEXIBLE_ARRAY];
88} StgThunk;
89
90typedef struct {
91    StgThunkHeader   header;
92    StgClosure *selectee;
93} StgSelector;
94
95typedef 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
103typedef 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
111typedef 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
118typedef struct {
119    StgHeader   header;
120    StgClosure *indirectee;
121} StgInd;
122
123typedef struct {
124    StgHeader     header;
125    StgClosure   *indirectee;
126    StgClosure   *static_link;
127    const StgInfoTable *saved_info;
128} StgIndStatic;
129
130typedef 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
138typedef struct {
139    StgHeader  header;
140    StgWord    bytes;
141    StgWord    payload[FLEXIBLE_ARRAY];
142} StgArrWords;
143
144typedef 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
152typedef struct {
153    StgHeader   header;
154    StgClosure *var;
155} StgMutVar;
156
157typedef struct _StgUpdateFrame {
158    StgHeader  header;
159    StgClosure *updatee;
160} StgUpdateFrame;
161
162typedef struct {
163    StgHeader  header;
164    StgWord    exceptions_blocked;
165    StgClosure *handler;
166} StgCatchFrame;
167
168typedef struct {
169    const StgInfoTable* info;
170    struct StgStack_ *next_chunk;
171} StgUnderflowFrame;
172
173typedef struct {
174    StgHeader  header;
175} StgStopFrame; 
176
177typedef struct {
178  StgHeader header;
179  StgWord data;
180} StgIntCharlikeClosure;
181
182/* statically allocated */
183typedef struct {
184  StgHeader  header;
185} StgRetry;
186
187typedef struct _StgStableName {
188  StgHeader      header;
189  StgWord        sn;
190} StgStableName;
191
192typedef 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
201typedef 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
227typedef 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
290typedef 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 */
304typedef struct {
305    const StgInfoTable* info;
306    StgWord        size;
307    StgClosure *   fun;
308    StgClosure *   payload[FLEXIBLE_ARRAY];
309} StgRetFun;
310
311/* Concurrent communication objects */
312
313typedef struct StgMVarTSOQueue_ {
314    StgHeader                header;
315    struct StgMVarTSOQueue_ *link;
316    struct StgTSO_          *tso;
317} StgMVarTSOQueue;
318
319typedef 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
350typedef struct StgTRecHeader_ StgTRecHeader;
351
352typedef 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
359typedef 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
368typedef 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 */
377typedef 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
388typedef 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
395typedef 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
403typedef struct StgInvariantCheckQueue_ {
404  StgHeader                       header;
405  StgAtomicInvariant             *invariant;
406  StgTRecHeader                  *my_execution;
407  struct StgInvariantCheckQueue_ *next_queue_entry;
408} StgInvariantCheckQueue;
409
410struct StgTRecHeader_ {
411  StgHeader                  header;
412  struct StgTRecHeader_     *enclosing_trec;
413  StgTRecChunk              *current_chunk;
414  StgInvariantCheckQueue    *invariants_to_check;
415  TRecState                  state;
416};
417
418typedef struct {
419  StgHeader   header;
420  StgClosure *code;
421  StgTVarWatchQueue *next_invariant_to_check;
422  StgClosure *result;
423} StgAtomicallyFrame;
424
425typedef struct {
426  StgHeader   header;
427  StgClosure *code;
428  StgClosure *handler;
429} StgCatchSTMFrame;
430
431typedef 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
442typedef struct Message_ {
443    StgHeader        header;
444    struct Message_ *link;
445} Message;
446
447typedef struct MessageWakeup_ {
448    StgHeader header;
449    Message  *link;
450    StgTSO   *tso;
451} MessageWakeup;
452
453typedef struct MessageThrowTo_ {
454    StgHeader   header;
455    struct MessageThrowTo_ *link;
456    StgTSO     *source;
457    StgTSO     *target;
458    StgClosure *exception;
459} MessageThrowTo;
460
461typedef struct MessageBlackHole_ {
462    StgHeader   header;
463    struct MessageBlackHole_ *link;
464    StgTSO     *tso;
465    StgClosure *bh;
466} MessageBlackHole;
467
468#endif /* RTS_STORAGE_CLOSURES_H */
Note: See TracBrowser for help on using the browser.