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