root/includes/rts/storage/InfoTables.h

Revision e562e59a7662010202fafb2edbd34edcaa06e5d2, 13.3 KB (checked in by Simon Marlow <marlowsd@…>, 3 months ago)

fix _BTM field of closureFlags[], and document what it means (#5923)

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