1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.21 2000/12/11 12:59:25 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 -------------------------------------------------------------------------- */
28 #else /* !PROFILING */
34 #endif /* PROFILING */
36 /* -----------------------------------------------------------------------------
38 -------------------------------------------------------------------------- */
43 /* StgWord ga; */ /* nope! global addresses are managed via a hash table */
54 /* -----------------------------------------------------------------------------
56 -------------------------------------------------------------------------- */
61 StgWord procs; /* bitmask indicating on which PEs this closure resides */
72 /* -----------------------------------------------------------------------------
73 The ticky-ticky header
75 Comment from old Ticky.h:
77 This is used to record if a closure has been updated but not yet
78 entered. It is set when the closure is updated and cleared when
81 NB: It is {\em not} an ``entry count'', it is an
82 ``entries-after-update count.''
84 The commoning up of @CONST@, @CHARLIKE@ and @INTLIKE@ closures is
85 turned off(?) if this is required. This has only been done for 2s
86 collection. It is done using a nasty hack which defines the
87 @_Evacuate@ and @_Scavenge@ code for @CONST@, @CHARLIKE@ and @INTLIKE@
88 info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
89 -------------------------------------------------------------------------- */
94 /* old: W_ updated; */
97 #else /* !TICKY_TICKY */
103 #endif /* TICKY_TICKY */
105 /* -----------------------------------------------------------------------------
106 The full fixed-size closure header
108 The size of the fixed header is the sum of the optional parts plus a single
109 word for the entry code pointer.
110 -------------------------------------------------------------------------- */
113 const struct _StgInfoTable* info;
124 StgTickyHeader ticky;
128 #define FIXED_HS (sizeof(StgHeader))
130 /* -----------------------------------------------------------------------------
133 For any given closure type (defined in InfoTables.h), there is a
134 corresponding structure defined below. The name of the structure
135 is obtained by concatenating the closure type with '_closure'
136 -------------------------------------------------------------------------- */
138 /* All closures follow the generic format */
142 struct StgClosure_ *payload[0];
145 /* What a stroke of luck - all our mutable closures follow the same
146 * basic layout, with the mutable link field as the second field after
147 * the header. This means the following structure is the supertype of
151 typedef struct StgMutClosure_ {
154 struct StgMutClosure_ *mut_link;
155 struct StgClosure_ *payload[0];
160 StgClosure *selectee;
167 StgClosure *payload[0];
174 StgClosure *payload[0];
179 StgClosure *literals; /* a pointer to an ArrWords */
180 StgClosure *instrs; /* a pointer to an ArrWords */
181 StgClosure *ptrs; /* a pointer to a MutArrPtrs */
186 StgClosure *indirectee;
191 StgClosure *indirectee;
192 StgMutClosure *mut_link;
197 StgClosure *indirectee;
198 StgClosure *static_link;
201 typedef struct StgCAF_ {
204 StgMutClosure *mut_link;
206 struct StgCAF_ *link;
218 StgMutClosure *mut_link; /* mutable list */
219 StgClosure *payload[0];
225 StgMutClosure *mut_link;
229 A collective typedef for all linkable stack frames i.e.
230 StgUpdateFrame, StgSeqFrame, StgCatchFrame
232 typedef struct _StgFrame {
234 struct _StgFrame *link;
237 typedef struct _StgUpdateFrame {
239 struct _StgUpdateFrame *link;
245 struct _StgUpdateFrame *link;
250 struct _StgUpdateFrame *link;
251 StgInt exceptions_blocked;
267 } StgIntCharlikeClosure;
269 /* statically allocated */
274 typedef struct _StgForeignObj {
276 StgAddr data; /* pointer to data in non-haskell-land */
279 typedef struct _StgStableName {
284 typedef struct _StgWeak { /* Weak v */
287 StgClosure *value; /* v */
288 StgClosure *finalizer;
289 struct _StgWeak *link;
292 typedef struct _StgDeadWeak { /* Weak v */
294 struct _StgWeak *link;
297 /* Dynamic stack frames - these have a liveness mask in the object
298 * itself, rather than in the info table. Useful for generic heap
303 const struct _StgInfoTable* info;
309 /* Concurrent communication objects */
313 struct StgTSO_ *head;
314 StgMutClosure *mut_link;
315 struct StgTSO_ *tail;
319 #if defined(PAR) || defined(GRAN)
321 StgBlockingQueueElement is a ``collective type'' representing the types
322 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
323 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
324 queue). Logically, this is a union type, but defining another struct
325 with a common layout is easier to handle in the code (same as for
327 Note that in the standard setup only StgTSOs can be on a blocking queue.
328 This is one of the main reasons for slightly different code in files
331 typedef struct StgBlockingQueueElement_ {
333 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
334 StgMutClosure *mut_link; /* next elem in mutable list */
335 struct StgClosure_ *payload[0];/* contents of the closure */
336 } StgBlockingQueueElement;
338 /* only difference to std code is type of the elem in the BQ */
339 typedef struct StgBlockingQueue_ {
341 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
342 StgMutClosure *mut_link; /* next elem in mutable list */
345 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
346 typedef struct StgRBHSave_ {
348 StgClosure *payload[0]; /* 2 words ripped out of the guts of the */
349 } StgRBHSave; /* closure holding the blocking queue */
351 typedef struct StgRBH_ {
353 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
354 StgMutClosure *mut_link; /* next elem in mutable list */
359 typedef struct StgBlockingQueue_ {
361 struct StgTSO_ *blocking_queue;
362 StgMutClosure *mut_link;
368 /* global indirections aka FETCH_ME closures */
369 typedef struct StgFetchMe_ {
371 globalAddr *ga; /* ptr to unique id for a closure */
372 StgMutClosure *mut_link; /* next elem in mutable list */
375 /* same contents as an ordinary StgBlockingQueue */
376 typedef struct StgFetchMeBlockingQueue_ {
378 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
379 StgMutClosure *mut_link; /* next elem in mutable list */
380 } StgFetchMeBlockingQueue;
382 /* This is an entry in a blocking queue. It indicates a fetch request from a
383 TSO on another PE demanding the value of this closur. Note that a
384 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
385 updated with the result, the result will be sent back (the PE is encoded
386 in the globalAddr) and the StgBlockedFetch closure will be nuked.
388 typedef struct StgBlockedFetch_ {
390 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
391 StgMutClosure *mut_link; /* next elem in mutable list */
392 StgClosure *node; /* node to fetch */
393 globalAddr ga; /* where to send the result to */
394 } StgBlockedFetch; /* NB: not just a ptr to a GA */
397 #endif /* CLOSURES_H */