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