Implement {resize,shrink}MutableByteArray# primops
[ghc.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/Types.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 const 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 /* This struct should be called StgArrBytes rather than StgArrWords.
139 *
140 * One might be very tempted to store the number of words in the bytes field,
141 * but the garbage collector will erase your data then.
142 *
143 * It's name is for historical reasons, see #3800
144 */
145 typedef struct {
146 StgHeader header;
147 StgWord bytes;
148 StgWord payload[FLEXIBLE_ARRAY];
149 } StgArrWords; // TODO: s/StgArrWords/StgArrBytes (#8552)
150
151 typedef struct {
152 StgHeader header;
153 StgWord ptrs;
154 StgWord size; // ptrs plus card table
155 StgClosure *payload[FLEXIBLE_ARRAY];
156 // see also: StgMutArrPtrs macros in ClosureMacros.h
157 } StgMutArrPtrs;
158
159 typedef struct {
160 StgHeader header;
161 StgWord ptrs;
162 StgClosure *payload[FLEXIBLE_ARRAY];
163 } StgSmallMutArrPtrs;
164
165 typedef struct {
166 StgHeader header;
167 StgClosure *var;
168 } StgMutVar;
169
170 typedef struct _StgUpdateFrame {
171 StgHeader header;
172 StgClosure *updatee;
173 } StgUpdateFrame;
174
175 typedef struct {
176 StgHeader header;
177 StgWord exceptions_blocked;
178 StgClosure *handler;
179 } StgCatchFrame;
180
181 typedef struct {
182 const StgInfoTable* info;
183 struct StgStack_ *next_chunk;
184 } StgUnderflowFrame;
185
186 typedef struct {
187 StgHeader header;
188 } StgStopFrame;
189
190 typedef struct {
191 StgHeader header;
192 StgWord data;
193 } StgIntCharlikeClosure;
194
195 /* statically allocated */
196 typedef struct {
197 StgHeader header;
198 } StgRetry;
199
200 typedef struct _StgStableName {
201 StgHeader header;
202 StgWord sn;
203 } StgStableName;
204
205 typedef struct _StgWeak { /* Weak v */
206 StgHeader header;
207 StgClosure *cfinalizers;
208 StgClosure *key;
209 StgClosure *value; /* v */
210 StgClosure *finalizer;
211 struct _StgWeak *link;
212 } StgWeak;
213
214 typedef struct _StgCFinalizerList {
215 StgHeader header;
216 StgClosure *link;
217 void (*fptr)(void);
218 void *ptr;
219 void *eptr;
220 StgWord flag; /* has environment (0 or 1) */
221 } StgCFinalizerList;
222
223 /* Byte code objects. These are fixed size objects with pointers to
224 * four arrays, designed so that a BCO can be easily "re-linked" to
225 * other BCOs, to facilitate GHC's intelligent recompilation. The
226 * array of instructions is static and not re-generated when the BCO
227 * is re-linked, but the other 3 arrays will be regenerated.
228 *
229 * A BCO represents either a function or a stack frame. In each case,
230 * it needs a bitmap to describe to the garbage collector the
231 * pointerhood of its arguments/free variables respectively, and in
232 * the case of a function it also needs an arity. These are stored
233 * directly in the BCO, rather than in the instrs array, for two
234 * reasons:
235 * (a) speed: we need to get at the bitmap info quickly when
236 * the GC is examining APs and PAPs that point to this BCO
237 * (b) a subtle interaction with the compacting GC. In compacting
238 * GC, the info that describes the size/layout of a closure
239 * cannot be in an object more than one level of indirection
240 * away from the current object, because of the order in
241 * which pointers are updated to point to their new locations.
242 */
243
244 typedef struct {
245 StgHeader header;
246 StgArrWords *instrs; /* a pointer to an ArrWords */
247 StgArrWords *literals; /* a pointer to an ArrWords */
248 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
249 StgHalfWord arity; /* arity of this BCO */
250 StgHalfWord size; /* size of this BCO (in words) */
251 StgWord bitmap[FLEXIBLE_ARRAY]; /* an StgLargeBitmap */
252 } StgBCO;
253
254 #define BCO_BITMAP(bco) ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
255 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
256 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
257 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
258 / BITS_IN(StgWord))
259
260 /* A function return stack frame: used when saving the state for a
261 * garbage collection at a function entry point. The function
262 * arguments are on the stack, and we also save the function (its
263 * info table describes the pointerhood of the arguments).
264 *
265 * The stack frame size is also cached in the frame for convenience.
266 */
267 typedef struct {
268 const StgInfoTable* info;
269 StgWord size;
270 StgClosure * fun;
271 StgClosure * payload[FLEXIBLE_ARRAY];
272 } StgRetFun;
273
274 /* Concurrent communication objects */
275
276 typedef struct StgMVarTSOQueue_ {
277 StgHeader header;
278 struct StgMVarTSOQueue_ *link;
279 struct StgTSO_ *tso;
280 } StgMVarTSOQueue;
281
282 typedef struct {
283 StgHeader header;
284 struct StgMVarTSOQueue_ *head;
285 struct StgMVarTSOQueue_ *tail;
286 StgClosure* value;
287 } StgMVar;
288
289
290 /* STM data structures
291 *
292 * StgTVar defines the only type that can be updated through the STM
293 * interface.
294 *
295 * Note that various optimisations may be possible in order to use less
296 * space for these data structures at the cost of more complexity in the
297 * implementation:
298 *
299 * - In StgTVar, current_value and first_watch_queue_entry could be held in
300 * the same field: if any thread is waiting then its expected_value for
301 * the tvar is the current value.
302 *
303 * - In StgTRecHeader, it might be worthwhile having separate chunks
304 * of read-only and read-write locations. This would save a
305 * new_value field in the read-only locations.
306 *
307 * - In StgAtomicallyFrame, we could combine the waiting bit into
308 * the header (maybe a different info tbl for a waiting transaction).
309 * This means we can specialise the code for the atomically frame
310 * (it immediately switches on frame->waiting anyway).
311 */
312
313 typedef struct StgTRecHeader_ StgTRecHeader;
314
315 typedef struct StgTVarWatchQueue_ {
316 StgHeader header;
317 StgClosure *closure; // StgTSO or StgAtomicInvariant
318 struct StgTVarWatchQueue_ *next_queue_entry;
319 struct StgTVarWatchQueue_ *prev_queue_entry;
320 } StgTVarWatchQueue;
321
322 typedef struct {
323 StgHeader header;
324 StgClosure *volatile current_value;
325 StgTVarWatchQueue *volatile first_watch_queue_entry;
326 StgInt volatile num_updates;
327 } StgTVar;
328
329 typedef struct {
330 StgHeader header;
331 StgClosure *code;
332 StgTRecHeader *last_execution;
333 StgWord lock;
334 } StgAtomicInvariant;
335
336 /* new_value == expected_value for read-only accesses */
337 /* new_value is a StgTVarWatchQueue entry when trec in state TREC_WAITING */
338 typedef struct {
339 StgTVar *tvar;
340 StgClosure *expected_value;
341 StgClosure *new_value;
342 #if defined(THREADED_RTS)
343 StgInt num_updates;
344 #endif
345 } TRecEntry;
346
347 #define TREC_CHUNK_NUM_ENTRIES 16
348
349 typedef struct StgTRecChunk_ {
350 StgHeader header;
351 struct StgTRecChunk_ *prev_chunk;
352 StgWord next_entry_idx;
353 TRecEntry entries[TREC_CHUNK_NUM_ENTRIES];
354 } StgTRecChunk;
355
356 typedef enum {
357 TREC_ACTIVE, /* Transaction in progress, outcome undecided */
358 TREC_CONDEMNED, /* Transaction in progress, inconsistent / out of date reads */
359 TREC_COMMITTED, /* Transaction has committed, now updating tvars */
360 TREC_ABORTED, /* Transaction has aborted, now reverting tvars */
361 TREC_WAITING, /* Transaction currently waiting */
362 } TRecState;
363
364 typedef struct StgInvariantCheckQueue_ {
365 StgHeader header;
366 StgAtomicInvariant *invariant;
367 StgTRecHeader *my_execution;
368 struct StgInvariantCheckQueue_ *next_queue_entry;
369 } StgInvariantCheckQueue;
370
371 struct StgTRecHeader_ {
372 StgHeader header;
373 struct StgTRecHeader_ *enclosing_trec;
374 StgTRecChunk *current_chunk;
375 StgInvariantCheckQueue *invariants_to_check;
376 TRecState state;
377 };
378
379 typedef struct {
380 StgHeader header;
381 StgClosure *code;
382 StgTVarWatchQueue *next_invariant_to_check;
383 StgClosure *result;
384 } StgAtomicallyFrame;
385
386 typedef struct {
387 StgHeader header;
388 StgClosure *code;
389 StgClosure *handler;
390 } StgCatchSTMFrame;
391
392 typedef struct {
393 StgHeader header;
394 StgWord running_alt_code;
395 StgClosure *first_code;
396 StgClosure *alt_code;
397 } StgCatchRetryFrame;
398
399 /* ----------------------------------------------------------------------------
400 Messages
401 ------------------------------------------------------------------------- */
402
403 typedef struct Message_ {
404 StgHeader header;
405 struct Message_ *link;
406 } Message;
407
408 typedef struct MessageWakeup_ {
409 StgHeader header;
410 Message *link;
411 StgTSO *tso;
412 } MessageWakeup;
413
414 typedef struct MessageThrowTo_ {
415 StgHeader header;
416 struct MessageThrowTo_ *link;
417 StgTSO *source;
418 StgTSO *target;
419 StgClosure *exception;
420 } MessageThrowTo;
421
422 typedef struct MessageBlackHole_ {
423 StgHeader header;
424 struct MessageBlackHole_ *link;
425 StgTSO *tso;
426 StgClosure *bh;
427 } MessageBlackHole;
428
429 #endif /* RTS_STORAGE_CLOSURES_H */