1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.31 2002/01/29 16:52:46 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
8 * -------------------------------------------------------------------------- */
14 * The Layout of a closure header depends on which kind of system we're
15 * compiling for: profiling, parallel, ticky, etc.
18 /* -----------------------------------------------------------------------------
20 -------------------------------------------------------------------------- */
25 struct _RetainerSet *rs; // Retainer Set
26 StgWord ldvw; // Lag/Drag/Void Word
30 /* -----------------------------------------------------------------------------
32 -------------------------------------------------------------------------- */
35 StgWord procs; /* bitmask indicating on which PEs this closure resides */
38 /* -----------------------------------------------------------------------------
39 The full fixed-size closure header
41 The size of the fixed header is the sum of the optional parts plus a single
42 word for the entry code pointer.
43 -------------------------------------------------------------------------- */
46 const struct _StgInfoTable* info;
55 #define FIXED_HS (sizeof(StgHeader))
57 /* -----------------------------------------------------------------------------
60 For any given closure type (defined in InfoTables.h), there is a
61 corresponding structure defined below. The name of the structure
62 is obtained by concatenating the closure type with '_closure'
63 -------------------------------------------------------------------------- */
65 /* All closures follow the generic format */
69 struct StgClosure_ *payload[FLEXIBLE_ARRAY];
72 /* What a stroke of luck - all our mutable closures follow the same
73 * basic layout, with the mutable link field as the second field after
74 * the header. This means the following structure is the supertype of
78 typedef struct StgMutClosure_ {
81 struct StgMutClosure_ *mut_link;
82 struct StgClosure_ *payload[FLEXIBLE_ARRAY];
94 StgClosure *payload[FLEXIBLE_ARRAY];
101 StgClosure *payload[FLEXIBLE_ARRAY];
106 StgClosure *indirectee;
111 StgClosure *indirectee;
112 StgMutClosure *mut_link;
117 StgClosure *indirectee;
118 StgClosure *static_link;
119 struct _StgInfoTable *saved_info;
125 StgWord payload[FLEXIBLE_ARRAY];
131 StgMutClosure *mut_link; /* mutable list */
132 StgClosure *payload[FLEXIBLE_ARRAY];
138 StgMutClosure *mut_link;
143 StgArrWords *instrs; /* a pointer to an ArrWords */
144 StgArrWords *literals; /* a pointer to an ArrWords */
145 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
146 StgArrWords *itbls; /* a pointer to an ArrWords */
150 A collective typedef for all linkable stack frames i.e.
151 StgUpdateFrame, StgSeqFrame, StgCatchFrame
153 typedef struct _StgFrame {
155 struct _StgFrame *link;
158 typedef struct _StgUpdateFrame {
160 struct _StgUpdateFrame *link;
166 struct _StgUpdateFrame *link;
171 struct _StgUpdateFrame *link;
172 StgInt exceptions_blocked;
188 } StgIntCharlikeClosure;
190 /* statically allocated */
195 typedef struct _StgForeignObj {
197 StgAddr data; /* pointer to data in non-haskell-land */
200 typedef struct _StgStableName {
205 typedef struct _StgWeak { /* Weak v */
208 StgClosure *value; /* v */
209 StgClosure *finalizer;
210 struct _StgWeak *link;
213 typedef struct _StgDeadWeak { /* Weak v */
215 struct _StgWeak *link;
218 /* Dynamic stack frames - these have a liveness mask in the object
219 * itself, rather than in the info table. Useful for generic heap
224 const struct _StgInfoTable* info;
227 StgWord payload[FLEXIBLE_ARRAY];
230 /* Concurrent communication objects */
234 struct StgTSO_ *head;
235 StgMutClosure *mut_link;
236 struct StgTSO_ *tail;
240 #if defined(PAR) || defined(GRAN)
242 StgBlockingQueueElement is a ``collective type'' representing the types
243 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
244 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
245 queue). Logically, this is a union type, but defining another struct
246 with a common layout is easier to handle in the code (same as for
248 Note that in the standard setup only StgTSOs can be on a blocking queue.
249 This is one of the main reasons for slightly different code in files
252 typedef struct StgBlockingQueueElement_ {
254 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
255 StgMutClosure *mut_link; /* next elem in mutable list */
256 struct StgClosure_ *payload[FLEXIBLE_ARRAY];/* contents of the closure */
257 } StgBlockingQueueElement;
259 /* only difference to std code is type of the elem in the BQ */
260 typedef struct StgBlockingQueue_ {
262 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
263 StgMutClosure *mut_link; /* next elem in mutable list */
266 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
267 typedef struct StgRBHSave_ {
269 StgClosure *payload[FLEXIBLE_ARRAY]; /* 2 words ripped out of the guts of the */
270 } StgRBHSave; /* closure holding the blocking queue */
272 typedef struct StgRBH_ {
274 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
275 StgMutClosure *mut_link; /* next elem in mutable list */
280 typedef struct StgBlockingQueue_ {
282 struct StgTSO_ *blocking_queue;
283 StgMutClosure *mut_link;
289 /* global indirections aka FETCH_ME closures */
290 typedef struct StgFetchMe_ {
292 globalAddr *ga; /* ptr to unique id for a closure */
293 StgMutClosure *mut_link; /* next elem in mutable list */
296 /* same contents as an ordinary StgBlockingQueue */
297 typedef struct StgFetchMeBlockingQueue_ {
299 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
300 StgMutClosure *mut_link; /* next elem in mutable list */
301 } StgFetchMeBlockingQueue;
303 /* This is an entry in a blocking queue. It indicates a fetch request from a
304 TSO on another PE demanding the value of this closur. Note that a
305 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
306 updated with the result, the result will be sent back (the PE is encoded
307 in the globalAddr) and the StgBlockedFetch closure will be nuked.
309 typedef struct StgBlockedFetch_ {
311 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
312 StgMutClosure *mut_link; /* next elem in mutable list */
313 StgClosure *node; /* node to fetch */
314 globalAddr ga; /* where to send the result to */
315 } StgBlockedFetch; /* NB: not just a ptr to a GA */
318 #endif /* CLOSURES_H */