1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.17 2000/03/31 03:09:35 hwloidl 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 */
140 typedef struct StgClosure_ {
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;
188 StgClosure *indirectee;
193 StgClosure *indirectee;
194 StgMutClosure *mut_link;
199 StgClosure *indirectee;
200 StgClosure *static_link;
203 typedef struct StgCAF_ {
206 StgMutClosure *mut_link;
208 struct StgCAF_ *link;
220 StgMutClosure *mut_link; /* mutable list */
221 StgClosure *payload[0];
227 StgMutClosure *mut_link;
231 A collective typedef for all linkable stack frames i.e.
232 StgUpdateFrame, StgSeqFrame, StgCatchFrame
234 typedef struct _StgFrame {
236 struct _StgFrame *link;
239 typedef struct _StgUpdateFrame {
241 struct _StgUpdateFrame *link;
247 struct _StgUpdateFrame *link;
252 struct _StgUpdateFrame *link;
253 StgInt exceptions_blocked;
269 } StgIntCharlikeClosure;
271 /* statically allocated */
276 typedef struct _StgForeignObj {
278 StgAddr data; /* pointer to data in non-haskell-land */
281 typedef struct _StgStableName {
286 typedef struct _StgWeak { /* Weak v */
289 StgClosure *value; /* v */
290 StgClosure *finalizer;
291 struct _StgWeak *link;
294 typedef struct _StgDeadWeak { /* Weak v */
296 struct _StgWeak *link;
299 /* Dynamic stack frames - these have a liveness mask in the object
300 * itself, rather than in the info table. Useful for generic heap
305 const struct _StgInfoTable* info;
311 /* Concurrent communication objects */
315 struct StgTSO_ *head;
316 StgMutClosure *mut_link;
317 struct StgTSO_ *tail;
321 #if defined(PAR) || defined(GRAN)
323 StgBlockingQueueElement is a ``collective type'' representing the types
324 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
325 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
326 queue). Logically, this is a union type, but defining another struct
327 with a common layout is easier to handle in the code (same as for
329 Note that in the standard setup only StgTSOs can be on a blocking queue.
330 This is one of the main reasons for slightly different code in files
333 typedef struct StgBlockingQueueElement_ {
335 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
336 StgMutClosure *mut_link; /* next elem in mutable list */
337 struct StgClosure_ *payload[0];/* contents of the closure */
338 } StgBlockingQueueElement;
340 /* only difference to std code is type of the elem in the BQ */
341 typedef struct StgBlockingQueue_ {
343 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
344 StgMutClosure *mut_link; /* next elem in mutable list */
347 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
348 typedef struct StgRBHSave_ {
350 StgPtr payload[0]; /* 2 words ripped out of the guts of the */
351 } StgRBHSave; /* closure holding the blocking queue */
353 typedef struct StgRBH_ {
355 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
356 StgMutClosure *mut_link; /* next elem in mutable list */
361 typedef struct StgBlockingQueue_ {
363 struct StgTSO_ *blocking_queue;
364 StgMutClosure *mut_link;
370 /* global indirections aka FETCH_ME closures */
371 typedef struct StgFetchMe_ {
373 globalAddr *ga; /* ptr to unique id for a closure */
374 StgMutClosure *mut_link; /* next elem in mutable list */
377 /* same contents as an ordinary StgBlockingQueue */
378 typedef struct StgFetchMeBlockingQueue_ {
380 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
381 StgMutClosure *mut_link; /* next elem in mutable list */
382 } StgFetchMeBlockingQueue;
384 /* This is an entry in a blocking queue. It indicates a fetch request from a
385 TSO on another PE demanding the value of this closur. Note that a
386 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
387 updated with the result, the result will be sent back (the PE is encoded
388 in the globalAddr) and the StgBlockedFetch closure will be nuked.
390 typedef struct StgBlockedFetch_ {
392 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
393 StgMutClosure *mut_link; /* next elem in mutable list */
394 StgClosure *node; /* node to fetch */
395 globalAddr ga; /* where to send the result to */
396 } StgBlockedFetch; /* NB: not just a ptr to a GA */
399 #endif /* CLOSURES_H */