1 /* ----------------------------------------------------------------------------
2 * $Id: Closures.h,v 1.25 2001/01/29 17:23:41 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;
193 struct _StgInfoTable *saved_info;
206 StgMutClosure *mut_link; /* mutable list */
207 StgClosure *payload[0];
213 StgMutClosure *mut_link;
218 StgArrWords *instrs; /* a pointer to an ArrWords */
219 StgArrWords *literals; /* a pointer to an ArrWords */
220 StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
221 StgArrWords *itbls; /* a pointer to an ArrWords */
225 A collective typedef for all linkable stack frames i.e.
226 StgUpdateFrame, StgSeqFrame, StgCatchFrame
228 typedef struct _StgFrame {
230 struct _StgFrame *link;
233 typedef struct _StgUpdateFrame {
235 struct _StgUpdateFrame *link;
241 struct _StgUpdateFrame *link;
246 struct _StgUpdateFrame *link;
247 StgInt exceptions_blocked;
263 } StgIntCharlikeClosure;
265 /* statically allocated */
270 typedef struct _StgForeignObj {
272 StgAddr data; /* pointer to data in non-haskell-land */
275 typedef struct _StgStableName {
280 typedef struct _StgWeak { /* Weak v */
283 StgClosure *value; /* v */
284 StgClosure *finalizer;
285 struct _StgWeak *link;
288 typedef struct _StgDeadWeak { /* Weak v */
290 struct _StgWeak *link;
293 /* Dynamic stack frames - these have a liveness mask in the object
294 * itself, rather than in the info table. Useful for generic heap
299 const struct _StgInfoTable* info;
305 /* Concurrent communication objects */
309 struct StgTSO_ *head;
310 StgMutClosure *mut_link;
311 struct StgTSO_ *tail;
315 #if defined(PAR) || defined(GRAN)
317 StgBlockingQueueElement is a ``collective type'' representing the types
318 of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
319 StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
320 queue). Logically, this is a union type, but defining another struct
321 with a common layout is easier to handle in the code (same as for
323 Note that in the standard setup only StgTSOs can be on a blocking queue.
324 This is one of the main reasons for slightly different code in files
327 typedef struct StgBlockingQueueElement_ {
329 struct StgBlockingQueueElement_ *link; /* next elem in BQ */
330 StgMutClosure *mut_link; /* next elem in mutable list */
331 struct StgClosure_ *payload[0];/* contents of the closure */
332 } StgBlockingQueueElement;
334 /* only difference to std code is type of the elem in the BQ */
335 typedef struct StgBlockingQueue_ {
337 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
338 StgMutClosure *mut_link; /* next elem in mutable list */
341 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
342 typedef struct StgRBHSave_ {
344 StgClosure *payload[0]; /* 2 words ripped out of the guts of the */
345 } StgRBHSave; /* closure holding the blocking queue */
347 typedef struct StgRBH_ {
349 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
350 StgMutClosure *mut_link; /* next elem in mutable list */
355 typedef struct StgBlockingQueue_ {
357 struct StgTSO_ *blocking_queue;
358 StgMutClosure *mut_link;
364 /* global indirections aka FETCH_ME closures */
365 typedef struct StgFetchMe_ {
367 globalAddr *ga; /* ptr to unique id for a closure */
368 StgMutClosure *mut_link; /* next elem in mutable list */
371 /* same contents as an ordinary StgBlockingQueue */
372 typedef struct StgFetchMeBlockingQueue_ {
374 struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
375 StgMutClosure *mut_link; /* next elem in mutable list */
376 } StgFetchMeBlockingQueue;
378 /* This is an entry in a blocking queue. It indicates a fetch request from a
379 TSO on another PE demanding the value of this closur. Note that a
380 StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
381 updated with the result, the result will be sent back (the PE is encoded
382 in the globalAddr) and the StgBlockedFetch closure will be nuked.
384 typedef struct StgBlockedFetch_ {
386 struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
387 StgMutClosure *mut_link; /* next elem in mutable list */
388 StgClosure *node; /* node to fetch */
389 globalAddr ga; /* where to send the result to */
390 } StgBlockedFetch; /* NB: not just a ptr to a GA */
393 #endif /* CLOSURES_H */