Closures.h 10.6 KB
Newer Older
1
/* ----------------------------------------------------------------------------
2
 * $Id: Closures.h,v 1.23 2000/12/19 12:34:00 sewardj Exp $
3
4
 *
 * (c) The GHC Team, 1998-1999
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 *
 * Closures
 *
 * -------------------------------------------------------------------------- */

#ifndef CLOSURES_H
#define CLOSURES_H

/*
 * The Layout of a closure header depends on which kind of system we're
 * compiling for: profiling, parallel, ticky, etc.
 */

/* -----------------------------------------------------------------------------
   The profiling header
   -------------------------------------------------------------------------- */

#ifdef PROFILING

typedef struct {
   CostCentreStack *ccs;
} StgProfHeader;

#else /* !PROFILING */

typedef struct {
	/* empty */
} StgProfHeader;

#endif /* PROFILING */

/* -----------------------------------------------------------------------------
   The parallel header
   -------------------------------------------------------------------------- */

40
#ifdef PAR
41
42

typedef struct {
43
44
  /* StgWord ga; */  /* nope! global addresses are managed via a hash table */
} StgParHeader;
45
46
47
48
49

#else /* !PAR */

typedef struct {
  /* empty */
50
} StgParHeader;
51
52
53

#endif /* PAR */

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/* -----------------------------------------------------------------------------
   The GranSim header
   -------------------------------------------------------------------------- */

#if defined(GRAN)

typedef struct {
  StgWord procs; /* bitmask indicating on which PEs this closure resides */
} StgGranHeader;

#else /* !GRAN */

typedef struct {
  /* empty */
} StgGranHeader;

#endif /* GRAN */

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* -----------------------------------------------------------------------------
   The ticky-ticky header

   Comment from old Ticky.h:

   This is used to record if a closure has been updated but not yet
   entered. It is set when the closure is updated and cleared when
   subsequently entered.
   
   NB: It is {\em not} an ``entry count'', it is an
   ``entries-after-update count.''
   
   The commoning up of @CONST@, @CHARLIKE@ and @INTLIKE@ closures is
   turned off(?) if this is required. This has only been done for 2s
   collection.  It is done using a nasty hack which defines the
   @_Evacuate@ and @_Scavenge@ code for @CONST@, @CHARLIKE@ and @INTLIKE@
   info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
   -------------------------------------------------------------------------- */

91
#ifdef TICKY_TICKY
92
93

typedef struct {
94
  /* old: W_ updated; */
95
96
} StgTickyHeader;

97
#else /* !TICKY_TICKY */
98
99
100
101
102

typedef struct {
	/* empty */
} StgTickyHeader;

103
#endif /* TICKY_TICKY */
104
105
106
107
108
109
110
111
112
113

/* -----------------------------------------------------------------------------
   The full fixed-size closure header

   The size of the fixed header is the sum of the optional parts plus a single
   word for the entry code pointer.
   -------------------------------------------------------------------------- */

typedef struct {
	const struct _StgInfoTable* info;
sof's avatar
sof committed
114
#ifdef PROFILING
115
	StgProfHeader         prof;
sof's avatar
sof committed
116
#endif
117
118
119
#ifdef PAR
	StgParHeader          par;
#endif
120
#ifdef GRAN
121
	StgGranHeader         gran;
sof's avatar
sof committed
122
#endif
123
#ifdef TICKY_TICKY
124
	StgTickyHeader        ticky;
sof's avatar
sof committed
125
#endif
126
127
128
129
130
131
132
133
134
135
136
137
138
139
} StgHeader;

#define FIXED_HS (sizeof(StgHeader))

/* -----------------------------------------------------------------------------
   Closure Types

   For any given closure type (defined in InfoTables.h), there is a
   corresponding structure defined below.  The name of the structure
   is obtained by concatenating the closure type with '_closure'
   -------------------------------------------------------------------------- */

/* All closures follow the generic format */

140
struct StgClosure_ {
141
142
    StgHeader   header;
    struct StgClosure_ *payload[0];
143
};
144

145
146
147
148
149
150
151
152
/* What a stroke of luck - all our mutable closures follow the same
 * basic layout, with the mutable link field as the second field after
 * the header.  This means the following structure is the supertype of
 * mutable closures.
 */

typedef struct StgMutClosure_ {
    StgHeader   header;
153
    StgWord     padding;
154
155
156
157
    struct StgMutClosure_ *mut_link;
    struct StgClosure_ *payload[0];
} StgMutClosure;

158
159
160
161
162
163
164
165
166
typedef struct {
    StgHeader   header;
    StgClosure *selectee;
} StgSelector;

typedef struct {
    StgHeader   header;
    StgWord     n_args;
    StgClosure *fun;
167
    StgClosure *payload[0];
168
169
170
171
172
173
} StgPAP;

typedef struct {
    StgHeader   header;
    StgWord     n_args;
    StgClosure *fun;
174
    StgClosure *payload[0];
175
176
177
} StgAP_UPD;

typedef struct {
178
    StgHeader   header;
179
    StgClosure *instrs;		/* a pointer to an ArrWords */
180
    StgClosure *literals;	/* a pointer to an ArrWords */
181
    StgClosure *ptrs;		/* a pointer to a MutArrPtrs */
182
    StgClosure *itbls;		/* a pointer to an ArrWords */
183
184
185
186
187
188
189
190
191
192
} StgBCO;

typedef struct {
    StgHeader   header;
    StgClosure *indirectee;
} StgInd;

typedef struct {
    StgHeader   header;
    StgClosure *indirectee;
193
    StgMutClosure *mut_link;
194
195
196
197
198
199
200
201
202
} StgIndOldGen;

typedef struct {
    StgHeader   header;
    StgClosure *indirectee;
    StgClosure *static_link;
} StgIndStatic;

typedef struct StgCAF_ {
203
204
205
206
    StgHeader     header;
    StgClosure    *body;
    StgMutClosure *mut_link;
    StgClosure    *value;
207
208
209
210
211
212
213
214
215
216
217
218
    struct StgCAF_ *link;
} StgCAF;

typedef struct {
    StgHeader  header;
    StgWord    words;
    StgWord    payload[0];
} StgArrWords;

typedef struct {
    StgHeader   header;
    StgWord     ptrs;
219
    StgMutClosure *mut_link;	/* mutable list */
220
    StgClosure *payload[0];
221
} StgMutArrPtrs;
222
223
224
225

typedef struct {
    StgHeader   header;
    StgClosure *var;
226
    StgMutClosure *mut_link;
227
228
} StgMutVar;

229
230
231
232
233
234
235
236
237
/* 
   A collective typedef for all linkable stack frames i.e.
     StgUpdateFrame, StgSeqFrame, StgCatchFrame
*/
typedef struct _StgFrame {
    StgHeader  header;
    struct _StgFrame *link;
} StgFrame;

238
239
240
241
242
243
244
245
246
247
248
249
250
251
typedef struct _StgUpdateFrame {
    StgHeader  header;
    struct _StgUpdateFrame *link;
    StgClosure *updatee;
} StgUpdateFrame;

typedef struct {
    StgHeader  header;
    struct _StgUpdateFrame *link;
} StgSeqFrame;  

typedef struct {
    StgHeader  header;
    struct _StgUpdateFrame *link;
252
    StgInt      exceptions_blocked;
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    StgClosure *handler;
} StgCatchFrame;

typedef struct {
    StgHeader  header;
} StgStopFrame;  

typedef struct {
    StgHeader   header;
    StgClosure *evacuee;
} StgEvacuated;

typedef struct {
  StgHeader header;
  StgWord data;
} StgIntCharlikeClosure;

/* statically allocated */
typedef struct {
  StgHeader  header;
} StgRetry;

typedef struct _StgForeignObj {
  StgHeader      header;
  StgAddr        data;		/* pointer to data in non-haskell-land */
} StgForeignObj;
  
280
281
282
283
typedef struct _StgStableName {
  StgHeader      header;
  StgWord        sn;
} StgStableName;
284

285
286
287
288
typedef struct _StgWeak {	/* Weak v */
  StgHeader header;
  StgClosure *key;
  StgClosure *value;		/* v */
289
  StgClosure *finalizer;
290
291
292
  struct _StgWeak *link;
} StgWeak;

293
294
295
296
297
typedef struct _StgDeadWeak {	/* Weak v */
  StgHeader header;
  struct _StgWeak *link;
} StgDeadWeak;

298
299
300
301
302
303
/* Dynamic stack frames - these have a liveness mask in the object
 * itself, rather than in the info table.  Useful for generic heap
 * check code.
 */
 
typedef struct {
304
  const struct _StgInfoTable* info;
305
306
307
308
309
310
311
312
313
  StgWord        liveness;
  StgWord        ret_addr;
  StgWord        payload[0];
} StgRetDyn;

/* Concurrent communication objects */

typedef struct {
  StgHeader       header;
314
315
316
  struct StgTSO_ *head;
  StgMutClosure  *mut_link;
  struct StgTSO_ *tail;
317
318
319
  StgClosure*     value;
} StgMVar;

320
321
#if defined(PAR) || defined(GRAN)
/*
322
323
324
325
326
327
328
329
330
  StgBlockingQueueElement is a ``collective type'' representing the types
  of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
  StgBlockedFetch.  (StgRBHSave can only appear at the end of a blocking
  queue).  Logically, this is a union type, but defining another struct
  with a common layout is easier to handle in the code (same as for
  StgMutClosures).  
  Note that in the standard setup only StgTSOs can be on a blocking queue.
  This is one of the main reasons for slightly different code in files
  such as Schedule.c.
331
332
333
*/
typedef struct StgBlockingQueueElement_ {
  StgHeader                         header;
334
335
336
  struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
  StgMutClosure                    *mut_link;  /* next elem in mutable list */
  struct StgClosure_               *payload[0];/* contents of the closure */
337
338
} StgBlockingQueueElement;

339
/* only difference to std code is type of the elem in the BQ */
340
typedef struct StgBlockingQueue_ {
341
  StgHeader                 header;
342
343
  struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
  StgMutClosure            *mut_link;              /* next elem in mutable list */
344
345
} StgBlockingQueue;

346
/* this closure is hanging at the end of a blocking queue in (see RBH.c) */
347
typedef struct StgRBHSave_ {
348
  StgHeader    header;
349
  StgClosure  *payload[0];     /* 2 words ripped out of the guts of the */
350
351
} StgRBHSave;                  /*  closure holding the blocking queue */
 
352
typedef struct StgRBH_ {
353
354
355
  StgHeader                         header;
  struct StgBlockingQueueElement_  *blocking_queue; /* start of the BQ */
  StgMutClosure                    *mut_link;       /* next elem in mutable list */
356
357
358
} StgRBH;

#else
359

360
typedef struct StgBlockingQueue_ {
361
362
363
  StgHeader          header;
  struct StgTSO_    *blocking_queue;
  StgMutClosure     *mut_link;
364
} StgBlockingQueue;
365

366
367
368
369
370
371
#endif

#if defined(PAR)
/* global indirections aka FETCH_ME closures */
typedef struct StgFetchMe_ {
  StgHeader              header;
372
373
  globalAddr            *ga;        /* ptr to unique id for a closure */
  StgMutClosure         *mut_link;  /* next elem in mutable list */
374
} StgFetchMe;
375
376
377
378

/* same contents as an ordinary StgBlockingQueue */
typedef struct StgFetchMeBlockingQueue_ {
  StgHeader                          header;
379
380
  struct StgBlockingQueueElement_   *blocking_queue; /* start of the BQ */
  StgMutClosure                     *mut_link;       /* next elem in mutable list */
381
382
} StgFetchMeBlockingQueue;

383
384
385
386
387
388
/* This is an entry in a blocking queue. It indicates a fetch request from a 
   TSO on another PE demanding the value of this closur. Note that a
   StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
   updated with the result, the result will be sent back (the PE is encoded
   in the globalAddr) and the StgBlockedFetch closure will be nuked.
*/
389
390
typedef struct StgBlockedFetch_ {
  StgHeader                         header;
391
392
393
394
395
  struct StgBlockingQueueElement_  *link;     /* next elem in the BQ */
  StgMutClosure                    *mut_link; /* next elem in mutable list */
  StgClosure                       *node;     /* node to fetch */
  globalAddr                        ga;       /* where to send the result to */
} StgBlockedFetch;                            /* NB: not just a ptr to a GA */
396
397
398
#endif

#endif /* CLOSURES_H */