[project @ 2000-03-31 03:09:35 by hwloidl]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.17 2000/03/31 03:09:35 hwloidl 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 typedef struct StgClosure_ {
141     StgHeader   header;
142     struct StgClosure_ *payload[0];
143 } StgClosure;
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     StgPtr     *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     StgPtr      payload[0];
168 } StgPAP;
169
170 typedef struct {
171     StgHeader   header;
172     StgWord     n_args;
173     StgClosure *fun;
174     StgPtr      payload[0];
175 } StgAP_UPD;
176
177 typedef struct {
178     StgHeader  header;
179     StgWord    n_ptrs;
180     StgWord    n_words;
181     StgWord    n_instrs;
182     StgWord    stgexpr;
183     StgPtr     payload[0];
184 } StgBCO;
185
186 typedef struct {
187     StgHeader   header;
188     StgClosure *indirectee;
189 } StgInd;
190
191 typedef struct {
192     StgHeader   header;
193     StgClosure *indirectee;
194     StgMutClosure *mut_link;
195 } StgIndOldGen;
196
197 typedef struct {
198     StgHeader   header;
199     StgClosure *indirectee;
200     StgClosure *static_link;
201 } StgIndStatic;
202
203 typedef struct StgCAF_ {
204     StgHeader     header;
205     StgClosure    *body;
206     StgMutClosure *mut_link;
207     StgClosure    *value;
208     struct StgCAF_ *link;
209 } StgCAF;
210
211 typedef struct {
212     StgHeader  header;
213     StgWord    words;
214     StgWord    payload[0];
215 } StgArrWords;
216
217 typedef struct {
218     StgHeader   header;
219     StgWord     ptrs;
220     StgMutClosure *mut_link;    /* mutable list */
221     StgClosure *payload[0];
222 } StgMutArrPtrs;
223
224 typedef struct {
225     StgHeader   header;
226     StgClosure *var;
227     StgMutClosure *mut_link;
228 } StgMutVar;
229
230 /* 
231    A collective typedef for all linkable stack frames i.e.
232      StgUpdateFrame, StgSeqFrame, StgCatchFrame
233 */
234 typedef struct _StgFrame {
235     StgHeader  header;
236     struct _StgFrame *link;
237 } StgFrame;
238
239 typedef struct _StgUpdateFrame {
240     StgHeader  header;
241     struct _StgUpdateFrame *link;
242     StgClosure *updatee;
243 } StgUpdateFrame;
244
245 typedef struct {
246     StgHeader  header;
247     struct _StgUpdateFrame *link;
248 } StgSeqFrame;  
249
250 typedef struct {
251     StgHeader  header;
252     struct _StgUpdateFrame *link;
253     StgInt      exceptions_blocked;
254     StgClosure *handler;
255 } StgCatchFrame;
256
257 typedef struct {
258     StgHeader  header;
259 } StgStopFrame;  
260
261 typedef struct {
262     StgHeader   header;
263     StgClosure *evacuee;
264 } StgEvacuated;
265
266 typedef struct {
267   StgHeader header;
268   StgWord data;
269 } StgIntCharlikeClosure;
270
271 /* statically allocated */
272 typedef struct {
273   StgHeader  header;
274 } StgRetry;
275
276 typedef struct _StgForeignObj {
277   StgHeader      header;
278   StgAddr        data;          /* pointer to data in non-haskell-land */
279 } StgForeignObj;
280   
281 typedef struct _StgStableName {
282   StgHeader      header;
283   StgWord        sn;
284 } StgStableName;
285
286 typedef struct _StgWeak {       /* Weak v */
287   StgHeader header;
288   StgClosure *key;
289   StgClosure *value;            /* v */
290   StgClosure *finalizer;
291   struct _StgWeak *link;
292 } StgWeak;
293
294 typedef struct _StgDeadWeak {   /* Weak v */
295   StgHeader header;
296   struct _StgWeak *link;
297 } StgDeadWeak;
298
299 /* Dynamic stack frames - these have a liveness mask in the object
300  * itself, rather than in the info table.  Useful for generic heap
301  * check code.
302  */
303  
304 typedef struct {
305   const struct _StgInfoTable* info;
306   StgWord        liveness;
307   StgWord        ret_addr;
308   StgWord        payload[0];
309 } StgRetDyn;
310
311 /* Concurrent communication objects */
312
313 typedef struct {
314   StgHeader       header;
315   struct StgTSO_ *head;
316   StgMutClosure  *mut_link;
317   struct StgTSO_ *tail;
318   StgClosure*     value;
319 } StgMVar;
320
321 #if defined(PAR) || defined(GRAN)
322 /*
323   StgBlockingQueueElement is a ``collective type'' representing the types
324   of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
325   StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
326   queue).  Logically, this is a union type, but defining another struct
327   with a common layout is easier to handle in the code (same as for
328   StgMutClosures).  
329   Note that in the standard setup only StgTSOs can be on a blocking queue.
330   This is one of the main reasons for slightly different code in files
331   such as Schedule.c.
332 */
333 typedef struct StgBlockingQueueElement_ {
334   StgHeader                         header;
335   struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
336   StgMutClosure                    *mut_link;  /* next elem in mutable list */
337   struct StgClosure_               *payload[0];/* contents of the closure */
338 } StgBlockingQueueElement;
339
340 /* only difference to std code is type of the elem in the BQ */
341 typedef struct StgBlockingQueue_ {
342   StgHeader                 header;
343   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
344   StgMutClosure            *mut_link;              /* next elem in mutable list */
345 } StgBlockingQueue;
346
347 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
348 typedef struct StgRBHSave_ {
349   StgHeader    header;
350   StgPtr       payload[0];     /* 2 words ripped out of the guts of the */
351 } StgRBHSave;                  /*  closure holding the blocking queue */
352  
353 typedef struct StgRBH_ {
354   StgHeader                         header;
355   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
356   StgMutClosure                    *mut_link;       /* next elem in mutable list */
357 } StgRBH;
358
359 #else
360
361 typedef struct StgBlockingQueue_ {
362   StgHeader          header;
363   struct StgTSO_    *blocking_queue;
364   StgMutClosure     *mut_link;
365 } StgBlockingQueue;
366
367 #endif
368
369 #if defined(PAR)
370 /* global indirections aka FETCH_ME closures */
371 typedef struct StgFetchMe_ {
372   StgHeader              header;
373   globalAddr            *ga;        /* ptr to unique id for a closure */
374   StgMutClosure         *mut_link;  /* next elem in mutable list */
375 } StgFetchMe;
376
377 /* same contents as an ordinary StgBlockingQueue */
378 typedef struct StgFetchMeBlockingQueue_ {
379   StgHeader                          header;
380   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
381   StgMutClosure                     *mut_link;       /* next elem in mutable list */
382 } StgFetchMeBlockingQueue;
383
384 /* This is an entry in a blocking queue. It indicates a fetch request from a 
385    TSO on another PE demanding the value of this closur. Note that a
386    StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
387    updated with the result, the result will be sent back (the PE is encoded
388    in the globalAddr) and the StgBlockedFetch closure will be nuked.
389 */
390 typedef struct StgBlockedFetch_ {
391   StgHeader                         header;
392   struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
393   StgMutClosure                    *mut_link; /* next elem in mutable list */
394   StgClosure                       *node;     /* node to fetch */
395   globalAddr                        ga;       /* where to send the result to */
396 } StgBlockedFetch;                            /* NB: not just a ptr to a GA */
397 #endif
398
399 #endif /* CLOSURES_H */