[project @ 2000-01-18 12:36:38 by simonmar]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.16 2000/01/18 12:36:38 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 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 typedef struct _StgUpdateFrame {
231     StgHeader  header;
232     struct _StgUpdateFrame *link;
233     StgClosure *updatee;
234 } StgUpdateFrame;
235
236 typedef struct {
237     StgHeader  header;
238     struct _StgUpdateFrame *link;
239 } StgSeqFrame;  
240
241 typedef struct {
242     StgHeader  header;
243     struct _StgUpdateFrame *link;
244     StgInt      exceptions_blocked;
245     StgClosure *handler;
246 } StgCatchFrame;
247
248 typedef struct {
249     StgHeader  header;
250 } StgStopFrame;  
251
252 typedef struct {
253     StgHeader   header;
254     StgClosure *evacuee;
255 } StgEvacuated;
256
257 typedef struct {
258   StgHeader header;
259   StgWord data;
260 } StgIntCharlikeClosure;
261
262 /* statically allocated */
263 typedef struct {
264   StgHeader  header;
265 } StgRetry;
266
267 typedef struct _StgForeignObj {
268   StgHeader      header;
269   StgAddr        data;          /* pointer to data in non-haskell-land */
270 } StgForeignObj;
271   
272 typedef struct _StgStableName {
273   StgHeader      header;
274   StgWord        sn;
275 } StgStableName;
276
277 typedef struct _StgWeak {       /* Weak v */
278   StgHeader header;
279   StgClosure *key;
280   StgClosure *value;            /* v */
281   StgClosure *finalizer;
282   struct _StgWeak *link;
283 } StgWeak;
284
285 typedef struct _StgDeadWeak {   /* Weak v */
286   StgHeader header;
287   struct _StgWeak *link;
288 } StgDeadWeak;
289
290 /* Dynamic stack frames - these have a liveness mask in the object
291  * itself, rather than in the info table.  Useful for generic heap
292  * check code.
293  */
294  
295 typedef struct {
296   const struct _StgInfoTable* info;
297   StgWord        liveness;
298   StgWord        ret_addr;
299   StgWord        payload[0];
300 } StgRetDyn;
301
302 /* Concurrent communication objects */
303
304 typedef struct {
305   StgHeader       header;
306   struct StgTSO_ *head;
307   StgMutClosure  *mut_link;
308   struct StgTSO_ *tail;
309   StgClosure*     value;
310 } StgMVar;
311
312 #if defined(PAR) || defined(GRAN)
313 /*
314   StgBlockingQueueElement represents the types of closures that can be 
315   found on a blocking queue: StgTSO, StgRBHSave, StgBlockedFetch.
316   (StgRBHSave can only appear at the end of a blocking queue).  
317   Logically, this is a union type, but defining another struct with a common
318   layout is easier to handle in the code (same as for StgMutClosures).
319 */
320 typedef struct StgBlockingQueueElement_ {
321   StgHeader                         header;
322   struct StgBlockingQueueElement_  *link;
323   StgMutClosure                    *mut_link;
324   struct StgClosure_               *payload[0];
325 } StgBlockingQueueElement;
326
327 typedef struct StgBlockingQueue_ {
328   StgHeader                 header;
329   struct StgBlockingQueueElement_ *blocking_queue;
330   StgMutClosure            *mut_link;
331 } StgBlockingQueue;
332
333 /* this closure is hanging at the end of a blocking queue in (par setup only) */
334 typedef struct StgRBHSave_ {
335   StgHeader    header;
336   StgPtr       payload[0];
337 } StgRBHSave;
338
339 typedef struct StgRBH_ {
340   StgHeader                                header;
341   struct StgBlockingQueueElement_         *blocking_queue;
342   StgMutClosure                           *mut_link;
343 } StgRBH;
344
345 #else
346
347 typedef struct StgBlockingQueue_ {
348   StgHeader          header;
349   struct StgTSO_    *blocking_queue;
350   StgMutClosure     *mut_link;
351 } StgBlockingQueue;
352
353 #endif
354
355 #if defined(PAR)
356 /* global indirections aka FETCH_ME closures */
357 typedef struct StgFetchMe_ {
358   StgHeader              header;
359   globalAddr            *ga;            /* type globalAddr is abstract here */
360   StgMutClosure         *mut_link;
361 } StgFetchMe;
362
363 /* same contents as an ordinary StgBlockingQueue */
364 typedef struct StgFetchMeBlockingQueue_ {
365   StgHeader                          header;
366   struct StgBlockingQueueElement_   *blocking_queue;
367   StgMutClosure                     *mut_link;
368 } StgFetchMeBlockingQueue;
369
370 /* entry in a blocking queue, indicating a request from a TSO on another PE */
371 typedef struct StgBlockedFetch_ {
372   StgHeader                         header;
373   struct StgBlockingQueueElement_  *link;
374   StgMutClosure                    *mut_link;
375   StgClosure                       *node;
376   globalAddr                        ga;
377 } StgBlockedFetch;
378 #endif
379
380 #endif /* CLOSURES_H */