[project @ 2000-12-19 16:48:58 by sewardj]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.24 2000/12/19 16:48:58 sewardj 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     StgClosure *indirectee;
180 } StgInd;
181
182 typedef struct {
183     StgHeader   header;
184     StgClosure *indirectee;
185     StgMutClosure *mut_link;
186 } StgIndOldGen;
187
188 typedef struct {
189     StgHeader   header;
190     StgClosure *indirectee;
191     StgClosure *static_link;
192 } StgIndStatic;
193
194 typedef struct StgCAF_ {
195     StgHeader     header;
196     StgClosure    *body;
197     StgMutClosure *mut_link;
198     StgClosure    *value;
199     struct StgCAF_ *link;
200 } StgCAF;
201
202 typedef struct {
203     StgHeader  header;
204     StgWord    words;
205     StgWord    payload[0];
206 } StgArrWords;
207
208 typedef struct {
209     StgHeader   header;
210     StgWord     ptrs;
211     StgMutClosure *mut_link;    /* mutable list */
212     StgClosure *payload[0];
213 } StgMutArrPtrs;
214
215 typedef struct {
216     StgHeader   header;
217     StgClosure *var;
218     StgMutClosure *mut_link;
219 } StgMutVar;
220
221 typedef struct {
222     StgHeader      header;
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 */
227 } StgBCO;
228
229 /* 
230    A collective typedef for all linkable stack frames i.e.
231      StgUpdateFrame, StgSeqFrame, StgCatchFrame
232 */
233 typedef struct _StgFrame {
234     StgHeader  header;
235     struct _StgFrame *link;
236 } StgFrame;
237
238 typedef struct _StgUpdateFrame {
239     StgHeader  header;
240     struct _StgUpdateFrame *link;
241     StgClosure *updatee;
242 } StgUpdateFrame;
243
244 typedef struct {
245     StgHeader  header;
246     struct _StgUpdateFrame *link;
247 } StgSeqFrame;  
248
249 typedef struct {
250     StgHeader  header;
251     struct _StgUpdateFrame *link;
252     StgInt      exceptions_blocked;
253     StgClosure *handler;
254 } StgCatchFrame;
255
256 typedef struct {
257     StgHeader  header;
258 } StgStopFrame;  
259
260 typedef struct {
261     StgHeader   header;
262     StgClosure *evacuee;
263 } StgEvacuated;
264
265 typedef struct {
266   StgHeader header;
267   StgWord data;
268 } StgIntCharlikeClosure;
269
270 /* statically allocated */
271 typedef struct {
272   StgHeader  header;
273 } StgRetry;
274
275 typedef struct _StgForeignObj {
276   StgHeader      header;
277   StgAddr        data;          /* pointer to data in non-haskell-land */
278 } StgForeignObj;
279   
280 typedef struct _StgStableName {
281   StgHeader      header;
282   StgWord        sn;
283 } StgStableName;
284
285 typedef struct _StgWeak {       /* Weak v */
286   StgHeader header;
287   StgClosure *key;
288   StgClosure *value;            /* v */
289   StgClosure *finalizer;
290   struct _StgWeak *link;
291 } StgWeak;
292
293 typedef struct _StgDeadWeak {   /* Weak v */
294   StgHeader header;
295   struct _StgWeak *link;
296 } StgDeadWeak;
297
298 /* Dynamic stack frames - these have a liveness mask in the object
299  * itself, rather than in the info table.  Useful for generic heap
300  * check code.
301  */
302  
303 typedef struct {
304   const struct _StgInfoTable* info;
305   StgWord        liveness;
306   StgWord        ret_addr;
307   StgWord        payload[0];
308 } StgRetDyn;
309
310 /* Concurrent communication objects */
311
312 typedef struct {
313   StgHeader       header;
314   struct StgTSO_ *head;
315   StgMutClosure  *mut_link;
316   struct StgTSO_ *tail;
317   StgClosure*     value;
318 } StgMVar;
319
320 #if defined(PAR) || defined(GRAN)
321 /*
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
327   StgMutClosures).  
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
330   such as Schedule.c.
331 */
332 typedef struct StgBlockingQueueElement_ {
333   StgHeader                         header;
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;
338
339 /* only difference to std code is type of the elem in the BQ */
340 typedef struct StgBlockingQueue_ {
341   StgHeader                 header;
342   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
343   StgMutClosure            *mut_link;              /* next elem in mutable list */
344 } StgBlockingQueue;
345
346 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
347 typedef struct StgRBHSave_ {
348   StgHeader    header;
349   StgClosure  *payload[0];     /* 2 words ripped out of the guts of the */
350 } StgRBHSave;                  /*  closure holding the blocking queue */
351  
352 typedef struct StgRBH_ {
353   StgHeader                         header;
354   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
355   StgMutClosure                    *mut_link;       /* next elem in mutable list */
356 } StgRBH;
357
358 #else
359
360 typedef struct StgBlockingQueue_ {
361   StgHeader          header;
362   struct StgTSO_    *blocking_queue;
363   StgMutClosure     *mut_link;
364 } StgBlockingQueue;
365
366 #endif
367
368 #if defined(PAR)
369 /* global indirections aka FETCH_ME closures */
370 typedef struct StgFetchMe_ {
371   StgHeader              header;
372   globalAddr            *ga;        /* ptr to unique id for a closure */
373   StgMutClosure         *mut_link;  /* next elem in mutable list */
374 } StgFetchMe;
375
376 /* same contents as an ordinary StgBlockingQueue */
377 typedef struct StgFetchMeBlockingQueue_ {
378   StgHeader                          header;
379   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
380   StgMutClosure                     *mut_link;       /* next elem in mutable list */
381 } StgFetchMeBlockingQueue;
382
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.
388 */
389 typedef struct StgBlockedFetch_ {
390   StgHeader                         header;
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 */
396 #endif
397
398 #endif /* CLOSURES_H */