mkDerivedConstants.c 12.9 KB
Newer Older
1 2
/* --------------------------------------------------------------------------
 *
3
 * (c) The GHC Team, 1992-2004
4
 *
5 6 7 8 9 10
 * mkDerivedConstants.c
 *
 * Basically this is a C program that extracts information from the C
 * declarations in the header files (primarily struct field offsets)
 * and generates a header file that can be #included into non-C source
 * containing this information.
11 12 13
 *
 * ------------------------------------------------------------------------*/

14
#define IN_STG_CODE 0
15

16 17 18 19
/*
 * We need offsets of profiled things... better be careful that this
 * doesn't affect the offsets of anything else.
 */
20
#define PROFILING
21
#define THREADED_RTS
22 23 24 25

#include "Rts.h"
#include "RtsFlags.h"
#include "Storage.h"
26 27
#include "OSThreads.h"
#include "Capability.h"
28

29 30
#include <stdio.h>

31
#define str(a,b) #a "_" #b
32 33 34

#define OFFSET(s_type, field) ((unsigned int)&(((s_type*)0)->field))

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
#if defined(GEN_HASKELL)
#define def_offset(str, offset) \
    printf("oFFSET_" str " = %d::Int\n", offset);
#else
#define def_offset(str, offset) \
    printf("#define OFFSET_" str " %d\n", offset);
#endif

#if defined(GEN_HASKELL)
#define ctype(type) /* nothing */
#else
#define ctype(type) \
    printf("#define SIZEOF_" #type " %d\n", sizeof(type)); 
#endif

#if defined(GEN_HASKELL)
#define field_type_(str, s_type, field) /* nothing */
#else
#define field_type_(str, s_type, field) \
    printf("#define REP_" str " I"); \
    printf("%d\n", sizeof (__typeof__(((((s_type*)0)->field)))) * 8);
#endif

#define field_type(s_type, field) \
    field_type_(str(s_type,field),s_type,field);

#define field_offset_(str, s_type, field) \
    def_offset(str, OFFSET(s_type,field));

#define field_offset(s_type, field) \
    field_offset_(str(s_type,field),s_type,field);

67
/* An access macro for use in C-- sources. */
68 69 70
#define struct_field_macro(str) \
    printf("#define " str "(__ptr__)  REP_" str "[__ptr__+OFFSET_" str "]\n");

71
/* Outputs the byte offset and MachRep for a field */
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#define struct_field(s_type, field)		\
    field_offset(s_type, field);		\
    field_type(s_type, field);			\
    struct_field_macro(str(s_type,field))

#define struct_field_(str, s_type, field)	\
    field_offset_(str, s_type, field);		\
    field_type_(str, s_type, field);		\
    struct_field_macro(str)

#if defined(GEN_HASKELL)
#define def_size(str, size) \
    printf("sIZEOF_" str " = %d::Int\n", size);
#else
#define def_size(str, size) \
    printf("#define SIZEOF_" str " %d\n", size);
#endif

#if defined(GEN_HASKELL)
#define def_closure_size(str, size) /* nothing */
#else
#define def_closure_size(str, size) \
    printf("#define SIZEOF_" str " (SIZEOF_StgHeader+%d)\n", size);
#endif

#define struct_size(s_type) \
    def_size(#s_type, sizeof(s_type));

100 101 102 103
/*
 * Size of a closure type, minus the header, named SIZEOF_<type>_NoHdr
 * Also, we #define SIZEOF_<type> to be the size of the whole closure for .cmm.
 */
104 105 106 107
#define closure_size(s_type) \
    def_size(#s_type "_NoHdr", sizeof(s_type) - sizeof(StgHeader)); \
    def_closure_size(#s_type, sizeof(s_type) - sizeof(StgHeader));

108
#define thunk_size(s_type) \
109 110
    def_size(#s_type "_NoThunkHdr", sizeof(s_type) - sizeof(StgThunkHeader)); \
    closure_size(s_type)
111

112
/* An access macro for use in C-- sources. */
113 114 115 116 117 118 119
#define closure_field_macro(str) \
    printf("#define " str "(__ptr__)  REP_" str "[__ptr__+SIZEOF_StgHeader+OFFSET_" str "]\n");

#define closure_field_offset_(str, s_type,field) \
    def_offset(str, OFFSET(s_type,field) - sizeof(StgHeader));

#define closure_field_offset(s_type,field) \
120 121
    closure_field_offset_(str(s_type,field),s_type,field)

122 123 124 125 126 127 128
#define closure_payload_macro(str) \
    printf("#define " str "(__ptr__,__ix__)  W_[__ptr__+SIZEOF_StgHeader+OFFSET_" str " + WDS(__ix__)]\n");

#define closure_payload(s_type,field) \
    closure_field_offset_(str(s_type,field),s_type,field); \
    closure_payload_macro(str(s_type,field));

129
/* Byte offset and MachRep for a closure field, minus the header */
130 131 132 133 134
#define closure_field(s_type, field) \
    closure_field_offset(s_type,field) \
    field_type(s_type, field); \
    closure_field_macro(str(s_type,field))

135
/* Byte offset and MachRep for a closure field, minus the header */
136 137 138 139 140
#define closure_field_(str, s_type, field) \
    closure_field_offset_(str,s_type,field) \
    field_type_(str, s_type, field); \
    closure_field_macro(str)

141 142
/* Byte offset for a TSO field, minus the header and variable prof bit. */
#define tso_payload_offset(s_type, field) \
143 144
    def_offset(str(s_type,field), OFFSET(s_type,field) - sizeof(StgHeader) - sizeof(StgTSOProfInfo));

145 146 147
/* Full byte offset for a TSO field, for use from Cmm */
#define tso_field_offset_macro(str) \
    printf("#define TSO_OFFSET_" str " (SIZEOF_StgHeader+SIZEOF_OPT_StgTSOProfInfo+SIZEOF_OPT_StgTSOParInfo+SIZEOF_OPT_StgTSOGranInfo+SIZEOF_OPT_StgTSODistInfo+OFFSET_" str ")\n");
148

149 150 151 152 153 154
#define tso_field_offset(s_type, field) \
    tso_payload_offset(s_type, field);  	\
    tso_field_offset_macro(str(s_type,field));

#define tso_field_macro(str) \
    printf("#define " str "(__ptr__)  REP_" str "[__ptr__+TSO_OFFSET_" str "]\n")
155 156
#define tso_field(s_type, field)		\
    field_type(s_type, field);			\
157
    tso_field_offset(s_type,field);		\
158
    tso_field_macro(str(s_type,field))
159
  
160 161 162 163 164 165 166 167 168 169
#define opt_struct_size(s_type, option)					\
    printf("#ifdef " #option "\n");					\
    printf("#define SIZEOF_OPT_" #s_type " SIZEOF_" #s_type "\n");	\
    printf("#else\n");							\
    printf("#define SIZEOF_OPT_" #s_type " 0\n");			\
    printf("#endif\n\n");

#define FUN_OFFSET(sym) (OFFSET(Capability,f.sym) - OFFSET(Capability,r))


170 171 172
int
main(int argc, char *argv[])
{
173 174
#ifndef GEN_HASKELL
    printf("/* This file is created automatically.  Do not edit by hand.*/\n\n");
175

176
    printf("#define STD_HDR_SIZE   %d\n", sizeofW(StgHeader) - sizeofW(StgProfHeader));
177
    /* grrr.. PROFILING is on so we need to subtract sizeofW(StgProfHeader) */
178 179 180 181
    printf("#define PROF_HDR_SIZE  %d\n", sizeofW(StgProfHeader));
    printf("#define GRAN_HDR_SIZE  %d\n", sizeofW(StgGranHeader));

    printf("#define STD_ITBL_SIZE   %d\n", sizeofW(StgInfoTable));
182
    printf("#define RET_ITBL_SIZE   %d\n", sizeofW(StgRetInfoTable) - sizeofW(StgInfoTable));
183
    printf("#define PROF_ITBL_SIZE  %d\n", sizeofW(StgProfInfo));
184

185
    printf("#define GRAN_ITBL_SIZE  %d\n", 0);
186
    printf("#define TICKY_ITBL_SIZE %d\n", 0);
187

188 189
    printf("#define BLOCK_SIZE   %d\n", BLOCK_SIZE);
    printf("#define MBLOCK_SIZE   %d\n", MBLOCK_SIZE);  
190

191 192
    printf("\n\n");
#endif
193

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
    field_offset(StgRegTable, rR1);
    field_offset(StgRegTable, rR2);
    field_offset(StgRegTable, rR3);
    field_offset(StgRegTable, rR4);
    field_offset(StgRegTable, rR5);
    field_offset(StgRegTable, rR6);
    field_offset(StgRegTable, rR7);
    field_offset(StgRegTable, rR8);
    field_offset(StgRegTable, rR9);
    field_offset(StgRegTable, rR10);
    field_offset(StgRegTable, rF1);
    field_offset(StgRegTable, rF2);
    field_offset(StgRegTable, rF3);
    field_offset(StgRegTable, rF4);
    field_offset(StgRegTable, rD1);
    field_offset(StgRegTable, rD2);
    field_offset(StgRegTable, rL1);
    field_offset(StgRegTable, rSp);
    field_offset(StgRegTable, rSpLim);
    field_offset(StgRegTable, rHp);
    field_offset(StgRegTable, rHpLim);
    field_offset(StgRegTable, rCurrentTSO);
    field_offset(StgRegTable, rCurrentNursery);
    field_offset(StgRegTable, rHpAlloc);
218
    struct_field(StgRegTable, rRet);
219

220 221 222 223 224 225 226
    // Needed for SMP builds
    field_offset(StgRegTable, rmp_tmp_w);
    field_offset(StgRegTable, rmp_tmp1);
    field_offset(StgRegTable, rmp_tmp2);
    field_offset(StgRegTable, rmp_result1);
    field_offset(StgRegTable, rmp_result2);

227 228 229 230
    def_offset("stgGCEnter1", FUN_OFFSET(stgGCEnter1));
    def_offset("stgGCFun", FUN_OFFSET(stgGCFun));

    field_offset(Capability, r);
231
    field_offset(Capability, lock);
232 233 234 235 236 237 238 239

    struct_field(bdescr, start);
    struct_field(bdescr, free);
    struct_field(bdescr, blocks);
    struct_field(bdescr, gen_no);
    struct_field(bdescr, link);

    struct_size(generation);
240
    struct_field(generation, mut_list);
241

242
    struct_size(CostCentreStack);
243 244 245 246 247 248 249 250 251 252 253 254
    struct_field(CostCentreStack, ccsID);
    struct_field(CostCentreStack, mem_alloc);
    struct_field(CostCentreStack, scc_count);
    struct_field(CostCentreStack, prevStack);

    struct_field(CostCentre, ccID);
    struct_field(CostCentre, link);

    struct_field(StgHeader, info);
    struct_field_("StgHeader_ccs",  StgHeader, prof.ccs);
    struct_field_("StgHeader_ldvw", StgHeader, prof.hp.ldvw);

255 256
    struct_size(StgSMPThunkHeader);

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    closure_payload(StgClosure,payload);

    struct_field(StgEntCounter, allocs);
    struct_field(StgEntCounter, registeredp);
    struct_field(StgEntCounter, link);
    
    closure_size(StgUpdateFrame);
    closure_size(StgCatchFrame);
    closure_size(StgStopFrame);

    closure_size(StgMutArrPtrs);
    closure_field(StgMutArrPtrs, ptrs);

    closure_size(StgArrWords);
    closure_field(StgArrWords, words);
    closure_payload(StgArrWords, payload);

    closure_field(StgTSO, link);
    closure_field(StgTSO, global_link);
    closure_field(StgTSO, what_next);
    closure_field(StgTSO, why_blocked);
    closure_field(StgTSO, block_info);
    closure_field(StgTSO, blocked_exceptions);
    closure_field(StgTSO, id);
281
    closure_field(StgTSO, cap);
282
    closure_field(StgTSO, saved_errno);
283
    closure_field(StgTSO, trec);
284
    closure_field(StgTSO, flags);
285 286
    closure_field_("StgTSO_CCCS", StgTSO, prof.CCCS);
    tso_field(StgTSO, sp);
287
    tso_field_offset(StgTSO, stack);
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
    tso_field(StgTSO, stack_size);

    struct_size(StgTSOProfInfo);
    struct_size(StgTSOParInfo);
    struct_size(StgTSOGranInfo);
    struct_size(StgTSODistInfo);

    opt_struct_size(StgTSOProfInfo,PROFILING);
    opt_struct_size(StgTSOParInfo,PAR);
    opt_struct_size(StgTSOGranInfo,GRAN);
    opt_struct_size(StgTSODistInfo,DIST);

    closure_field(StgUpdateFrame, updatee);

    closure_field(StgCatchFrame, handler);
    closure_field(StgCatchFrame, exceptions_blocked);

    closure_size(StgPAP);
    closure_field(StgPAP, n_args);
    closure_field(StgPAP, fun);
    closure_field(StgPAP, arity);
    closure_payload(StgPAP, payload);

311
    thunk_size(StgAP);
312 313 314 315
    closure_field(StgAP, n_args);
    closure_field(StgAP, fun);
    closure_payload(StgAP, payload);

316
    thunk_size(StgAP_STACK);
317 318 319
    closure_field(StgAP_STACK, size);
    closure_field(StgAP_STACK, fun);
    closure_payload(StgAP_STACK, payload);
320

321 322
    thunk_size(StgSelector);

323 324 325 326 327
    closure_field(StgInd, indirectee);

    closure_size(StgMutVar);
    closure_field(StgMutVar, var);

328 329 330 331 332 333 334 335 336 337 338 339
    closure_size(StgAtomicallyFrame);
    closure_field(StgAtomicallyFrame, code);

    closure_size(StgCatchSTMFrame);
    closure_field(StgCatchSTMFrame, handler);

    closure_size(StgCatchRetryFrame);
    closure_field(StgCatchRetryFrame, running_alt_code);
    closure_field(StgCatchRetryFrame, first_code);
    closure_field(StgCatchRetryFrame, alt_code);
    closure_field(StgCatchRetryFrame, first_code_trec);

340 341 342 343 344 345
    closure_size(StgWeak);
    closure_field(StgWeak,link);
    closure_field(StgWeak,key);
    closure_field(StgWeak,value);
    closure_field(StgWeak,finalizer);

346 347 348
    closure_size(StgDeadWeak);
    closure_field(StgDeadWeak,link);

349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
    closure_size(StgMVar);
    closure_field(StgMVar,head);
    closure_field(StgMVar,tail);
    closure_field(StgMVar,value);

    closure_size(StgBCO);
    closure_field(StgBCO, instrs);
    closure_field(StgBCO, literals);
    closure_field(StgBCO, ptrs);
    closure_field(StgBCO, itbls);
    closure_field(StgBCO, arity);
    closure_field(StgBCO, size);
    closure_payload(StgBCO, bitmap);

    closure_size(StgStableName);
    closure_field(StgStableName,sn);

    struct_field_("RtsFlags_ProfFlags_showCCSOnException",
		  RTS_FLAGS, ProfFlags.showCCSOnException);
    struct_field_("RtsFlags_DebugFlags_apply",
		  RTS_FLAGS, DebugFlags.apply);
    struct_field_("RtsFlags_DebugFlags_sanity",
		  RTS_FLAGS, DebugFlags.sanity);
    struct_field_("RtsFlags_DebugFlags_weak",
		  RTS_FLAGS, DebugFlags.weak);
    struct_field_("RtsFlags_GcFlags_initialStkSize",
		  RTS_FLAGS, GcFlags.initialStkSize);

    struct_size(StgFunInfoExtraFwd);
    struct_field(StgFunInfoExtraFwd, slow_apply);
    struct_field(StgFunInfoExtraFwd, fun_type);
    struct_field(StgFunInfoExtraFwd, arity);
381
    struct_field_("StgFunInfoExtraFwd_bitmap", StgFunInfoExtraFwd, b.bitmap);
382 383

    struct_size(StgFunInfoExtraRev);
384
    struct_field(StgFunInfoExtraRev, slow_apply_offset);
385 386
    struct_field(StgFunInfoExtraRev, fun_type);
    struct_field(StgFunInfoExtraRev, arity);
387
    struct_field_("StgFunInfoExtraRev_bitmap", StgFunInfoExtraRev, b.bitmap);
388 389 390 391 392 393 394 395

    struct_field(StgLargeBitmap, size);
    field_offset(StgLargeBitmap, bitmap);

    struct_size(snEntry);
    struct_field(snEntry,sn_obj);
    struct_field(snEntry,addr);

396
#ifdef mingw32_HOST_OS
397 398 399 400 401 402 403 404 405 406 407 408
    struct_size(StgAsyncIOResult);
    struct_field(StgAsyncIOResult, reqID);
    struct_field(StgAsyncIOResult, len);
    struct_field(StgAsyncIOResult, errCode);
#endif

    struct_size(MP_INT);
    struct_field(MP_INT,_mp_alloc);
    struct_field(MP_INT,_mp_size);
    struct_field(MP_INT,_mp_d);

    ctype(mp_limb_t);
409 410
    return 0;
}