1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.24 2000/12/19 16:48:58 sewardj 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;
194 typedef struct StgCAF_ {
197 StgMutClosure *mut_link;
199 struct StgCAF_ *link;
211 StgMutClosure *mut_link; /* mutable list */
212 StgClosure *payload[0];
218 StgMutClosure *mut_link;
223 StgArrWords *instrs; /* a pointer to an ArrWords */
224 StgArrWords *literals; /* a pointer to an ArrWords */
225 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
226 StgArrWords *itbls; /* a pointer to an ArrWords */
230 A collective typedef for all linkable stack frames i.e.
231 StgUpdateFrame, StgSeqFrame, StgCatchFrame
233 typedef struct _StgFrame {
235 struct _StgFrame *link;
238 typedef struct _StgUpdateFrame {
240 struct _StgUpdateFrame *link;
246 struct _StgUpdateFrame *link;
251 struct _StgUpdateFrame *link;
252 StgInt exceptions_blocked;
268 } StgIntCharlikeClosure;
270 /* statically allocated */
275 typedef struct _StgForeignObj {
277 StgAddr data; /* pointer to data in non-haskell-land */
280 typedef struct _StgStableName {
285 typedef struct _StgWeak { /* Weak v */
288 StgClosure *value; /* v */
289 StgClosure *finalizer;
290 struct _StgWeak *link;
293 typedef struct _StgDeadWeak { /* Weak v */
295 struct _StgWeak *link;
298 /* Dynamic stack frames - these have a liveness mask in the object
299 * itself, rather than in the info table. Useful for generic heap
304 const struct _StgInfoTable* info;
310 /* Concurrent communication objects */
314 struct StgTSO_ *head;
315 StgMutClosure *mut_link;
316 struct StgTSO_ *tail;
320 #if defined(PAR) || defined(GRAN)
322 StgBlockingQueueElement is a ``collective type'' representing the types
323 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
324 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
325 queue). Logically, this is a union type, but defining another struct
326 with a common layout is easier to handle in the code (same as for
328 Note that in the standard setup only StgTSOs can be on a blocking queue.
329 This is one of the main reasons for slightly different code in files
332 typedef struct StgBlockingQueueElement_ {
334 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
335 StgMutClosure *mut_link; /* next elem in mutable list */
336 struct StgClosure_ *payload[0];/* contents of the closure */
337 } StgBlockingQueueElement;
339 /* only difference to std code is type of the elem in the BQ */
340 typedef struct StgBlockingQueue_ {
342 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
343 StgMutClosure *mut_link; /* next elem in mutable list */
346 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
347 typedef struct StgRBHSave_ {
349 StgClosure *payload[0]; /* 2 words ripped out of the guts of the */
350 } StgRBHSave; /* closure holding the blocking queue */
352 typedef struct StgRBH_ {
354 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
355 StgMutClosure *mut_link; /* next elem in mutable list */
360 typedef struct StgBlockingQueue_ {
362 struct StgTSO_ *blocking_queue;
363 StgMutClosure *mut_link;
369 /* global indirections aka FETCH_ME closures */
370 typedef struct StgFetchMe_ {
372 globalAddr *ga; /* ptr to unique id for a closure */
373 StgMutClosure *mut_link; /* next elem in mutable list */
376 /* same contents as an ordinary StgBlockingQueue */
377 typedef struct StgFetchMeBlockingQueue_ {
379 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
380 StgMutClosure *mut_link; /* next elem in mutable list */
381 } StgFetchMeBlockingQueue;
383 /* This is an entry in a blocking queue. It indicates a fetch request from a
384 TSO on another PE demanding the value of this closur. Note that a
385 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
386 updated with the result, the result will be sent back (the PE is encoded
387 in the globalAddr) and the StgBlockedFetch closure will be nuked.
389 typedef struct StgBlockedFetch_ {
391 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
392 StgMutClosure *mut_link; /* next elem in mutable list */
393 StgClosure *node; /* node to fetch */
394 globalAddr ga; /* where to send the result to */
395 } StgBlockedFetch; /* NB: not just a ptr to a GA */
398 #endif /* CLOSURES_H */