[project @ 2001-10-03 13:57:42 by simonmar]
[ghc-hetmet.git] / ghc / includes / Closures.h
1 /* ----------------------------------------------------------------------------
2  * $Id: Closures.h,v 1.28 2001/10/03 13:57:42 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 typedef struct {
23    CostCentreStack *ccs;
24 } StgProfHeader;
25
26 /* -----------------------------------------------------------------------------
27    The parallel header
28    -------------------------------------------------------------------------- */
29
30 typedef struct {
31   /* StgWord ga; */  /* nope! global addresses are managed via a hash table */
32 } StgParHeader;
33
34 /* -----------------------------------------------------------------------------
35    The GranSim header
36    -------------------------------------------------------------------------- */
37
38 typedef struct {
39   StgWord procs; /* bitmask indicating on which PEs this closure resides */
40 } StgGranHeader;
41
42 /* -----------------------------------------------------------------------------
43    The ticky-ticky header
44
45    Comment from old Ticky.h:
46
47    This is used to record if a closure has been updated but not yet
48    entered. It is set when the closure is updated and cleared when
49    subsequently entered.
50    
51    NB: It is {\em not} an ``entry count'', it is an
52    ``entries-after-update count.''
53    
54    The commoning up of @CONST@, @CHARLIKE@ and @INTLIKE@ closures is
55    turned off(?) if this is required. This has only been done for 2s
56    collection.  It is done using a nasty hack which defines the
57    @_Evacuate@ and @_Scavenge@ code for @CONST@, @CHARLIKE@ and @INTLIKE@
58    info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
59    -------------------------------------------------------------------------- */
60
61 typedef struct {
62   /* old: W_ updated; */
63 } StgTickyHeader;
64
65 /* -----------------------------------------------------------------------------
66    The full fixed-size closure header
67
68    The size of the fixed header is the sum of the optional parts plus a single
69    word for the entry code pointer.
70    -------------------------------------------------------------------------- */
71
72 typedef struct {
73         const struct _StgInfoTable* info;
74 #ifdef PROFILING
75         StgProfHeader         prof;
76 #endif
77 #ifdef PAR
78         StgParHeader          par;
79 #endif
80 #ifdef GRAN
81         StgGranHeader         gran;
82 #endif
83 #ifdef TICKY_TICKY
84         StgTickyHeader        ticky;
85 #endif
86 } StgHeader;
87
88 #define FIXED_HS (sizeof(StgHeader))
89
90 /* -----------------------------------------------------------------------------
91    Closure Types
92
93    For any given closure type (defined in InfoTables.h), there is a
94    corresponding structure defined below.  The name of the structure
95    is obtained by concatenating the closure type with '_closure'
96    -------------------------------------------------------------------------- */
97
98 /* All closures follow the generic format */
99
100 struct StgClosure_ {
101     StgHeader   header;
102     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
103 };
104
105 /* What a stroke of luck - all our mutable closures follow the same
106  * basic layout, with the mutable link field as the second field after
107  * the header.  This means the following structure is the supertype of
108  * mutable closures.
109  */
110
111 typedef struct StgMutClosure_ {
112     StgHeader   header;
113     StgWord     padding;
114     struct StgMutClosure_ *mut_link;
115     struct StgClosure_ *payload[FLEXIBLE_ARRAY];
116 } StgMutClosure;
117
118 typedef struct {
119     StgHeader   header;
120     StgClosure *selectee;
121 } StgSelector;
122
123 typedef struct {
124     StgHeader   header;
125     StgWord     n_args;
126     StgClosure *fun;
127     StgClosure *payload[FLEXIBLE_ARRAY];
128 } StgPAP;
129
130 typedef struct {
131     StgHeader   header;
132     StgWord     n_args;
133     StgClosure *fun;
134     StgClosure *payload[FLEXIBLE_ARRAY];
135 } StgAP_UPD;
136
137 typedef struct {
138     StgHeader   header;
139     StgClosure *indirectee;
140 } StgInd;
141
142 typedef struct {
143     StgHeader   header;
144     StgClosure *indirectee;
145     StgMutClosure *mut_link;
146 } StgIndOldGen;
147
148 typedef struct {
149     StgHeader     header;
150     StgClosure   *indirectee;
151     StgClosure   *static_link;
152     struct _StgInfoTable *saved_info;
153 } StgIndStatic;
154
155 typedef struct {
156     StgHeader  header;
157     StgWord    words;
158     StgWord    payload[FLEXIBLE_ARRAY];
159 } StgArrWords;
160
161 typedef struct {
162     StgHeader   header;
163     StgWord     ptrs;
164     StgMutClosure *mut_link;    /* mutable list */
165     StgClosure *payload[FLEXIBLE_ARRAY];
166 } StgMutArrPtrs;
167
168 typedef struct {
169     StgHeader   header;
170     StgClosure *var;
171     StgMutClosure *mut_link;
172 } StgMutVar;
173
174 typedef struct {
175     StgHeader      header;
176     StgArrWords   *instrs;      /* a pointer to an ArrWords */
177     StgArrWords   *literals;    /* a pointer to an ArrWords */
178     StgMutArrPtrs *ptrs;        /* a pointer to a MutArrPtrs */
179     StgArrWords   *itbls;       /* a pointer to an ArrWords */
180 } StgBCO;
181
182 /* 
183    A collective typedef for all linkable stack frames i.e.
184      StgUpdateFrame, StgSeqFrame, StgCatchFrame
185 */
186 typedef struct _StgFrame {
187     StgHeader  header;
188     struct _StgFrame *link;
189 } StgFrame;
190
191 typedef struct _StgUpdateFrame {
192     StgHeader  header;
193     struct _StgUpdateFrame *link;
194     StgClosure *updatee;
195 } StgUpdateFrame;
196
197 typedef struct {
198     StgHeader  header;
199     struct _StgUpdateFrame *link;
200 } StgSeqFrame;  
201
202 typedef struct {
203     StgHeader  header;
204     struct _StgUpdateFrame *link;
205     StgInt      exceptions_blocked;
206     StgClosure *handler;
207 } StgCatchFrame;
208
209 typedef struct {
210     StgHeader  header;
211 } StgStopFrame;  
212
213 typedef struct {
214     StgHeader   header;
215     StgClosure *evacuee;
216 } StgEvacuated;
217
218 typedef struct {
219   StgHeader header;
220   StgWord data;
221 } StgIntCharlikeClosure;
222
223 /* statically allocated */
224 typedef struct {
225   StgHeader  header;
226 } StgRetry;
227
228 typedef struct _StgForeignObj {
229   StgHeader      header;
230   StgAddr        data;          /* pointer to data in non-haskell-land */
231 } StgForeignObj;
232   
233 typedef struct _StgStableName {
234   StgHeader      header;
235   StgWord        sn;
236 } StgStableName;
237
238 typedef struct _StgWeak {       /* Weak v */
239   StgHeader header;
240   StgClosure *key;
241   StgClosure *value;            /* v */
242   StgClosure *finalizer;
243   struct _StgWeak *link;
244 } StgWeak;
245
246 typedef struct _StgDeadWeak {   /* Weak v */
247   StgHeader header;
248   struct _StgWeak *link;
249 } StgDeadWeak;
250
251 /* Dynamic stack frames - these have a liveness mask in the object
252  * itself, rather than in the info table.  Useful for generic heap
253  * check code.
254  */
255  
256 typedef struct {
257   const struct _StgInfoTable* info;
258   StgWord        liveness;
259   StgWord        ret_addr;
260   StgWord        payload[FLEXIBLE_ARRAY];
261 } StgRetDyn;
262
263 /* Concurrent communication objects */
264
265 typedef struct {
266   StgHeader       header;
267   struct StgTSO_ *head;
268   StgMutClosure  *mut_link;
269   struct StgTSO_ *tail;
270   StgClosure*     value;
271 } StgMVar;
272
273 #if defined(PAR) || defined(GRAN)
274 /*
275   StgBlockingQueueElement is a ``collective type'' representing the types
276   of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
277   StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
278   queue).  Logically, this is a union type, but defining another struct
279   with a common layout is easier to handle in the code (same as for
280   StgMutClosures).  
281   Note that in the standard setup only StgTSOs can be on a blocking queue.
282   This is one of the main reasons for slightly different code in files
283   such as Schedule.c.
284 */
285 typedef struct StgBlockingQueueElement_ {
286   StgHeader                         header;
287   struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
288   StgMutClosure                    *mut_link;  /* next elem in mutable list */
289   struct StgClosure_               *payload[FLEXIBLE_ARRAY];/* contents of the closure */
290 } StgBlockingQueueElement;
291
292 /* only difference to std code is type of the elem in the BQ */
293 typedef struct StgBlockingQueue_ {
294   StgHeader                 header;
295   struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
296   StgMutClosure            *mut_link;              /* next elem in mutable list */
297 } StgBlockingQueue;
298
299 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
300 typedef struct StgRBHSave_ {
301   StgHeader    header;
302   StgClosure  *payload[FLEXIBLE_ARRAY];     /* 2 words ripped out of the guts of the */
303 } StgRBHSave;                  /*  closure holding the blocking queue */
304  
305 typedef struct StgRBH_ {
306   StgHeader                         header;
307   struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
308   StgMutClosure                    *mut_link;       /* next elem in mutable list */
309 } StgRBH;
310
311 #else
312
313 typedef struct StgBlockingQueue_ {
314   StgHeader          header;
315   struct StgTSO_    *blocking_queue;
316   StgMutClosure     *mut_link;
317 } StgBlockingQueue;
318
319 #endif
320
321 #if defined(PAR)
322 /* global indirections aka FETCH_ME closures */
323 typedef struct StgFetchMe_ {
324   StgHeader              header;
325   globalAddr            *ga;        /* ptr to unique id for a closure */
326   StgMutClosure         *mut_link;  /* next elem in mutable list */
327 } StgFetchMe;
328
329 /* same contents as an ordinary StgBlockingQueue */
330 typedef struct StgFetchMeBlockingQueue_ {
331   StgHeader                          header;
332   struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
333   StgMutClosure                     *mut_link;       /* next elem in mutable list */
334 } StgFetchMeBlockingQueue;
335
336 /* This is an entry in a blocking queue. It indicates a fetch request from a 
337    TSO on another PE demanding the value of this closur. Note that a
338    StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
339    updated with the result, the result will be sent back (the PE is encoded
340    in the globalAddr) and the StgBlockedFetch closure will be nuked.
341 */
342 typedef struct StgBlockedFetch_ {
343   StgHeader                         header;
344   struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
345   StgMutClosure                    *mut_link; /* next elem in mutable list */
346   StgClosure                       *node;     /* node to fetch */
347   globalAddr                        ga;       /* where to send the result to */
348 } StgBlockedFetch;                            /* NB: not just a ptr to a GA */
349 #endif
350
351 #endif /* CLOSURES_H */