1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.26 2001/02/11 17:51:08 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 *indirectee;
184 StgClosure *indirectee;
185 StgMutClosure *mut_link;
190 StgClosure *indirectee;
191 StgClosure *static_link;
192 struct _StgInfoTable *saved_info;
204 StgMutClosure *mut_link; /* mutable list */
205 StgClosure *payload[0];
211 StgMutClosure *mut_link;
216 StgArrWords *instrs; /* a pointer to an ArrWords */
217 StgArrWords *literals; /* a pointer to an ArrWords */
218 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
219 StgArrWords *itbls; /* a pointer to an ArrWords */
223 A collective typedef for all linkable stack frames i.e.
224 StgUpdateFrame, StgSeqFrame, StgCatchFrame
226 typedef struct _StgFrame {
228 struct _StgFrame *link;
231 typedef struct _StgUpdateFrame {
233 struct _StgUpdateFrame *link;
239 struct _StgUpdateFrame *link;
244 struct _StgUpdateFrame *link;
245 StgInt exceptions_blocked;
261 } StgIntCharlikeClosure;
263 /* statically allocated */
268 typedef struct _StgForeignObj {
270 StgAddr data; /* pointer to data in non-haskell-land */
273 typedef struct _StgStableName {
278 typedef struct _StgWeak { /* Weak v */
281 StgClosure *value; /* v */
282 StgClosure *finalizer;
283 struct _StgWeak *link;
286 typedef struct _StgDeadWeak { /* Weak v */
288 struct _StgWeak *link;
291 /* Dynamic stack frames - these have a liveness mask in the object
292 * itself, rather than in the info table. Useful for generic heap
297 const struct _StgInfoTable* info;
303 /* Concurrent communication objects */
307 struct StgTSO_ *head;
308 StgMutClosure *mut_link;
309 struct StgTSO_ *tail;
313 #if defined(PAR) || defined(GRAN)
315 StgBlockingQueueElement is a ``collective type'' representing the types
316 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
317 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
318 queue). Logically, this is a union type, but defining another struct
319 with a common layout is easier to handle in the code (same as for
321 Note that in the standard setup only StgTSOs can be on a blocking queue.
322 This is one of the main reasons for slightly different code in files
325 typedef struct StgBlockingQueueElement_ {
327 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
328 StgMutClosure *mut_link; /* next elem in mutable list */
329 struct StgClosure_ *payload[0];/* contents of the closure */
330 } StgBlockingQueueElement;
332 /* only difference to std code is type of the elem in the BQ */
333 typedef struct StgBlockingQueue_ {
335 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
336 StgMutClosure *mut_link; /* next elem in mutable list */
339 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
340 typedef struct StgRBHSave_ {
342 StgClosure *payload[0]; /* 2 words ripped out of the guts of the */
343 } StgRBHSave; /* closure holding the blocking queue */
345 typedef struct StgRBH_ {
347 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
348 StgMutClosure *mut_link; /* next elem in mutable list */
353 typedef struct StgBlockingQueue_ {
355 struct StgTSO_ *blocking_queue;
356 StgMutClosure *mut_link;
362 /* global indirections aka FETCH_ME closures */
363 typedef struct StgFetchMe_ {
365 globalAddr *ga; /* ptr to unique id for a closure */
366 StgMutClosure *mut_link; /* next elem in mutable list */
369 /* same contents as an ordinary StgBlockingQueue */
370 typedef struct StgFetchMeBlockingQueue_ {
372 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
373 StgMutClosure *mut_link; /* next elem in mutable list */
374 } StgFetchMeBlockingQueue;
376 /* This is an entry in a blocking queue. It indicates a fetch request from a
377 TSO on another PE demanding the value of this closur. Note that a
378 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
379 updated with the result, the result will be sent back (the PE is encoded
380 in the globalAddr) and the StgBlockedFetch closure will be nuked.
382 typedef struct StgBlockedFetch_ {
384 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
385 StgMutClosure *mut_link; /* next elem in mutable list */
386 StgClosure *node; /* node to fetch */
387 globalAddr ga; /* where to send the result to */
388 } StgBlockedFetch; /* NB: not just a ptr to a GA */
391 #endif /* CLOSURES_H */