Prefer #if defined to #ifdef
[ghc.git] / includes / rts / storage / Closures.h
1 /* ----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2004
4 *
5 * Closures
6 *
7 * -------------------------------------------------------------------------- */
8
9 #pragma once
10
11 /*
12 * The Layout of a closure header depends on which kind of system we're
13 * compiling for: profiling, parallel, ticky, etc.
14 */
15
16 /* -----------------------------------------------------------------------------
17 The profiling header
18 -------------------------------------------------------------------------- */
19
20 typedef struct {
21 CostCentreStack *ccs;
22 union {
23 struct _RetainerSet *rs; /* Retainer Set */
24 StgWord ldvw; /* Lag/Drag/Void Word */
25 } hp;
26 } StgProfHeader;
27
28 /* -----------------------------------------------------------------------------
29 The SMP header
30
31 A thunk has a padding word to take the updated value. This is so
32 that the update doesn't overwrite the payload, so we can avoid
33 needing to lock the thunk during entry and update.
34
35 Note: this doesn't apply to THUNK_STATICs, which have no payload.
36
37 Note: we leave this padding word in all ways, rather than just SMP,
38 so that we don't have to recompile all our libraries for SMP.
39 -------------------------------------------------------------------------- */
40
41 typedef struct {
42 StgWord pad;
43 } StgSMPThunkHeader;
44
45 /* -----------------------------------------------------------------------------
46 The full fixed-size closure header
47
48 The size of the fixed header is the sum of the optional parts plus a single
49 word for the entry code pointer.
50 -------------------------------------------------------------------------- */
51
52 typedef struct {
53 const StgInfoTable* info;
54 #if defined(PROFILING)
55 StgProfHeader prof;
56 #endif
57 } StgHeader;
58
59 typedef struct {
60 const StgInfoTable* info;
61 #if defined(PROFILING)
62 StgProfHeader prof;
63 #endif
64 StgSMPThunkHeader smp;
65 } StgThunkHeader;
66
67 #define THUNK_EXTRA_HEADER_W (sizeofW(StgThunkHeader)-sizeofW(StgHeader))
68
69 /* -----------------------------------------------------------------------------
70 Closure Types
71
72 For any given closure type (defined in InfoTables.h), there is a
73 corresponding structure defined below. The name of the structure
74 is obtained by concatenating the closure type with '_closure'
75 -------------------------------------------------------------------------- */
76
77 /* All closures follow the generic format */
78
79 typedef struct StgClosure_ {
80 StgHeader header;
81 struct StgClosure_ *payload[];
82 } *StgClosurePtr; // StgClosure defined in rts/Types.h
83
84 typedef struct {
85 StgThunkHeader header;
86 struct StgClosure_ *payload[];
87 } StgThunk;
88
89 typedef struct {
90 StgThunkHeader header;
91 StgClosure *selectee;
92 } StgSelector;
93
94 typedef struct {
95 StgHeader header;
96 StgHalfWord arity; /* zero if it is an AP */
97 StgHalfWord n_args;
98 StgClosure *fun; /* really points to a fun */
99 StgClosure *payload[];
100 } StgPAP;
101
102 typedef struct {
103 StgThunkHeader header;
104 StgHalfWord arity; /* zero if it is an AP */
105 StgHalfWord n_args;
106 StgClosure *fun; /* really points to a fun */
107 StgClosure *payload[];
108 } StgAP;
109
110 typedef struct {
111 StgThunkHeader header;
112 StgWord size; /* number of words in payload */
113 StgClosure *fun;
114 StgClosure *payload[]; /* contains a chunk of *stack* */
115 } StgAP_STACK;
116
117 typedef struct {
118 StgHeader header;
119 StgClosure *indirectee;
120 } StgInd;
121
122 typedef struct {
123 StgHeader header;
124 StgClosure *indirectee;
125 StgClosure *static_link;
126 const StgInfoTable *saved_info;
127 } StgIndStatic;
128
129 typedef struct StgBlockingQueue_ {
130 StgHeader header;
131 struct StgBlockingQueue_ *link; // here so it looks like an IND
132 StgClosure *bh; // the BLACKHOLE
133 StgTSO *owner;
134 struct MessageBlackHole_ *queue;
135 } StgBlockingQueue;
136
137 typedef struct {
138 StgHeader header;
139 StgWord bytes;
140 StgWord payload[];
141 } StgArrBytes;
142
143 typedef struct {
144 StgHeader header;
145 StgWord ptrs;
146 StgWord size; // ptrs plus card table
147 StgClosure *payload[];
148 // see also: StgMutArrPtrs macros in ClosureMacros.h
149 } StgMutArrPtrs;
150
151 typedef struct {
152 StgHeader header;
153 StgWord ptrs;
154 StgClosure *payload[];
155 } StgSmallMutArrPtrs;
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 StgWord exceptions_blocked;
170 StgClosure *handler;
171 } StgCatchFrame;
172
173 typedef struct {
174 const StgInfoTable* info;
175 struct StgStack_ *next_chunk;
176 } StgUnderflowFrame;
177
178 typedef struct {
179 StgHeader header;
180 } StgStopFrame;
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 _StgStableName {
193 StgHeader header;
194 StgWord sn;
195 } StgStableName;
196
197 typedef struct _StgWeak { /* Weak v */
198 StgHeader header;
199 StgClosure *cfinalizers;
200 StgClosure *key;
201 StgClosure *value; /* v */
202 StgClosure *finalizer;
203 struct _StgWeak *link;
204 } StgWeak;
205
206 typedef struct _StgCFinalizerList {
207 StgHeader header;
208 StgClosure *link;
209 void (*fptr)(void);
210 void *ptr;
211 void *eptr;
212 StgWord flag; /* has environment (0 or 1) */
213 } StgCFinalizerList;
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 StgArrBytes *instrs; /* a pointer to an ArrWords */
239 StgArrBytes *literals; /* a pointer to an ArrWords */
240 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
241 StgHalfWord arity; /* arity of this BCO */
242 StgHalfWord size; /* size of this BCO (in words) */
243 StgWord bitmap[]; /* an StgLargeBitmap */
244 } StgBCO;
245
246 #define BCO_BITMAP(bco) ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
247 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
248 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
249 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
250 / BITS_IN(StgWord))
251
252 /* A function return stack frame: used when saving the state for a
253 * garbage collection at a function entry point. The function
254 * arguments are on the stack, and we also save the function (its
255 * info table describes the pointerhood of the arguments).
256 *
257 * The stack frame size is also cached in the frame for convenience.
258 */
259 typedef struct {
260 const StgInfoTable* info;
261 StgWord size;
262 StgClosure * fun;
263 StgClosure * payload[];
264 } StgRetFun;
265
266 /* Concurrent communication objects */
267
268 typedef struct StgMVarTSOQueue_ {
269 StgHeader header;
270 struct StgMVarTSOQueue_ *link;
271 struct StgTSO_ *tso;
272 } StgMVarTSOQueue;
273
274 typedef struct {
275 StgHeader header;
276 struct StgMVarTSOQueue_ *head;
277 struct StgMVarTSOQueue_ *tail;
278 StgClosure* value;
279 } StgMVar;
280
281
282 /* STM data structures
283 *
284 * StgTVar defines the only type that can be updated through the STM
285 * interface.
286 *
287 * Note that various optimisations may be possible in order to use less
288 * space for these data structures at the cost of more complexity in the
289 * implementation:
290 *
291 * - In StgTVar, current_value and first_watch_queue_entry could be held in
292 * the same field: if any thread is waiting then its expected_value for
293 * the tvar is the current value.
294 *
295 * - In StgTRecHeader, it might be worthwhile having separate chunks
296 * of read-only and read-write locations. This would save a
297 * new_value field in the read-only locations.
298 *
299 * - In StgAtomicallyFrame, we could combine the waiting bit into
300 * the header (maybe a different info tbl for a waiting transaction).
301 * This means we can specialise the code for the atomically frame
302 * (it immediately switches on frame->waiting anyway).
303 */
304
305 typedef struct StgTRecHeader_ StgTRecHeader;
306
307 typedef struct StgTVarWatchQueue_ {
308 StgHeader header;
309 StgClosure *closure; // StgTSO or StgAtomicInvariant
310 struct StgTVarWatchQueue_ *next_queue_entry;
311 struct StgTVarWatchQueue_ *prev_queue_entry;
312 } StgTVarWatchQueue;
313
314 typedef struct {
315 StgHeader header;
316 StgClosure *volatile current_value;
317 StgTVarWatchQueue *volatile first_watch_queue_entry;
318 StgInt volatile num_updates;
319 } StgTVar;
320
321 typedef struct {
322 StgHeader header;
323 StgClosure *code;
324 StgTRecHeader *last_execution;
325 StgWord lock;
326 } StgAtomicInvariant;
327
328 /* new_value == expected_value for read-only accesses */
329 /* new_value is a StgTVarWatchQueue entry when trec in state TREC_WAITING */
330 typedef struct {
331 StgTVar *tvar;
332 StgClosure *expected_value;
333 StgClosure *new_value;
334 #if defined(THREADED_RTS)
335 StgInt num_updates;
336 #endif
337 } TRecEntry;
338
339 #define TREC_CHUNK_NUM_ENTRIES 16
340
341 typedef struct StgTRecChunk_ {
342 StgHeader header;
343 struct StgTRecChunk_ *prev_chunk;
344 StgWord next_entry_idx;
345 TRecEntry entries[TREC_CHUNK_NUM_ENTRIES];
346 } StgTRecChunk;
347
348 typedef enum {
349 TREC_ACTIVE, /* Transaction in progress, outcome undecided */
350 TREC_CONDEMNED, /* Transaction in progress, inconsistent / out of date reads */
351 TREC_COMMITTED, /* Transaction has committed, now updating tvars */
352 TREC_ABORTED, /* Transaction has aborted, now reverting tvars */
353 TREC_WAITING, /* Transaction currently waiting */
354 } TRecState;
355
356 typedef struct StgInvariantCheckQueue_ {
357 StgHeader header;
358 StgAtomicInvariant *invariant;
359 StgTRecHeader *my_execution;
360 struct StgInvariantCheckQueue_ *next_queue_entry;
361 } StgInvariantCheckQueue;
362
363 struct StgTRecHeader_ {
364 StgHeader header;
365 struct StgTRecHeader_ *enclosing_trec;
366 StgTRecChunk *current_chunk;
367 StgInvariantCheckQueue *invariants_to_check;
368 TRecState state;
369 };
370
371 typedef struct {
372 StgHeader header;
373 StgClosure *code;
374 StgTVarWatchQueue *next_invariant_to_check;
375 StgClosure *result;
376 } StgAtomicallyFrame;
377
378 typedef struct {
379 StgHeader header;
380 StgClosure *code;
381 StgClosure *handler;
382 } StgCatchSTMFrame;
383
384 typedef struct {
385 StgHeader header;
386 StgWord running_alt_code;
387 StgClosure *first_code;
388 StgClosure *alt_code;
389 } StgCatchRetryFrame;
390
391 /* ----------------------------------------------------------------------------
392 Messages
393 ------------------------------------------------------------------------- */
394
395 typedef struct Message_ {
396 StgHeader header;
397 struct Message_ *link;
398 } Message;
399
400 typedef struct MessageWakeup_ {
401 StgHeader header;
402 Message *link;
403 StgTSO *tso;
404 } MessageWakeup;
405
406 typedef struct MessageThrowTo_ {
407 StgHeader header;
408 struct MessageThrowTo_ *link;
409 StgTSO *source;
410 StgTSO *target;
411 StgClosure *exception;
412 } MessageThrowTo;
413
414 typedef struct MessageBlackHole_ {
415 StgHeader header;
416 struct MessageBlackHole_ *link;
417 StgTSO *tso;
418 StgClosure *bh;
419 } MessageBlackHole;
420
421 /* ----------------------------------------------------------------------------
422 Compact Regions
423 ------------------------------------------------------------------------- */
424
425 //
426 // A compact region is a list of blocks. Each block starts with an
427 // StgCompactNFDataBlock structure, and the list is chained through the next
428 // field of these structs. (the link field of the bdescr is used to chain
429 // together multiple compact region on the compact_objects field of a
430 // generation).
431 //
432 // See Note [Compact Normal Forms] for details
433 //
434 typedef struct StgCompactNFDataBlock_ {
435 struct StgCompactNFDataBlock_ *self;
436 // the address of this block this is copied over to the
437 // receiving end when serializing a compact, so the receiving
438 // end can allocate the block at best as it can, and then
439 // verify if pointer adjustment is needed or not by comparing
440 // self with the actual address; the same data is sent over as
441 // SerializedCompact metadata, but having it here simplifies
442 // the fixup implementation.
443 struct StgCompactNFData_ *owner;
444 // the closure who owns this block (used in objectGetCompact)
445 struct StgCompactNFDataBlock_ *next;
446 // chain of blocks used for serialization and freeing
447 } StgCompactNFDataBlock;
448
449 //
450 // This is the Compact# primitive object.
451 //
452 typedef struct StgCompactNFData_ {
453 StgHeader header;
454 // for sanity and other checks in practice, nothing should ever
455 // need the compact info pointer (we don't even need fwding
456 // pointers because it's a large object)
457 StgWord totalW;
458 // Total number of words in all blocks in the compact
459 StgWord autoBlockW;
460 // size of automatically appended blocks
461 StgPtr hp, hpLim;
462 // the beginning and end of the free area in the nursery block. This is
463 // just a convenience so that we can avoid multiple indirections through
464 // the nursery pointer below during compaction.
465 StgCompactNFDataBlock *nursery;
466 // where to (try to) allocate from when appending
467 StgCompactNFDataBlock *last;
468 // the last block of the chain (to know where to append new
469 // blocks for resize)
470 struct hashtable *hash;
471 // the hash table for the current compaction, or NULL if
472 // there's no (sharing-preserved) compaction in progress.
473 StgClosure *result;
474 // Used temporarily to store the result of compaction. Doesn't need to be
475 // a GC root.
476 } StgCompactNFData;