1 /* ----------------------------------------------------------------------------
2 * $Id: InfoMacros.h,v 1.16 2001/07/24 05:04:58 ken Exp $
4 * (c) The GHC Team, 1998-1999
6 * Macros for building and deconstructing info tables.
8 * -------------------------------------------------------------------------- */
13 #define STD_INFO(type_) \
18 #define SRT_INFO(type_,srt_,srt_off_,srt_len_) \
19 srt : (StgSRT *)((StgClosure **)srt_+srt_off_), \
23 #define CONSTR_INFO(type_,tag_) \
29 #define PROF_INFO(type_str, desc_str) \
31 closure_type: type_str, \
32 closure_desc: desc_str, \
35 #define PROF_INFO(type_str, desc_str)
38 #ifdef USE_MINIINTERPRETER
39 #define INIT_VECTOR {}
45 On the GranSim/GUM specific parts of the InfoTables (GRAN/PAR):
47 In both GranSim and GUM we use revertible black holes (RBH) when putting
48 an updatable closure into a packet for communication. The entry code for
49 an RBH performs standard blocking (as with any kind of BH). The info
50 table for the RBH resides just before the one for the std info
51 table. (NB: there is one RBH ITBL for every ITBL of an updatable
52 closure.) The @rbh_infoptr@ field in the ITBL points from the std ITBL to
53 the RBH ITBL and vice versa. This is used by the RBH_INFOPTR and
54 REVERT_INFOPTR macros to turn an updatable node into an RBH and vice
55 versa. Note, that the only case where we have to revert the RBH in its
56 original form is when a packet is sent back because of garbage collection
57 on another PE. In the RTS for GdH we will use this reversion mechanism in
58 order to deal with faults in the system.
59 ToDo: Check that RBHs are needed for all the info tables below. From a quick
60 check of the macros generated in the libs it seems that all of them are used
61 for generating THUNKs.
62 Possible optimisation: Note that any RBH ITBL is a fixed distance away from
63 the actual ITBL. We could inline this offset as a constant into the RTS and
64 avoid the rbh_infoptr fields altogether (Jim did that in the old RTS).
69 /* function/thunk info tables --------------------------------------------- */
71 #if defined(GRAN) || defined(PAR)
74 INFO_TABLE_SRT(info, /* info-table label */ \
75 entry, /* entry code label */ \
76 ptrs, nptrs, /* closure layout info */\
77 srt_, srt_off_, srt_len_, /* SRT info */ \
78 type, /* closure type */ \
79 info_class, entry_class, /* C storage classes */ \
80 prof_descr, prof_type) /* profiling info */ \
81 entry_class(stg_RBH_##entry); \
83 ED_RO_ StgInfoTable info; \
84 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
85 layout : { payload : {ptrs,nptrs} }, \
86 PROF_INFO(prof_type, prof_descr) \
87 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
88 INCLUDE_RBH_INFO(info), \
89 INIT_ENTRY(stg_RBH_##entry), \
92 StgFunPtr stg_RBH_##entry (void) { \
94 JMP_(stg_RBH_entry); \
97 info_class INFO_TBL_CONST StgInfoTable info = { \
98 layout : { payload : {ptrs,nptrs} }, \
99 PROF_INFO(prof_type, prof_descr) \
100 SRT_INFO(type,srt_,srt_off_,srt_len_), \
101 INCLUDE_RBH_INFO(stg_RBH_##info), \
109 INFO_TABLE_SRT(info, /* info-table label */ \
110 entry, /* entry code label */ \
111 ptrs, nptrs, /* closure layout info */\
112 srt_, srt_off_, srt_len_, /* SRT info */ \
113 type, /* closure type */ \
114 info_class, entry_class, /* C storage classes */ \
115 prof_descr, prof_type) /* profiling info */ \
116 entry_class(entry); \
117 info_class INFO_TBL_CONST StgInfoTable info = { \
118 layout : { payload : {ptrs,nptrs} }, \
119 PROF_INFO(prof_type, prof_descr) \
120 SRT_INFO(type,srt_,srt_off_,srt_len_), \
127 /* direct-return address info tables --------------------------------------*/
129 #if defined(GRAN) || defined(PAR)
132 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
133 type, info_class, entry_class, \
134 prof_descr, prof_type) \
135 entry_class(stg_RBH_##entry); \
136 entry_class(entry); \
137 ED_RO_ StgInfoTable info; \
138 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
139 layout : { bitmap : (StgWord)bitmap_ }, \
140 PROF_INFO(prof_type, prof_descr) \
141 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
142 INCLUDE_RBH_INFO(info), \
143 INIT_ENTRY(stg_RBH_##entry), \
146 StgFunPtr stg_RBH_##entry (void) { \
148 JMP_(stg_RBH_entry); \
151 info_class INFO_TBL_CONST StgInfoTable info = { \
152 layout : { bitmap : (StgWord)bitmap_ }, \
153 PROF_INFO(prof_type, prof_descr) \
154 SRT_INFO(type,srt_,srt_off_,srt_len_), \
155 INCLUDE_RBH_INFO(stg_RBH_##info), \
163 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
164 type, info_class, entry_class, \
165 prof_descr, prof_type) \
166 entry_class(entry); \
167 info_class INFO_TBL_CONST StgInfoTable info = { \
168 layout : { bitmap : (StgWord)bitmap_ }, \
169 PROF_INFO(prof_type, prof_descr) \
170 SRT_INFO(type,srt_,srt_off_,srt_len_), \
176 /* info-table without an SRT -----------------------------------------------*/
178 #if defined(GRAN) || defined(PAR)
181 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
182 entry_class, prof_descr, prof_type) \
183 entry_class(stg_RBH_##entry); \
184 entry_class(entry); \
185 ED_ StgInfoTable info; \
186 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
187 layout : { payload : {ptrs,nptrs} }, \
188 PROF_INFO(prof_type, prof_descr) \
190 INCLUDE_RBH_INFO(info), \
191 INIT_ENTRY(stg_RBH_##entry), \
194 StgFunPtr stg_RBH_##entry (void) { \
196 JMP_(stg_RBH_entry); \
199 info_class INFO_TBL_CONST StgInfoTable info = { \
200 layout : { payload : {ptrs,nptrs} }, \
201 PROF_INFO(prof_type, prof_descr) \
203 INCLUDE_RBH_INFO(stg_RBH_##info), \
211 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
212 entry_class, prof_descr, prof_type) \
213 entry_class(entry); \
214 info_class INFO_TBL_CONST StgInfoTable info = { \
215 layout : { payload : {ptrs,nptrs} }, \
216 PROF_INFO(prof_type, prof_descr) \
224 /* special selector-thunk info table ---------------------------------------*/
226 #if defined(GRAN) || defined(PAR)
229 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
230 entry_class, prof_descr, prof_type) \
231 entry_class(stg_RBH_##entry); \
232 entry_class(entry); \
233 ED_RO_ StgInfoTable info; \
234 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
235 layout : { selector_offset : offset }, \
236 PROF_INFO(prof_type, prof_descr) \
238 INCLUDE_RBH_INFO(info), \
239 INIT_ENTRY(stg_RBH_##entry), \
242 StgFunPtr stg_RBH_##entry (void) { \
244 JMP_(stg_RBH_entry); \
247 info_class INFO_TBL_CONST StgInfoTable info = { \
248 layout : { selector_offset : offset }, \
249 PROF_INFO(prof_type, prof_descr) \
250 STD_INFO(THUNK_SELECTOR), \
251 INCLUDE_RBH_INFO(stg_RBH_##info), \
259 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
260 entry_class, prof_descr, prof_type) \
261 entry_class(entry); \
262 info_class INFO_TBL_CONST StgInfoTable info = { \
263 layout : { selector_offset : offset }, \
264 PROF_INFO(prof_type, prof_descr) \
265 STD_INFO(THUNK_SELECTOR), \
272 /* constructor info table --------------------------------------------------*/
275 INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class, \
276 entry_class, prof_descr, prof_type) \
277 entry_class(entry); \
278 info_class INFO_TBL_CONST StgInfoTable info = { \
279 layout : { payload : {ptrs,nptrs} }, \
280 PROF_INFO(prof_type, prof_descr) \
281 CONSTR_INFO(type_,tag_), \
286 #define constrTag(con) (get_itbl(con)->srt_len)
288 /* return-vectors ----------------------------------------------------------*/
290 /* vectored-return info tables have the vector slammed up against the
291 * start of the info table.
293 * A vectored-return address always has an SRT and a bitmap-style
294 * layout field, so we only need one macro for these.
297 #ifdef TABLES_NEXT_TO_CODE
334 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
337 info_class INFO_TBL_CONST vec_info_2 info = { \
340 layout : { bitmap : (StgWord)bitmap_ }, \
341 SRT_INFO(type,srt_,srt_off_,srt_len_) \
345 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
347 alt_1, alt_2, alt_3 \
349 info_class INFO_TBL_CONST vec_info_3 info = { \
350 { alt_3, alt_2, alt_1 }, \
352 layout : { bitmap : (StgWord)bitmap_ }, \
353 SRT_INFO(type,srt_,srt_off_,srt_len_) \
357 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
359 alt_1, alt_2, alt_3, alt_4 \
361 info_class INFO_TBL_CONST vec_info_4 info = { \
362 { alt_4, alt_3, alt_2, alt_1 }, \
364 layout : { bitmap : (StgWord)bitmap_ }, \
365 SRT_INFO(type,srt_,srt_off_,srt_len_) \
369 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
371 alt_1, alt_2, alt_3, alt_4, \
374 info_class INFO_TBL_CONST vec_info_5 info = { \
375 { alt_5, alt_4, alt_3, alt_2, \
378 layout : { bitmap : (StgWord)bitmap_ }, \
379 SRT_INFO(type,srt_,srt_off_,srt_len_) \
383 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
385 alt_1, alt_2, alt_3, alt_4, \
388 info_class INFO_TBL_CONST vec_info_6 info = { \
389 { alt_6, alt_5, alt_4, alt_3, \
392 layout : { bitmap : (StgWord)bitmap_ }, \
393 SRT_INFO(type,srt_,srt_off_,srt_len_) \
397 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
399 alt_1, alt_2, alt_3, alt_4, \
400 alt_5, alt_6, alt_7 \
402 info_class INFO_TBL_CONST vec_info_7 info = { \
403 { alt_7, alt_6, alt_5, alt_4, \
404 alt_3, alt_2, alt_1 }, \
406 layout : { bitmap : (StgWord)bitmap_ }, \
407 SRT_INFO(type,srt_,srt_off_,srt_len_) \
411 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
413 alt_1, alt_2, alt_3, alt_4, \
414 alt_5, alt_6, alt_7, alt_8 \
416 info_class INFO_TBL_CONST vec_info_8 info = { \
417 { alt_8, alt_7, alt_6, alt_5, \
418 alt_4, alt_3, alt_2, alt_1 }, \
420 layout : { bitmap : (StgWord)bitmap_ }, \
421 SRT_INFO(type,srt_,srt_off_,srt_len_) \
428 /* We have to define these structure to work around a bug in gcc: if we
429 * try to initialise the vector directly (it's defined as a zero-length
430 * array tacked on the end of the info table structor), then gcc silently
431 * throws away our vector table sometimes.
469 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
472 info_class INFO_TBL_CONST vec_info_2 info = { \
473 i : { layout : { bitmap : (StgWord)bitmap_ }, \
474 SRT_INFO(type,srt_,srt_off_,srt_len_), \
477 vec : { alt_1, alt_2 } \
480 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
482 alt_1, alt_2, alt_3 \
484 info_class INFO_TBL_CONST vec_info_3 info = { \
485 i : { layout : { bitmap : (StgWord)bitmap_ }, \
486 SRT_INFO(type,srt_,srt_off_,srt_len_), \
489 vec : { alt_1, alt_2, alt_3 } \
492 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
494 alt_1, alt_2, alt_3, alt_4 \
496 info_class INFO_TBL_CONST vec_info_4 info = { \
497 i : { layout : { bitmap : (StgWord)bitmap_ }, \
498 SRT_INFO(type,srt_,srt_off_,srt_len_), \
501 vec : { alt_1, alt_2, alt_3, alt_4 } \
504 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
506 alt_1, alt_2, alt_3, alt_4, \
509 info_class INFO_TBL_CONST vec_info_5 info = { \
510 i : { layout : { bitmap : (StgWord)bitmap_ }, \
511 SRT_INFO(type,srt_,srt_off_,srt_len_), \
514 vec : { alt_1, alt_2, alt_3, alt_4, \
518 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
520 alt_1, alt_2, alt_3, alt_4, \
523 info_class INFO_TBL_CONST vec_info_6 info = { \
524 i : { layout : { bitmap : (StgWord)bitmap_ }, \
525 SRT_INFO(type,srt_,srt_off_,srt_len_), \
528 vec : { alt_1, alt_2, alt_3, alt_4, \
532 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
534 alt_1, alt_2, alt_3, alt_4, \
535 alt_5, alt_6, alt_7 \
537 info_class INFO_TBL_CONST vec_info_7 info = { \
538 i : { layout : { bitmap : (StgWord)bitmap_ }, \
539 SRT_INFO(type,srt_,srt_off_,srt_len_), \
542 vec : { alt_1, alt_2, alt_3, alt_4, \
543 alt_5, alt_6, alt_7 } \
546 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
548 alt_1, alt_2, alt_3, alt_4, \
549 alt_5, alt_6, alt_7, alt_8 \
551 info_class INFO_TBL_CONST vec_info_8 info = { \
552 i : { layout : { bitmap : (StgWord)bitmap_ }, \
553 SRT_INFO(type,srt_,srt_off_,srt_len_), \
556 vec : { alt_1, alt_2, alt_3, alt_4, \
557 alt_5, alt_6, alt_7, alt_8 } \
560 #endif /* TABLES_NEXT_TO_CODE */
562 /* For polymorphic activation records, we need both a direct return
563 * address and a return vector:
566 typedef vec_info_8 StgPolyInfoTable;
568 #ifndef TABLES_NEXT_TO_CODE
570 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
571 srt_, srt_off_, srt_len_, \
572 type, info_class, entry_class \
574 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
575 i : { layout : { bitmap : (StgWord)bitmap_ }, \
576 SRT_INFO(type,srt_,srt_off_,srt_len_), \
577 INIT_ENTRY(nm##_entry), \
593 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
594 srt_, srt_off_, srt_len_, \
595 type, info_class, entry_class \
597 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
609 layout : { bitmap : (StgWord)bitmap_ }, \
610 SRT_INFO(type,srt_,srt_off_,srt_len_), \
611 INIT_ENTRY(nm##_entry) \
618 static const StgSRT lbl = {
620 #define BITMAP(lbl,size,contents) \
621 static const StgLargeBitmap lbl = { size, { contents } };
623 #if SIZEOF_VOID_P == 8
624 #define BITMAP_SWITCH64(small, large) small
625 #define BITMAP64(first, second) \
626 (((StgWord32)(first)) | ((StgWord)(StgWord32)(second) << 32))
628 #define BITMAP_SWITCH64(small, large) large
629 #define BITMAP64(first, second) first, second
631 #define BITMAP32(x) ((StgWord32)(x))
634 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
635 an entry in an SRT table with a reference to a closure that's
636 living in a DLL. See elsewhere for reasons as to why we need
637 to distinguish these kinds of references.
638 (ToDo: fill in a more precise href.)
640 #ifdef ENABLE_WIN32_DLL_SUPPORT /* mingw DietHEP doesn't seem to care either way */
641 #define DLL_SRT_ENTRY(x) ((StgClosure*)(((char*)&DLL_IMPORT_DATA_VAR(x)) + 1))
643 #define DLL_SRT_ENTRY(x) no-can-do
646 #endif /* INFOMACROS_H */