137cfe2a1e86cc1958eae8aa3815ee054cee08f6
[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 Info Tables
129 ------------------------------------------------------------------------- */
130
131 /*
132 * Stuff describing the closure layout. Well, actually, it might
133 * contain the selector index for a THUNK_SELECTOR. This union is one
134 * word long.
135 */
136 typedef union {
137 struct { /* Heap closure payload layout: */
138 StgHalfWord ptrs; /* number of pointers */
139 StgHalfWord nptrs; /* number of non-pointers */
140 } payload;
141
142 StgWord bitmap; /* word-sized bit pattern describing */
143 /* a stack frame: see below */
144
145 #if !defined(TABLES_NEXT_TO_CODE)
146 StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
147 #else
148 OFFSET_FIELD(large_bitmap_offset); /* offset from info table to large bitmap structure */
149 #endif
150
151 StgWord selector_offset; /* used in THUNK_SELECTORs */
152
153 } StgClosureInfo;
154
155
156 #if defined(x86_64_TARGET_ARCH) && defined(TABLES_NEXT_TO_CODE)
157 // On x86_64 we can fit a pointer offset in half a word, so put the SRT offset
158 // in the info->srt field directly.
159 #define USE_INLINE_SRT_FIELD
160 #endif
161
162 #if defined(USE_INLINE_SRT_FIELD)
163 // offset to the SRT / closure, or zero if there's no SRT
164 typedef StgHalfInt StgSRTField;
165 #else
166 // non-zero if there is an SRT, the offset is in the optional srt field.
167 typedef StgHalfWord StgSRTField;
168 #endif
169
170
171 /*
172 * The "standard" part of an info table. Every info table has this bit.
173 */
174 typedef struct StgInfoTable_ {
175
176 #if !defined(TABLES_NEXT_TO_CODE)
177 StgFunPtr entry; /* pointer to the entry code */
178 #endif
179
180 #if defined(PROFILING)
181 StgProfInfo prof;
182 #endif
183
184 StgClosureInfo layout; /* closure layout info (one word) */
185
186 StgHalfWord type; /* closure type */
187 StgSRTField srt;
188 /* In a CONSTR:
189 - the constructor tag
190 In a FUN/THUNK
191 - if USE_INLINE_SRT_FIELD
192 - offset to the SRT (or zero if no SRT)
193 - otherwise
194 - non-zero if there is an SRT, offset is in srt_offset
195 */
196
197 #if defined(TABLES_NEXT_TO_CODE)
198 StgCode code[];
199 #endif
200 } *StgInfoTablePtr; // StgInfoTable defined in rts/Types.h
201
202
203 /* -----------------------------------------------------------------------------
204 Function info tables
205
206 This is the general form of function info tables. The compiler
207 will omit some of the fields in common cases:
208
209 - If fun_type is not ARG_GEN or ARG_GEN_BIG, then the slow_apply
210 and bitmap fields may be left out (they are at the end, so omitting
211 them doesn't affect the layout).
212
213 - If has_srt (in the std info table part) is zero, then the srt
214 field needn't be set. This only applies if the slow_apply and
215 bitmap fields have also been omitted.
216 -------------------------------------------------------------------------- */
217
218 /*
219 Note [Encoding static reference tables]
220 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
221
222 As static reference tables appear frequently in code, we use a special
223 compact encoding for the common case of a module defining only a few CAFs: We
224 produce one table containing a list of CAFs in the module and then include a
225 bitmap in each info table describing which entries of this table the closure
226 references.
227 */
228
229 typedef struct StgFunInfoExtraRev_ {
230 OFFSET_FIELD(slow_apply_offset); /* apply to args on the stack */
231 union {
232 StgWord bitmap;
233 OFFSET_FIELD(bitmap_offset); /* arg ptr/nonptr bitmap */
234 } b;
235 #if !defined(USE_INLINE_SRT_FIELD)
236 OFFSET_FIELD(srt_offset); /* pointer to the SRT closure */
237 #endif
238 StgHalfWord fun_type; /* function type */
239 StgHalfWord arity; /* function arity */
240 } StgFunInfoExtraRev;
241
242 typedef struct StgFunInfoExtraFwd_ {
243 StgHalfWord fun_type; /* function type */
244 StgHalfWord arity; /* function arity */
245 StgClosure *srt; /* pointer to the SRT closure */
246 union { /* union for compat. with TABLES_NEXT_TO_CODE version */
247 StgWord bitmap; /* arg ptr/nonptr bitmap */
248 } b;
249 StgFun *slow_apply; /* apply to args on the stack */
250 } StgFunInfoExtraFwd;
251
252 typedef struct {
253 #if defined(TABLES_NEXT_TO_CODE)
254 StgFunInfoExtraRev f;
255 StgInfoTable i;
256 #else
257 StgInfoTable i;
258 StgFunInfoExtraFwd f;
259 #endif
260 } StgFunInfoTable;
261
262 // canned bitmap for each arg type, indexed by constants in FunTypes.h
263 extern const StgWord stg_arg_bitmaps[];
264
265 /* -----------------------------------------------------------------------------
266 Return info tables
267 -------------------------------------------------------------------------- */
268
269 /*
270 * When info tables are laid out backwards, we can omit the SRT
271 * pointer iff has_srt is zero.
272 */
273
274 typedef struct {
275 #if defined(TABLES_NEXT_TO_CODE)
276 #if !defined(USE_INLINE_SRT_FIELD)
277 OFFSET_FIELD(srt_offset); /* offset to the SRT closure */
278 #endif
279 StgInfoTable i;
280 #else
281 StgInfoTable i;
282 StgClosure *srt; /* pointer to the SRT closure */
283 #endif
284 } StgRetInfoTable;
285
286 /* -----------------------------------------------------------------------------
287 Thunk info tables
288 -------------------------------------------------------------------------- */
289
290 /*
291 * When info tables are laid out backwards, we can omit the SRT
292 * pointer iff has_srt is zero.
293 */
294
295 typedef struct StgThunkInfoTable_ {
296 #if defined(TABLES_NEXT_TO_CODE)
297 #if !defined(USE_INLINE_SRT_FIELD)
298 OFFSET_FIELD(srt_offset); /* offset to the SRT closure */
299 #endif
300 StgInfoTable i;
301 #else
302 StgInfoTable i;
303 StgClosure *srt; /* pointer to the SRT closure */
304 #endif
305 } StgThunkInfoTable;
306
307 /* -----------------------------------------------------------------------------
308 Constructor info tables
309 -------------------------------------------------------------------------- */
310
311 typedef struct StgConInfoTable_ {
312 #if !defined(TABLES_NEXT_TO_CODE)
313 StgInfoTable i;
314 #endif
315
316 #if defined(TABLES_NEXT_TO_CODE)
317 OFFSET_FIELD(con_desc); // the name of the data constructor
318 // as: Package:Module.Name
319 #else
320 char *con_desc;
321 #endif
322
323 #if defined(TABLES_NEXT_TO_CODE)
324 StgInfoTable i;
325 #endif
326 } StgConInfoTable;
327
328
329 /* -----------------------------------------------------------------------------
330 Accessor macros for fields that might be offsets (C version)
331 -------------------------------------------------------------------------- */
332
333 /*
334 * GET_SRT(info)
335 * info must be a Stg[Ret|Thunk]InfoTable* (an info table that has a SRT)
336 */
337 #if defined(TABLES_NEXT_TO_CODE)
338 #if defined(x86_64_TARGET_ARCH)
339 #define GET_SRT(info) \
340 ((StgClosure*) (((StgWord) ((info)+1)) + (info)->i.srt))
341 #else
342 #define GET_SRT(info) \
343 ((StgClosure*) (((StgWord) ((info)+1)) + (info)->srt_offset))
344 #endif
345 #else // !TABLES_NEXT_TO_CODE
346 #define GET_SRT(info) ((info)->srt)
347 #endif
348
349 /*
350 * GET_CON_DESC(info)
351 * info must be a StgConInfoTable*.
352 */
353 #if defined(TABLES_NEXT_TO_CODE)
354 #define GET_CON_DESC(info) \
355 ((const char *)((StgWord)((info)+1) + (info->con_desc)))
356 #else
357 #define GET_CON_DESC(info) ((const char *)(info)->con_desc)
358 #endif
359
360 /*
361 * GET_FUN_SRT(info)
362 * info must be a StgFunInfoTable*
363 */
364 #if defined(TABLES_NEXT_TO_CODE)
365 #if defined(x86_64_TARGET_ARCH)
366 #define GET_FUN_SRT(info) \
367 ((StgClosure*) (((StgWord) ((info)+1)) + (info)->i.srt))
368 #else
369 #define GET_FUN_SRT(info) \
370 ((StgClosure*) (((StgWord) ((info)+1)) + (info)->f.srt_offset))
371 #endif
372 #else
373 #define GET_FUN_SRT(info) ((info)->f.srt)
374 #endif
375
376 #if defined(TABLES_NEXT_TO_CODE)
377 #define GET_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
378 + (info)->layout.large_bitmap_offset))
379 #else
380 #define GET_LARGE_BITMAP(info) ((info)->layout.large_bitmap)
381 #endif
382
383 #if defined(TABLES_NEXT_TO_CODE)
384 #define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
385 + (info)->f.b.bitmap_offset))
386 #else
387 #define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) ((info)->f.b.bitmap))
388 #endif
389
390 /*
391 * GET_PROF_TYPE, GET_PROF_DESC
392 */
393 #if defined(TABLES_NEXT_TO_CODE)
394 #define GET_PROF_TYPE(info) ((char *)((StgWord)((info)+1) + (info->prof.closure_type_off)))
395 #else
396 #define GET_PROF_TYPE(info) ((info)->prof.closure_type)
397 #endif
398 #if defined(TABLES_NEXT_TO_CODE)
399 #define GET_PROF_DESC(info) ((char *)((StgWord)((info)+1) + (info->prof.closure_desc_off)))
400 #else
401 #define GET_PROF_DESC(info) ((info)->prof.closure_desc)
402 #endif