1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.30 2001/11/26 16:54:22 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 ga; */ /* nope! global addresses are managed via a hash table */
38 /* -----------------------------------------------------------------------------
40 -------------------------------------------------------------------------- */
43 StgWord procs; /* bitmask indicating on which PEs this closure resides */
46 /* -----------------------------------------------------------------------------
47 The ticky-ticky header
49 Comment from old Ticky.h:
51 This is used to record if a closure has been updated but not yet
52 entered. It is set when the closure is updated and cleared when
55 NB: It is {\em not} an ``entry count'', it is an
56 ``entries-after-update count.''
58 The commoning up of @CONST@, @CHARLIKE@ and @INTLIKE@ closures is
59 turned off(?) if this is required. This has only been done for 2s
60 collection. It is done using a nasty hack which defines the
61 @_Evacuate@ and @_Scavenge@ code for @CONST@, @CHARLIKE@ and @INTLIKE@
62 info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
63 -------------------------------------------------------------------------- */
66 /* old: W_ updated; */
69 /* -----------------------------------------------------------------------------
70 The full fixed-size closure header
72 The size of the fixed header is the sum of the optional parts plus a single
73 word for the entry code pointer.
74 -------------------------------------------------------------------------- */
77 const struct _StgInfoTable* info;
92 #define FIXED_HS (sizeof(StgHeader))
94 /* -----------------------------------------------------------------------------
97 For any given closure type (defined in InfoTables.h), there is a
98 corresponding structure defined below. The name of the structure
99 is obtained by concatenating the closure type with '_closure'
100 -------------------------------------------------------------------------- */
102 /* All closures follow the generic format */
106 struct StgClosure_ *payload[FLEXIBLE_ARRAY];
109 /* What a stroke of luck - all our mutable closures follow the same
110 * basic layout, with the mutable link field as the second field after
111 * the header. This means the following structure is the supertype of
115 typedef struct StgMutClosure_ {
118 struct StgMutClosure_ *mut_link;
119 struct StgClosure_ *payload[FLEXIBLE_ARRAY];
124 StgClosure *selectee;
131 StgClosure *payload[FLEXIBLE_ARRAY];
138 StgClosure *payload[FLEXIBLE_ARRAY];
143 StgClosure *indirectee;
148 StgClosure *indirectee;
149 StgMutClosure *mut_link;
154 StgClosure *indirectee;
155 StgClosure *static_link;
156 struct _StgInfoTable *saved_info;
162 StgWord payload[FLEXIBLE_ARRAY];
168 StgMutClosure *mut_link; /* mutable list */
169 StgClosure *payload[FLEXIBLE_ARRAY];
175 StgMutClosure *mut_link;
180 StgArrWords *instrs; /* a pointer to an ArrWords */
181 StgArrWords *literals; /* a pointer to an ArrWords */
182 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
183 StgArrWords *itbls; /* a pointer to an ArrWords */
187 A collective typedef for all linkable stack frames i.e.
188 StgUpdateFrame, StgSeqFrame, StgCatchFrame
190 typedef struct _StgFrame {
192 struct _StgFrame *link;
195 typedef struct _StgUpdateFrame {
197 struct _StgUpdateFrame *link;
203 struct _StgUpdateFrame *link;
208 struct _StgUpdateFrame *link;
209 StgInt exceptions_blocked;
225 } StgIntCharlikeClosure;
227 /* statically allocated */
232 typedef struct _StgForeignObj {
234 StgAddr data; /* pointer to data in non-haskell-land */
237 typedef struct _StgStableName {
242 typedef struct _StgWeak { /* Weak v */
245 StgClosure *value; /* v */
246 StgClosure *finalizer;
247 struct _StgWeak *link;
250 typedef struct _StgDeadWeak { /* Weak v */
252 struct _StgWeak *link;
255 /* Dynamic stack frames - these have a liveness mask in the object
256 * itself, rather than in the info table. Useful for generic heap
261 const struct _StgInfoTable* info;
264 StgWord payload[FLEXIBLE_ARRAY];
267 /* Concurrent communication objects */
271 struct StgTSO_ *head;
272 StgMutClosure *mut_link;
273 struct StgTSO_ *tail;
277 #if defined(PAR) || defined(GRAN)
279 StgBlockingQueueElement is a ``collective type'' representing the types
280 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
281 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
282 queue). Logically, this is a union type, but defining another struct
283 with a common layout is easier to handle in the code (same as for
285 Note that in the standard setup only StgTSOs can be on a blocking queue.
286 This is one of the main reasons for slightly different code in files
289 typedef struct StgBlockingQueueElement_ {
291 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
292 StgMutClosure *mut_link; /* next elem in mutable list */
293 struct StgClosure_ *payload[FLEXIBLE_ARRAY];/* contents of the closure */
294 } StgBlockingQueueElement;
296 /* only difference to std code is type of the elem in the BQ */
297 typedef struct StgBlockingQueue_ {
299 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
300 StgMutClosure *mut_link; /* next elem in mutable list */
303 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
304 typedef struct StgRBHSave_ {
306 StgClosure *payload[FLEXIBLE_ARRAY]; /* 2 words ripped out of the guts of the */
307 } StgRBHSave; /* closure holding the blocking queue */
309 typedef struct StgRBH_ {
311 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
312 StgMutClosure *mut_link; /* next elem in mutable list */
317 typedef struct StgBlockingQueue_ {
319 struct StgTSO_ *blocking_queue;
320 StgMutClosure *mut_link;
326 /* global indirections aka FETCH_ME closures */
327 typedef struct StgFetchMe_ {
329 globalAddr *ga; /* ptr to unique id for a closure */
330 StgMutClosure *mut_link; /* next elem in mutable list */
333 /* same contents as an ordinary StgBlockingQueue */
334 typedef struct StgFetchMeBlockingQueue_ {
336 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
337 StgMutClosure *mut_link; /* next elem in mutable list */
338 } StgFetchMeBlockingQueue;
340 /* This is an entry in a blocking queue. It indicates a fetch request from a
341 TSO on another PE demanding the value of this closur. Note that a
342 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
343 updated with the result, the result will be sent back (the PE is encoded
344 in the globalAddr) and the StgBlockedFetch closure will be nuked.
346 typedef struct StgBlockedFetch_ {
348 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
349 StgMutClosure *mut_link; /* next elem in mutable list */
350 StgClosure *node; /* node to fetch */
351 globalAddr ga; /* where to send the result to */
352 } StgBlockedFetch; /* NB: not just a ptr to a GA */
355 #endif /* CLOSURES_H */