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