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