Prefer #if defined to #ifdef
[ghc.git] / includes / rts / storage / InfoTables.h
1 /* ----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2002
4 *
5 * Info Tables
6 *
7 * -------------------------------------------------------------------------- */
8
9 #pragma once
10
11 /* ----------------------------------------------------------------------------
12 Relative pointers
13
14 Several pointer fields in info tables are expressed as offsets
15 relative to the info pointer, so that we can generate
16 position-independent code.
17
18 Note [x86-64-relative]
19 There is a complication on the x86_64 platform, where pointers are
20 64 bits, but the tools don't support 64-bit relative relocations.
21 However, the default memory model (small) ensures that all symbols
22 have values in the lower 2Gb of the address space, so offsets all
23 fit in 32 bits. Hence we can use 32-bit offset fields.
24
25 Somewhere between binutils-2.16.1 and binutils-2.16.91.0.6,
26 support for 64-bit PC-relative relocations was added, so maybe this
27 hackery can go away sometime.
28 ------------------------------------------------------------------------- */
29
30 #if defined(x86_64_TARGET_ARCH)
31 #define OFFSET_FIELD(n) StgHalfInt n; StgHalfWord __pad_##n
32 #else
33 #define OFFSET_FIELD(n) StgInt n
34 #endif
35
36 /* -----------------------------------------------------------------------------
37 Profiling info
38 -------------------------------------------------------------------------- */
39
40 typedef struct {
41 #if !defined(TABLES_NEXT_TO_CODE)
42 char *closure_type;
43 char *closure_desc;
44 #else
45 OFFSET_FIELD(closure_type_off);
46 OFFSET_FIELD(closure_desc_off);
47 #endif
48 } StgProfInfo;
49
50 /* -----------------------------------------------------------------------------
51 Closure flags
52 -------------------------------------------------------------------------- */
53
54 /* The type flags provide quick access to certain properties of a closure. */
55
56 #define _HNF (1<<0) /* head normal form? */
57 #define _BTM (1<<1) /* uses info->layout.bitmap */
58 #define _NS (1<<2) /* non-sparkable */
59 #define _THU (1<<3) /* thunk? */
60 #define _MUT (1<<4) /* mutable? */
61 #define _UPT (1<<5) /* unpointed? */
62 #define _SRT (1<<6) /* has an SRT? */
63 #define _IND (1<<7) /* is an indirection? */
64
65 #define isMUTABLE(flags) ((flags) &_MUT)
66 #define isBITMAP(flags) ((flags) &_BTM)
67 #define isTHUNK(flags) ((flags) &_THU)
68 #define isUNPOINTED(flags) ((flags) &_UPT)
69 #define hasSRT(flags) ((flags) &_SRT)
70
71 extern StgWord16 closure_flags[];
72
73 #define closureFlags(c) (closure_flags[get_itbl \
74 (UNTAG_CONST_CLOSURE(c))->type])
75
76 #define closure_HNF(c) ( closureFlags(c) & _HNF)
77 #define closure_BITMAP(c) ( closureFlags(c) & _BTM)
78 #define closure_NON_SPARK(c) ( (closureFlags(c) & _NS))
79 #define closure_SHOULD_SPARK(c) (!(closureFlags(c) & _NS))
80 #define closure_THUNK(c) ( closureFlags(c) & _THU)
81 #define closure_MUTABLE(c) ( closureFlags(c) & _MUT)
82 #define closure_UNPOINTED(c) ( closureFlags(c) & _UPT)
83 #define closure_SRT(c) ( closureFlags(c) & _SRT)
84 #define closure_IND(c) ( closureFlags(c) & _IND)
85
86 /* same as above but for info-ptr rather than closure */
87 #define ipFlags(ip) (closure_flags[ip->type])
88
89 #define ip_HNF(ip) ( ipFlags(ip) & _HNF)
90 #define ip_BITMAP(ip) ( ipFlags(ip) & _BTM)
91 #define ip_SHOULD_SPARK(ip) (!(ipFlags(ip) & _NS))
92 #define ip_THUNK(ip) ( ipFlags(ip) & _THU)
93 #define ip_MUTABLE(ip) ( ipFlags(ip) & _MUT)
94 #define ip_UNPOINTED(ip) ( ipFlags(ip) & _UPT)
95 #define ip_SRT(ip) ( ipFlags(ip) & _SRT)
96 #define ip_IND(ip) ( ipFlags(ip) & _IND)
97
98 /* -----------------------------------------------------------------------------
99 Bitmaps
100
101 These are used to describe the pointerhood of a sequence of words
102 (usually on the stack) to the garbage collector. The two primary
103 uses are for stack frames, and functions (where we need to describe
104 the layout of a PAP to the GC).
105
106 In these bitmaps: 0 == ptr, 1 == non-ptr.
107 -------------------------------------------------------------------------- */
108
109 /*
110 * Small bitmaps: for a small bitmap, we store the size and bitmap in
111 * the same word, using the following macros. If the bitmap doesn't
112 * fit in a single word, we use a pointer to an StgLargeBitmap below.
113 */
114 #define MK_SMALL_BITMAP(size,bits) (((bits)<<BITMAP_BITS_SHIFT) | (size))
115
116 #define BITMAP_SIZE(bitmap) ((bitmap) & BITMAP_SIZE_MASK)
117 #define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT)
118
119 /*
120 * A large bitmap.
121 */
122 typedef struct {
123 StgWord size;
124 StgWord bitmap[];
125 } StgLargeBitmap;
126
127 /* -----------------------------------------------------------------------------
128 SRTs (Static Reference Tables)
129
130 These tables are used to keep track of the static objects referred
131 to by the code for a closure or stack frame, so that we can follow
132 static data references from code and thus accurately
133 garbage-collect CAFs.
134 -------------------------------------------------------------------------- */
135
136 /* An SRT is just an array of closure pointers: */
137 typedef StgClosure* StgSRT[];
138
139 /*
140 * Each info table refers to some subset of the closure pointers in an
141 * SRT. It does this using a pair of an StgSRT pointer and a
142 * half-word bitmap. If the half-word bitmap isn't large enough, then
143 * we fall back to a large SRT, including an unbounded bitmap. If the
144 * half-word bitmap is set to all ones (0xffff), then the StgSRT
145 * pointer instead points to an StgLargeSRT:
146 */
147 typedef struct StgLargeSRT_ {
148 StgSRT *srt;
149 StgLargeBitmap l;
150 } StgLargeSRT;
151
152 /* ----------------------------------------------------------------------------
153 Info Tables
154 ------------------------------------------------------------------------- */
155
156 /*
157 * Stuff describing the closure layout. Well, actually, it might
158 * contain the selector index for a THUNK_SELECTOR. This union is one
159 * word long.
160 */
161 typedef union {
162 struct { /* Heap closure payload layout: */
163 StgHalfWord ptrs; /* number of pointers */
164 StgHalfWord nptrs; /* number of non-pointers */
165 } payload;
166
167 StgWord bitmap; /* word-sized bit pattern describing */
168 /* a stack frame: see below */
169
170 #if !defined(TABLES_NEXT_TO_CODE)
171 StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
172 #else
173 OFFSET_FIELD(large_bitmap_offset); /* offset from info table to large bitmap structure */
174 #endif
175
176 StgWord selector_offset; /* used in THUNK_SELECTORs */
177
178 } StgClosureInfo;
179
180
181 /*
182 * The "standard" part of an info table. Every info table has this bit.
183 */
184 typedef struct StgInfoTable_ {
185
186 #if !defined(TABLES_NEXT_TO_CODE)
187 StgFunPtr entry; /* pointer to the entry code */
188 #endif
189
190 #if defined(PROFILING)
191 StgProfInfo prof;
192 #endif
193
194 StgClosureInfo layout; /* closure layout info (one word) */
195
196 StgHalfWord type; /* closure type */
197 StgHalfWord srt_bitmap;
198 /* In a CONSTR:
199 - the constructor tag
200 In a FUN/THUNK
201 - a bitmap of SRT entries
202 */
203
204 #if defined(TABLES_NEXT_TO_CODE)
205 StgCode code[];
206 #endif
207 } *StgInfoTablePtr; // StgInfoTable defined in rts/Types.h
208
209
210 /* -----------------------------------------------------------------------------
211 Function info tables
212
213 This is the general form of function info tables. The compiler
214 will omit some of the fields in common cases:
215
216 - If fun_type is not ARG_GEN or ARG_GEN_BIG, then the slow_apply
217 and bitmap fields may be left out (they are at the end, so omitting
218 them doesn't affect the layout).
219
220 - If srt_bitmap (in the std info table part) is zero, then the srt
221 field needn't be set. This only applies if the slow_apply and
222 bitmap fields have also been omitted.
223 -------------------------------------------------------------------------- */
224
225 /*
226 Note [Encoding static reference tables]
227 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
228
229 As static reference tables appear frequently in code, we use a special
230 compact encoding for the common case of a module defining only a few CAFs: We
231 produce one table containing a list of CAFs in the module and then include a
232 bitmap in each info table describing which entries of this table the closure
233 references.
234 */
235
236 typedef struct StgFunInfoExtraRev_ {
237 OFFSET_FIELD(slow_apply_offset); /* apply to args on the stack */
238 union {
239 StgWord bitmap;
240 OFFSET_FIELD(bitmap_offset); /* arg ptr/nonptr bitmap */
241 } b;
242 OFFSET_FIELD(srt_offset); /* pointer to the SRT table */
243 StgHalfWord fun_type; /* function type */
244 StgHalfWord arity; /* function arity */
245 } StgFunInfoExtraRev;
246
247 typedef struct StgFunInfoExtraFwd_ {
248 StgHalfWord fun_type; /* function type */
249 StgHalfWord arity; /* function arity */
250 StgSRT *srt; /* pointer to the SRT table */
251 union { /* union for compat. with TABLES_NEXT_TO_CODE version */
252 StgWord bitmap; /* arg ptr/nonptr bitmap */
253 } b;
254 StgFun *slow_apply; /* apply to args on the stack */
255 } StgFunInfoExtraFwd;
256
257 typedef struct {
258 #if defined(TABLES_NEXT_TO_CODE)
259 StgFunInfoExtraRev f;
260 StgInfoTable i;
261 #else
262 StgInfoTable i;
263 StgFunInfoExtraFwd f;
264 #endif
265 } StgFunInfoTable;
266
267 // canned bitmap for each arg type, indexed by constants in FunTypes.h
268 extern const StgWord stg_arg_bitmaps[];
269
270 /* -----------------------------------------------------------------------------
271 Return info tables
272 -------------------------------------------------------------------------- */
273
274 /*
275 * When info tables are laid out backwards, we can omit the SRT
276 * pointer iff srt_bitmap is zero.
277 */
278
279 typedef struct {
280 #if defined(TABLES_NEXT_TO_CODE)
281 OFFSET_FIELD(srt_offset); /* offset to the SRT table */
282 StgInfoTable i;
283 #else
284 StgInfoTable i;
285 StgSRT *srt; /* pointer to the SRT table */
286 #endif
287 } StgRetInfoTable;
288
289 /* -----------------------------------------------------------------------------
290 Thunk info tables
291 -------------------------------------------------------------------------- */
292
293 /*
294 * When info tables are laid out backwards, we can omit the SRT
295 * pointer iff srt_bitmap is zero.
296 */
297
298 typedef struct StgThunkInfoTable_ {
299 #if !defined(TABLES_NEXT_TO_CODE)
300 StgInfoTable i;
301 #endif
302 #if defined(TABLES_NEXT_TO_CODE)
303 OFFSET_FIELD(srt_offset); /* offset to the SRT table */
304 #else
305 StgSRT *srt; /* pointer to the SRT table */
306 #endif
307 #if defined(TABLES_NEXT_TO_CODE)
308 StgInfoTable i;
309 #endif
310 } StgThunkInfoTable;
311
312 /* -----------------------------------------------------------------------------
313 Constructor info tables
314 -------------------------------------------------------------------------- */
315
316 typedef struct StgConInfoTable_ {
317 #if !defined(TABLES_NEXT_TO_CODE)
318 StgInfoTable i;
319 #endif
320
321 #if defined(TABLES_NEXT_TO_CODE)
322 OFFSET_FIELD(con_desc); // the name of the data constructor
323 // as: Package:Module.Name
324 #else
325 char *con_desc;
326 #endif
327
328 #if defined(TABLES_NEXT_TO_CODE)
329 StgInfoTable i;
330 #endif
331 } StgConInfoTable;
332
333
334 /* -----------------------------------------------------------------------------
335 Accessor macros for fields that might be offsets (C version)
336 -------------------------------------------------------------------------- */
337
338 /*
339 * GET_SRT(info)
340 * info must be a Stg[Ret|Thunk]InfoTable* (an info table that has a SRT)
341 */
342 #if defined(TABLES_NEXT_TO_CODE)
343 #define GET_SRT(info) ((StgSRT*) (((StgWord) ((info)+1)) + (info)->srt_offset))
344 #else
345 #define GET_SRT(info) ((info)->srt)
346 #endif
347
348 /*
349 * GET_CON_DESC(info)
350 * info must be a StgConInfoTable*.
351 */
352 #if defined(TABLES_NEXT_TO_CODE)
353 #define GET_CON_DESC(info) \
354 ((const char *)((StgWord)((info)+1) + (info->con_desc)))
355 #else
356 #define GET_CON_DESC(info) ((const char *)(info)->con_desc)
357 #endif
358
359 /*
360 * GET_FUN_SRT(info)
361 * info must be a StgFunInfoTable*
362 */
363 #if defined(TABLES_NEXT_TO_CODE)
364 #define GET_FUN_SRT(info) ((StgSRT*) (((StgWord) ((info)+1)) + (info)->f.srt_offset))
365 #else
366 #define GET_FUN_SRT(info) ((info)->f.srt)
367 #endif
368
369 #if defined(TABLES_NEXT_TO_CODE)
370 #define GET_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
371 + (info)->layout.large_bitmap_offset))
372 #else
373 #define GET_LARGE_BITMAP(info) ((info)->layout.large_bitmap)
374 #endif
375
376 #if defined(TABLES_NEXT_TO_CODE)
377 #define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
378 + (info)->f.b.bitmap_offset))
379 #else
380 #define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) ((info)->f.b.bitmap))
381 #endif
382
383 /*
384 * GET_PROF_TYPE, GET_PROF_DESC
385 */
386 #if defined(TABLES_NEXT_TO_CODE)
387 #define GET_PROF_TYPE(info) ((char *)((StgWord)((info)+1) + (info->prof.closure_type_off)))
388 #else
389 #define GET_PROF_TYPE(info) ((info)->prof.closure_type)
390 #endif
391 #if defined(TABLES_NEXT_TO_CODE)
392 #define GET_PROF_DESC(info) ((char *)((StgWord)((info)+1) + (info->prof.closure_desc_off)))
393 #else
394 #define GET_PROF_DESC(info) ((info)->prof.closure_desc)
395 #endif