InfoTables.h 12.3 KB
Newer Older
1
/* ----------------------------------------------------------------------------
2
 *
3
 * (c) The GHC Team, 1998-2002
4
 *
5 6 7 8
 * Info Tables
 *
 * -------------------------------------------------------------------------- */

Simon Marlow's avatar
Simon Marlow committed
9 10
#ifndef RTS_STORAGE_INFOTABLES_H
#define RTS_STORAGE_INFOTABLES_H
11

Simon Marlow's avatar
Simon Marlow committed
12 13 14 15 16 17 18 19 20
/* ----------------------------------------------------------------------------
   Relative pointers

   Several pointer fields in info tables are expressed as offsets
   relative to the info pointer, so that we can generate
   position-independent code.
   ------------------------------------------------------------------------- */

#if x86_64_TARGET_ARCH
21
#define OFFSET_FIELD(n) StgHalfInt n; StgHalfWord __pad_##n
22
#else
23
#define OFFSET_FIELD(n) StgInt n
Simon Marlow's avatar
Simon Marlow committed
24 25
#endif

26 27 28 29 30
/* -----------------------------------------------------------------------------
   Profiling info
   -------------------------------------------------------------------------- */

typedef struct {
Simon Marlow's avatar
Simon Marlow committed
31
#ifndef TABLES_NEXT_TO_CODE
32 33
    char *closure_type;
    char *closure_desc;
Simon Marlow's avatar
Simon Marlow committed
34 35 36 37
#else
    OFFSET_FIELD(closure_type_off);
    OFFSET_FIELD(closure_desc_off);
#endif
38 39
} StgProfInfo;

40 41 42 43
/* -----------------------------------------------------------------------------
   Closure flags
   -------------------------------------------------------------------------- */

44 45
/* The type flags provide quick access to certain properties of a closure. */

46
#define _HNF (1<<0)  /* head normal form?    */
47
#define _BTM (1<<1)  /* uses info->layout.bitmap */
48 49 50 51 52 53 54
#define _NS  (1<<2)  /* non-sparkable        */
#define _STA (1<<3)  /* static?              */
#define _THU (1<<4)  /* thunk?               */
#define _MUT (1<<5)  /* mutable?             */
#define _UPT (1<<6)  /* unpointed?           */
#define _SRT (1<<7)  /* has an SRT?          */
#define _IND (1<<8)  /* is an indirection?   */
55

56 57 58 59 60 61
#define isSTATIC(flags)    ((flags) &_STA)
#define isMUTABLE(flags)   ((flags) &_MUT)
#define isBITMAP(flags)    ((flags) &_BTM)
#define isTHUNK(flags)     ((flags) &_THU)
#define isUNPOINTED(flags) ((flags) &_UPT)
#define hasSRT(flags)      ((flags) &_SRT)
62

63 64
extern StgWord16 closure_flags[];

65 66
#define closureFlags(c)         (closure_flags[get_itbl \
                                    (UNTAG_CONST_CLOSURE(c))->type])
67

68 69
#define closure_HNF(c)          (  closureFlags(c) & _HNF)
#define closure_BITMAP(c)       (  closureFlags(c) & _BTM)
70
#define closure_NON_SPARK(c)    ( (closureFlags(c) & _NS))
71
#define closure_SHOULD_SPARK(c) (!(closureFlags(c) & _NS))
72 73
#define closure_STATIC(c)       (  closureFlags(c) & _STA)
#define closure_THUNK(c)        (  closureFlags(c) & _THU)
74 75
#define closure_MUTABLE(c)      (  closureFlags(c) & _MUT)
#define closure_UNPOINTED(c)    (  closureFlags(c) & _UPT)
76
#define closure_SRT(c)          (  closureFlags(c) & _SRT)
77
#define closure_IND(c)          (  closureFlags(c) & _IND)
78 79 80

/* same as above but for info-ptr rather than closure */
#define ipFlags(ip)             (closure_flags[ip->type])
81

82
#define ip_HNF(ip)               (  ipFlags(ip) & _HNF)
83 84 85 86 87 88 89 90
#define ip_BITMAP(ip)            (  ipFlags(ip) & _BTM)
#define ip_SHOULD_SPARK(ip)      (!(ipFlags(ip) & _NS))
#define ip_STATIC(ip)            (  ipFlags(ip) & _STA)
#define ip_THUNK(ip)             (  ipFlags(ip) & _THU)
#define ip_MUTABLE(ip)           (  ipFlags(ip) & _MUT)
#define ip_UNPOINTED(ip)         (  ipFlags(ip) & _UPT)
#define ip_SRT(ip)               (  ipFlags(ip) & _SRT)
#define ip_IND(ip)               (  ipFlags(ip) & _IND)
91 92

/* -----------------------------------------------------------------------------
93 94 95 96 97 98
   Bitmaps

   These are used to describe the pointerhood of a sequence of words
   (usually on the stack) to the garbage collector.  The two primary
   uses are for stack frames, and functions (where we need to describe
   the layout of a PAP to the GC).
99 100

   In these bitmaps: 0 == ptr, 1 == non-ptr.
101 102
   -------------------------------------------------------------------------- */

103
/*
104
 * Small bitmaps:  for a small bitmap, we store the size and bitmap in
105 106 107
 * the same word, using the following macros.  If the bitmap doesn't
 * fit in a single word, we use a pointer to an StgLargeBitmap below.
 */
108 109 110 111
#define MK_SMALL_BITMAP(size,bits) (((bits)<<BITMAP_BITS_SHIFT) | (size))

#define BITMAP_SIZE(bitmap) ((bitmap) & BITMAP_SIZE_MASK)
#define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT)
112

113 114 115
/*
 * A large bitmap.
 */
116
typedef struct {
117
  StgWord size;
118
  StgWord bitmap[];
119 120
} StgLargeBitmap;

121 122 123 124 125 126 127 128 129
/* -----------------------------------------------------------------------------
   SRTs  (Static Reference Tables)

   These tables are used to keep track of the static objects referred
   to by the code for a closure or stack frame, so that we can follow
   static data references from code and thus accurately
   garbage-collect CAFs.
   -------------------------------------------------------------------------- */

130
/* An SRT is just an array of closure pointers: */
131 132
typedef StgClosure* StgSRT[];

133 134 135 136 137 138 139 140
/*
 * Each info table refers to some subset of the closure pointers in an
 * SRT.  It does this using a pair of an StgSRT pointer and a
 * half-word bitmap.  If the half-word bitmap isn't large enough, then
 * we fall back to a large SRT, including an unbounded bitmap.  If the
 * half-word bitmap is set to all ones (0xffff), then the StgSRT
 * pointer instead points to an StgLargeSRT:
 */
141 142 143 144 145
typedef struct StgLargeSRT_ {
    StgSRT *srt;
    StgLargeBitmap l;
} StgLargeSRT;

146 147 148
/* ----------------------------------------------------------------------------
   Info Tables
   ------------------------------------------------------------------------- */
149

150 151 152 153 154
/*
 * Stuff describing the closure layout.  Well, actually, it might
 * contain the selector index for a THUNK_SELECTOR.  This union is one
 * word long.
 */
155
typedef union {
156 157 158
    struct {                    /* Heap closure payload layout: */
        StgHalfWord ptrs;       /* number of pointers */
        StgHalfWord nptrs;      /* number of non-pointers */
159
    } payload;
160 161 162

    StgWord bitmap;               /* word-sized bit pattern describing */
                                  /*  a stack frame: see below */
163

164
#ifndef TABLES_NEXT_TO_CODE
165
    StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
166
#else
167
    OFFSET_FIELD(large_bitmap_offset);  /* offset from info table to large bitmap structure */
168
#endif
169 170

    StgWord selector_offset;      /* used in THUNK_SELECTORs */
sof's avatar
sof committed
171

172 173 174
} StgClosureInfo;


175 176 177
/*
 * The "standard" part of an info table.  Every info table has this bit.
 */
Simon Marlow's avatar
Simon Marlow committed
178
typedef struct StgInfoTable_ {
179

180
#if !defined(TABLES_NEXT_TO_CODE)
181
    StgFunPtr       entry;      /* pointer to the entry code */
182 183
#endif

sof's avatar
sof committed
184
#ifdef PROFILING
185
    StgProfInfo     prof;
sof's avatar
sof committed
186
#endif
187

188
    StgClosureInfo  layout;     /* closure layout info (one word) */
189

190
    StgHalfWord     type;       /* closure type */
191 192 193 194 195 196
    StgHalfWord     srt_bitmap;
       /* In a CONSTR:
            - the constructor tag
          In a FUN/THUNK
            - a bitmap of SRT entries
       */
197

198
#ifdef TABLES_NEXT_TO_CODE
199
    StgCode         code[];
200
#endif
thomie's avatar
thomie committed
201
} *StgInfoTablePtr; // StgInfoTable defined in rts/Types.h
202

203 204 205 206 207 208 209 210 211 212

/* -----------------------------------------------------------------------------
   Function info tables

   This is the general form of function info tables.  The compiler
   will omit some of the fields in common cases:

   -  If fun_type is not ARG_GEN or ARG_GEN_BIG, then the slow_apply
      and bitmap fields may be left out (they are at the end, so omitting
      them doesn't affect the layout).
213

214
   -  If srt_bitmap (in the std info table part) is zero, then the srt
215 216 217 218
      field may be omitted.  This only applies if the slow_apply and
      bitmap fields have also been omitted.
   -------------------------------------------------------------------------- */

Simon Marlow's avatar
Simon Marlow committed
219
typedef struct StgFunInfoExtraRev_ {
220
    OFFSET_FIELD(slow_apply_offset); /* apply to args on the stack */
221 222 223
    union {
        StgWord bitmap;
        OFFSET_FIELD(bitmap_offset);    /* arg ptr/nonptr bitmap */
224
    } b;
225
    OFFSET_FIELD(srt_offset);   /* pointer to the SRT table */
226 227
    StgHalfWord    fun_type;    /* function type */
    StgHalfWord    arity;       /* function arity */
228 229
} StgFunInfoExtraRev;

Simon Marlow's avatar
Simon Marlow committed
230
typedef struct StgFunInfoExtraFwd_ {
231 232
    StgHalfWord    fun_type;    /* function type */
    StgHalfWord    arity;       /* function arity */
233
    StgSRT         *srt;        /* pointer to the SRT table */
234
    union { /* union for compat. with TABLES_NEXT_TO_CODE version */
235
        StgWord        bitmap;  /* arg ptr/nonptr bitmap */
236
    } b;
237
    StgFun         *slow_apply; /* apply to args on the stack */
238 239 240 241 242 243 244 245 246
} StgFunInfoExtraFwd;

typedef struct {
#if defined(TABLES_NEXT_TO_CODE)
    StgFunInfoExtraRev f;
    StgInfoTable i;
#else
    StgInfoTable i;
    StgFunInfoExtraFwd f;
247 248 249
#endif
} StgFunInfoTable;

250 251 252
// canned bitmap for each arg type, indexed by constants in FunTypes.h
extern StgWord stg_arg_bitmaps[];

253 254 255 256
/* -----------------------------------------------------------------------------
   Return info tables
   -------------------------------------------------------------------------- */

257 258 259 260
/*
 * When info tables are laid out backwards, we can omit the SRT
 * pointer iff srt_bitmap is zero.
 */
261

262
typedef struct {
263
#if defined(TABLES_NEXT_TO_CODE)
264
    OFFSET_FIELD(srt_offset);   /* offset to the SRT table */
265
    StgInfoTable i;
266 267
#else
    StgInfoTable i;
268
    StgSRT      *srt;   /* pointer to the SRT table */
269 270 271 272 273 274 275
#endif
} StgRetInfoTable;

/* -----------------------------------------------------------------------------
   Thunk info tables
   -------------------------------------------------------------------------- */

276 277 278 279
/*
 * When info tables are laid out backwards, we can omit the SRT
 * pointer iff srt_bitmap is zero.
 */
280

Simon Marlow's avatar
Simon Marlow committed
281
typedef struct StgThunkInfoTable_ {
282 283 284
#if !defined(TABLES_NEXT_TO_CODE)
    StgInfoTable i;
#endif
285
#if defined(TABLES_NEXT_TO_CODE)
286
    OFFSET_FIELD(srt_offset);   /* offset to the SRT table */
287
#else
288
    StgSRT         *srt;        /* pointer to the SRT table */
289
#endif
290 291
#if defined(TABLES_NEXT_TO_CODE)
    StgInfoTable i;
292
#endif
293
} StgThunkInfoTable;
294

295 296 297 298
/* -----------------------------------------------------------------------------
   Constructor info tables
   -------------------------------------------------------------------------- */

Simon Marlow's avatar
Simon Marlow committed
299
typedef struct StgConInfoTable_ {
300 301 302 303
#if !defined(TABLES_NEXT_TO_CODE)
    StgInfoTable i;
#endif

304
#if defined(TABLES_NEXT_TO_CODE)
305
    OFFSET_FIELD(con_desc); // the name of the data constructor
306
                            // as: Package:Module.Name
307 308
#else
    char *con_desc;
Simon Marlow's avatar
Simon Marlow committed
309
#endif
310 311 312 313 314 315

#if defined(TABLES_NEXT_TO_CODE)
    StgInfoTable i;
#endif
} StgConInfoTable;

316 317 318 319 320

/* -----------------------------------------------------------------------------
   Accessor macros for fields that might be offsets (C version)
   -------------------------------------------------------------------------- */

321 322 323 324
/*
 * GET_SRT(info)
 * info must be a Stg[Ret|Thunk]InfoTable* (an info table that has a SRT)
 */
325 326 327 328 329 330
#ifdef TABLES_NEXT_TO_CODE
#define GET_SRT(info) ((StgSRT*) (((StgWord) ((info)+1)) + (info)->srt_offset))
#else
#define GET_SRT(info) ((info)->srt)
#endif

331 332 333 334 335
/*
 * GET_CON_DESC(info)
 * info must be a StgConInfoTable*.
 */
#ifdef TABLES_NEXT_TO_CODE
336 337
#define GET_CON_DESC(info) \
            ((const char *)((StgWord)((info)+1) + (info->con_desc)))
338
#else
339
#define GET_CON_DESC(info) ((const char *)(info)->con_desc)
340 341
#endif

342 343 344 345
/*
 * GET_FUN_SRT(info)
 * info must be a StgFunInfoTable*
 */
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
#ifdef TABLES_NEXT_TO_CODE
#define GET_FUN_SRT(info) ((StgSRT*) (((StgWord) ((info)+1)) + (info)->f.srt_offset))
#else
#define GET_FUN_SRT(info) ((info)->f.srt)
#endif

#ifdef TABLES_NEXT_TO_CODE
#define GET_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
                                        + (info)->layout.large_bitmap_offset))
#else
#define GET_LARGE_BITMAP(info) ((info)->layout.large_bitmap)
#endif

#ifdef TABLES_NEXT_TO_CODE
#define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
361
                                        + (info)->f.b.bitmap_offset))
362
#else
363
#define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) ((info)->f.b.bitmap))
364 365
#endif

Simon Marlow's avatar
Simon Marlow committed
366 367 368 369 370 371 372 373 374 375 376 377 378
/*
 * GET_PROF_TYPE, GET_PROF_DESC
 */
#ifdef TABLES_NEXT_TO_CODE
#define GET_PROF_TYPE(info) ((char *)((StgWord)((info)+1) + (info->prof.closure_type_off)))
#else
#define GET_PROF_TYPE(info) ((info)->prof.closure_type)
#endif
#ifdef TABLES_NEXT_TO_CODE
#define GET_PROF_DESC(info) ((char *)((StgWord)((info)+1) + (info->prof.closure_desc_off)))
#else
#define GET_PROF_DESC(info) ((info)->prof.closure_desc)
#endif
Simon Marlow's avatar
Simon Marlow committed
379 380

#endif /* RTS_STORAGE_INFOTABLES_H */