a94e23ab4f24ec792dbed704bb6148446232e4f5
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.20 2000/12/11 12:36:59 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Closures
7  *
8  * -------------------------------------------------------------------------- */
9
10 #ifndef CLOSURES_H
11 #define CLOSURES_H
12
13 /*
14  * The Layout of a closure header depends on which kind of system we're
15  * compiling for: profiling, parallel, ticky, etc.
16  */
17
18 /* -----------------------------------------------------------------------------
19    The profiling header
20    -------------------------------------------------------------------------- */
21
22 #ifdef PROFILING
23
24 typedef struct {
25    CostCentreStack *ccs;
26 } StgProfHeader;
27
28 #else /* !PROFILING */
29
30 typedef struct {
31         /* empty */
32 } StgProfHeader;
33
34 #endif /* PROFILING */
35
36 /* -----------------------------------------------------------------------------
37    The parallel header
38    -------------------------------------------------------------------------- */
39
40 #ifdef PAR
41
42 typedef struct {
43   /* StgWord ga; */  /* nope! global addresses are managed via a hash table */
44 } StgParHeader;
45
46 #else /* !PAR */
47
48 typedef struct {
49   /* empty */
50 } StgParHeader;
51
52 #endif /* PAR */
53
54 /* -----------------------------------------------------------------------------
55    The GranSim header
56    -------------------------------------------------------------------------- */
57
58 #if defined(GRAN)
59
60 typedef struct {
61   StgWord procs; /* bitmask indicating on which PEs this closure resides */
62 } StgGranHeader;
63
64 #else /* !GRAN */
65
66 typedef struct {
67   /* empty */
68 } StgGranHeader;
69
70 #endif /* GRAN */
71
72 /* -----------------------------------------------------------------------------
73    The ticky-ticky header
74
75    Comment from old Ticky.h:
76
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
79    subsequently entered.
80    
81    NB: It is {\em not} an ``entry count'', it is an
82    ``entries-after-update count.''
83    
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    -------------------------------------------------------------------------- */
90
91 #ifdef TICKY_TICKY
92
93 typedef struct {
94   /* old: W_ updated; */
95 } StgTickyHeader;
96
97 #else /* !TICKY_TICKY */
98
99 typedef struct {
100         /* empty */
101 } StgTickyHeader;
102
103 #endif /* TICKY_TICKY */
104
105 /* -----------------------------------------------------------------------------
106    The full fixed-size closure header
107
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    -------------------------------------------------------------------------- */
111
112 typedef struct {
113         const struct _StgInfoTable* info;
114 #ifdef PROFILING
115         StgProfHeader         prof;
116 #endif
117 #ifdef PAR
118         StgParHeader          par;
119 #endif
120 #ifdef GRAN
121         StgGranHeader         gran;
122 #endif
123 #ifdef TICKY_TICKY
124         StgTickyHeader        ticky;
125 #endif
126 } StgHeader;
127
128 #define FIXED_HS (sizeof(StgHeader))
129
130 /* -----------------------------------------------------------------------------
131    Closure Types
132
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    -------------------------------------------------------------------------- */
137
138 /* All closures follow the generic format */
139
140 struct StgClosure_ {
141     StgHeader   header;
142     struct StgClosure_ *payload[0];
143 };
144
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
148  * mutable closures.
149  */
150
151 typedef struct StgMutClosure_ {
152     StgHeader   header;
153     StgWord     padding;
154     struct StgMutClosure_ *mut_link;
155     struct StgClosure_ *payload[0];
156 } StgMutClosure;
157
158 typedef struct {
159     StgHeader   header;
160     StgClosure *selectee;
161 } StgSelector;
162
163 typedef struct {
164     StgHeader   header;
165     StgWord     n_args;
166     StgClosure *fun;
167     StgClosure *payload[0];
168 } StgPAP;
169
170 typedef struct {
171     StgHeader   header;
172     StgWord     n_args;
173     StgClosure *fun;
174     StgClosure *payload[0];
175 } StgAP_UPD;
176
177 typedef struct {
178     StgHeader   header;
179     StgPtr      literals;       /* a pointer to an ArrWords */
180     StgPtr      instrs;         /* a pointer to an ArrWords */
181     StgPtr      ptrs;           /* a pointer to a MutArrPtrs */
182 } StgBCO;
183
184 typedef struct {
185     StgHeader   header;
186     StgClosure *indirectee;
187 } StgInd;
188
189 typedef struct {
190     StgHeader   header;
191     StgClosure *indirectee;
192     StgMutClosure *mut_link;
193 } StgIndOldGen;
194
195 typedef struct {
196     StgHeader   header;
197     StgClosure *indirectee;
198     StgClosure *static_link;
199 } StgIndStatic;
200
201 typedef struct StgCAF_ {
202     StgHeader     header;
203     StgClosure    *body;
204     StgMutClosure *mut_link;
205     StgClosure    *value;
206     struct StgCAF_ *link;
207 } StgCAF;
208
209 typedef struct {
210     StgHeader  header;
211     StgWord    words;
212     StgWord    payload[0];
213 } StgArrWords;
214
215 typedef struct {
216     StgHeader   header;
217     StgWord     ptrs;
218     StgMutClosure *mut_link;    /* mutable list */
219     StgClosure *payload[0];
220 } StgMutArrPtrs;
221
222 typedef struct {
223     StgHeader   header;
224     StgClosure *var;
225     StgMutClosure *mut_link;
226 } StgMutVar;
227
228 /* 
229    A collective typedef for all linkable stack frames i.e.
230      StgUpdateFrame, StgSeqFrame, StgCatchFrame
231 */
232 typedef struct _StgFrame {
233     StgHeader  header;
234     struct _StgFrame *link;
235 } StgFrame;
236
237 typedef struct _StgUpdateFrame {
238     StgHeader  header;
239     struct _StgUpdateFrame *link;
240     StgClosure *updatee;
241 } StgUpdateFrame;
242
243 typedef struct {
244     StgHeader  header;
245     struct _StgUpdateFrame *link;
246 } StgSeqFrame;  
247
248 typedef struct {
249     StgHeader  header;
250     struct _StgUpdateFrame *link;
251     StgInt      exceptions_blocked;
252     StgClosure *handler;
253 } StgCatchFrame;
254
255 typedef struct {
256     StgHeader  header;
257 } StgStopFrame;  
258
259 typedef struct {
260     StgHeader   header;
261     StgClosure *evacuee;
262 } StgEvacuated;
263
264 typedef struct {
265   StgHeader header;
266   StgWord data;
267 } StgIntCharlikeClosure;
268
269 /* statically allocated */
270 typedef struct {
271   StgHeader  header;
272 } StgRetry;
273
274 typedef struct _StgForeignObj {
275   StgHeader      header;
276   StgAddr        data;          /* pointer to data in non-haskell-land */
277 } StgForeignObj;
278   
279 typedef struct _StgStableName {
280   StgHeader      header;
281   StgWord        sn;
282 } StgStableName;
283
284 typedef struct _StgWeak {       /* Weak v */
285   StgHeader header;
286   StgClosure *key;
287   StgClosure *value;            /* v */
288   StgClosure *finalizer;
289   struct _StgWeak *link;
290 } StgWeak;
291
292 typedef struct _StgDeadWeak {   /* Weak v */
293   StgHeader header;
294   struct _StgWeak *link;
295 } StgDeadWeak;
296
297 /* Dynamic stack frames - these have a liveness mask in the object
298  * itself, rather than in the info table.  Useful for generic heap
299  * check code.
300  */
301  
302 typedef struct {
303   const struct _StgInfoTable* info;
304   StgWord        liveness;
305   StgWord        ret_addr;
306   StgWord        payload[0];
307 } StgRetDyn;
308
309 /* Concurrent communication objects */
310
311 typedef struct {
312   StgHeader       header;
313   struct StgTSO_ *head;
314   StgMutClosure  *mut_link;
315   struct StgTSO_ *tail;
316   StgClosure*     value;
317 } StgMVar;
318
319 #if defined(PAR) || defined(GRAN)
320 /*
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
326   StgMutClosures).  
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
329   such as Schedule.c.
330 */
331 typedef struct StgBlockingQueueElement_ {
332   StgHeader                         header;
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;
337
338 /* only difference to std code is type of the elem in the BQ */
339 typedef struct StgBlockingQueue_ {
340   StgHeader                 header;
341   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
342   StgMutClosure            *mut_link;              /* next elem in mutable list */
343 } StgBlockingQueue;
344
345 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
346 typedef struct StgRBHSave_ {
347   StgHeader    header;
348   StgClosure  *payload[0];     /* 2 words ripped out of the guts of the */
349 } StgRBHSave;                  /*  closure holding the blocking queue */
350  
351 typedef struct StgRBH_ {
352   StgHeader                         header;
353   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
354   StgMutClosure                    *mut_link;       /* next elem in mutable list */
355 } StgRBH;
356
357 #else
358
359 typedef struct StgBlockingQueue_ {
360   StgHeader          header;
361   struct StgTSO_    *blocking_queue;
362   StgMutClosure     *mut_link;
363 } StgBlockingQueue;
364
365 #endif
366
367 #if defined(PAR)
368 /* global indirections aka FETCH_ME closures */
369 typedef struct StgFetchMe_ {
370   StgHeader              header;
371   globalAddr            *ga;        /* ptr to unique id for a closure */
372   StgMutClosure         *mut_link;  /* next elem in mutable list */
373 } StgFetchMe;
374
375 /* same contents as an ordinary StgBlockingQueue */
376 typedef struct StgFetchMeBlockingQueue_ {
377   StgHeader                          header;
378   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
379   StgMutClosure                     *mut_link;       /* next elem in mutable list */
380 } StgFetchMeBlockingQueue;
381
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.
387 */
388 typedef struct StgBlockedFetch_ {
389   StgHeader                         header;
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 */
395 #endif
396
397 #endif /* CLOSURES_H */