1 /* ----------------------------------------------------------------------------
2 * $Id: InfoMacros.h,v 1.20 2002/09/25 20:43:34 wolfgang 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)
39 On the GranSim/GUM specific parts of the InfoTables (GRAN/PAR):
41 In both GranSim and GUM we use revertible black holes (RBH) when putting
42 an updatable closure into a packet for communication. The entry code for
43 an RBH performs standard blocking (as with any kind of BH). The info
44 table for the RBH resides just before the one for the std info
45 table. (NB: there is one RBH ITBL for every ITBL of an updatable
46 closure.) The @rbh_infoptr@ field in the ITBL points from the std ITBL to
47 the RBH ITBL and vice versa. This is used by the RBH_INFOPTR and
48 REVERT_INFOPTR macros to turn an updatable node into an RBH and vice
49 versa. Note, that the only case where we have to revert the RBH in its
50 original form is when a packet is sent back because of garbage collection
51 on another PE. In the RTS for GdH we will use this reversion mechanism in
52 order to deal with faults in the system.
53 ToDo: Check that RBHs are needed for all the info tables below. From a quick
54 check of the macros generated in the libs it seems that all of them are used
55 for generating THUNKs.
56 Possible optimisation: Note that any RBH ITBL is a fixed distance away from
57 the actual ITBL. We could inline this offset as a constant into the RTS and
58 avoid the rbh_infoptr fields altogether (Jim did that in the old RTS).
63 /* function/thunk info tables --------------------------------------------- */
65 #if defined(GRAN) || defined(PAR)
68 INFO_TABLE_SRT(info, /* info-table label */ \
69 entry, /* entry code label */ \
70 ptrs, nptrs, /* closure layout info */\
71 srt_, srt_off_, srt_len_, /* SRT info */ \
72 type, /* closure type */ \
73 info_class, entry_class, /* C storage classes */ \
74 prof_descr, prof_type) /* profiling info */ \
75 entry_class(stg_RBH_##entry); \
77 ED_RO_ StgInfoTable info; \
78 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
79 layout : { payload : {ptrs,nptrs} }, \
80 PROF_INFO(prof_type, prof_descr) \
81 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
82 INCLUDE_RBH_INFO(info), \
83 INIT_ENTRY(stg_RBH_##entry) \
85 StgFunPtr stg_RBH_##entry (void) { \
87 JMP_(stg_RBH_entry); \
90 info_class INFO_TBL_CONST StgInfoTable info = { \
91 layout : { payload : {ptrs,nptrs} }, \
92 PROF_INFO(prof_type, prof_descr) \
93 SRT_INFO(type,srt_,srt_off_,srt_len_), \
94 INCLUDE_RBH_INFO(stg_RBH_##info), \
101 INFO_TABLE_SRT(info, /* info-table label */ \
102 entry, /* entry code label */ \
103 ptrs, nptrs, /* closure layout info */\
104 srt_, srt_off_, srt_len_, /* SRT info */ \
105 type, /* closure type */ \
106 info_class, entry_class, /* C storage classes */ \
107 prof_descr, prof_type) /* profiling info */ \
108 entry_class(entry); \
109 info_class INFO_TBL_CONST StgInfoTable info = { \
110 layout : { payload : {ptrs,nptrs} }, \
111 PROF_INFO(prof_type, prof_descr) \
112 SRT_INFO(type,srt_,srt_off_,srt_len_), \
118 /* direct-return address info tables --------------------------------------*/
120 #if defined(GRAN) || defined(PAR)
123 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
124 type, info_class, entry_class, \
125 prof_descr, prof_type) \
126 entry_class(stg_RBH_##entry); \
127 entry_class(entry); \
128 ED_RO_ StgInfoTable info; \
129 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
130 layout : { bitmap : (StgWord)bitmap_ }, \
131 PROF_INFO(prof_type, prof_descr) \
132 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
133 INCLUDE_RBH_INFO(info), \
134 INIT_ENTRY(stg_RBH_##entry) \
136 StgFunPtr stg_RBH_##entry (void) { \
138 JMP_(stg_RBH_entry); \
141 info_class INFO_TBL_CONST StgInfoTable info = { \
142 layout : { bitmap : (StgWord)bitmap_ }, \
143 PROF_INFO(prof_type, prof_descr) \
144 SRT_INFO(type,srt_,srt_off_,srt_len_), \
145 INCLUDE_RBH_INFO(stg_RBH_##info), \
152 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
153 type, info_class, entry_class, \
154 prof_descr, prof_type) \
155 entry_class(entry); \
156 info_class INFO_TBL_CONST StgInfoTable info = { \
157 layout : { bitmap : (StgWord)bitmap_ }, \
158 PROF_INFO(prof_type, prof_descr) \
159 SRT_INFO(type,srt_,srt_off_,srt_len_), \
164 /* info-table without an SRT -----------------------------------------------*/
166 #if defined(GRAN) || defined(PAR)
169 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
170 entry_class, prof_descr, prof_type) \
171 entry_class(stg_RBH_##entry); \
172 entry_class(entry); \
173 ED_ StgInfoTable info; \
174 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
175 layout : { payload : {ptrs,nptrs} }, \
176 PROF_INFO(prof_type, prof_descr) \
178 INCLUDE_RBH_INFO(info), \
179 INIT_ENTRY(stg_RBH_##entry) \
181 StgFunPtr stg_RBH_##entry (void) { \
183 JMP_(stg_RBH_entry); \
186 info_class INFO_TBL_CONST StgInfoTable info = { \
187 layout : { payload : {ptrs,nptrs} }, \
188 PROF_INFO(prof_type, prof_descr) \
190 INCLUDE_RBH_INFO(stg_RBH_##info), \
197 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
198 entry_class, prof_descr, prof_type) \
199 entry_class(entry); \
200 info_class INFO_TBL_CONST StgInfoTable info = { \
201 layout : { payload : {ptrs,nptrs} }, \
202 PROF_INFO(prof_type, prof_descr) \
209 /* special selector-thunk info table ---------------------------------------*/
211 #if defined(GRAN) || defined(PAR)
214 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
215 entry_class, prof_descr, prof_type) \
216 entry_class(stg_RBH_##entry); \
217 entry_class(entry); \
218 ED_RO_ StgInfoTable info; \
219 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
220 layout : { selector_offset : offset }, \
221 PROF_INFO(prof_type, prof_descr) \
223 INCLUDE_RBH_INFO(info), \
224 INIT_ENTRY(stg_RBH_##entry) \
226 StgFunPtr stg_RBH_##entry (void) { \
228 JMP_(stg_RBH_entry); \
231 info_class INFO_TBL_CONST StgInfoTable info = { \
232 layout : { selector_offset : offset }, \
233 PROF_INFO(prof_type, prof_descr) \
234 STD_INFO(THUNK_SELECTOR), \
235 INCLUDE_RBH_INFO(stg_RBH_##info), \
242 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
243 entry_class, prof_descr, prof_type) \
244 entry_class(entry); \
245 info_class INFO_TBL_CONST StgInfoTable info = { \
246 layout : { selector_offset : offset }, \
247 PROF_INFO(prof_type, prof_descr) \
248 STD_INFO(THUNK_SELECTOR), \
254 /* constructor info table --------------------------------------------------*/
257 INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class, \
258 entry_class, prof_descr, prof_type) \
259 entry_class(entry); \
260 info_class INFO_TBL_CONST StgInfoTable info = { \
261 layout : { payload : {ptrs,nptrs} }, \
262 PROF_INFO(prof_type, prof_descr) \
263 CONSTR_INFO(type_,tag_), \
267 #define constrTag(con) (get_itbl(con)->srt_len)
269 /* return-vectors ----------------------------------------------------------*/
271 /* vectored-return info tables have the vector slammed up against the
272 * start of the info table.
274 * A vectored-return address always has an SRT and a bitmap-style
275 * layout field, so we only need one macro for these.
278 #ifdef TABLES_NEXT_TO_CODE
315 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
318 info_class INFO_TBL_CONST vec_info_2 info = { \
321 layout : { bitmap : (StgWord)bitmap_ }, \
322 SRT_INFO(type,srt_,srt_off_,srt_len_) \
326 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
328 alt_1, alt_2, alt_3 \
330 info_class INFO_TBL_CONST vec_info_3 info = { \
331 { alt_3, alt_2, alt_1 }, \
333 layout : { bitmap : (StgWord)bitmap_ }, \
334 SRT_INFO(type,srt_,srt_off_,srt_len_) \
338 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
340 alt_1, alt_2, alt_3, alt_4 \
342 info_class INFO_TBL_CONST vec_info_4 info = { \
343 { alt_4, alt_3, alt_2, alt_1 }, \
345 layout : { bitmap : (StgWord)bitmap_ }, \
346 SRT_INFO(type,srt_,srt_off_,srt_len_) \
350 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
352 alt_1, alt_2, alt_3, alt_4, \
355 info_class INFO_TBL_CONST vec_info_5 info = { \
356 { alt_5, alt_4, alt_3, alt_2, \
359 layout : { bitmap : (StgWord)bitmap_ }, \
360 SRT_INFO(type,srt_,srt_off_,srt_len_) \
364 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
366 alt_1, alt_2, alt_3, alt_4, \
369 info_class INFO_TBL_CONST vec_info_6 info = { \
370 { alt_6, alt_5, alt_4, alt_3, \
373 layout : { bitmap : (StgWord)bitmap_ }, \
374 SRT_INFO(type,srt_,srt_off_,srt_len_) \
378 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
380 alt_1, alt_2, alt_3, alt_4, \
381 alt_5, alt_6, alt_7 \
383 info_class INFO_TBL_CONST vec_info_7 info = { \
384 { alt_7, alt_6, alt_5, alt_4, \
385 alt_3, alt_2, alt_1 }, \
387 layout : { bitmap : (StgWord)bitmap_ }, \
388 SRT_INFO(type,srt_,srt_off_,srt_len_) \
392 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
394 alt_1, alt_2, alt_3, alt_4, \
395 alt_5, alt_6, alt_7, alt_8 \
397 info_class INFO_TBL_CONST vec_info_8 info = { \
398 { alt_8, alt_7, alt_6, alt_5, \
399 alt_4, alt_3, alt_2, alt_1 }, \
401 layout : { bitmap : (StgWord)bitmap_ }, \
402 SRT_INFO(type,srt_,srt_off_,srt_len_) \
409 /* We have to define these structure to work around a bug in gcc: if we
410 * try to initialise the vector directly (it's defined as a zero-length
411 * array tacked on the end of the info table structor), then gcc silently
412 * throws away our vector table sometimes.
450 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
453 info_class INFO_TBL_CONST vec_info_2 info = { \
454 i : { layout : { bitmap : (StgWord)bitmap_ }, \
455 SRT_INFO(type,srt_,srt_off_,srt_len_), \
458 vec : { alt_1, alt_2 } \
461 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
463 alt_1, alt_2, alt_3 \
465 info_class INFO_TBL_CONST vec_info_3 info = { \
466 i : { layout : { bitmap : (StgWord)bitmap_ }, \
467 SRT_INFO(type,srt_,srt_off_,srt_len_), \
470 vec : { alt_1, alt_2, alt_3 } \
473 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
475 alt_1, alt_2, alt_3, alt_4 \
477 info_class INFO_TBL_CONST vec_info_4 info = { \
478 i : { layout : { bitmap : (StgWord)bitmap_ }, \
479 SRT_INFO(type,srt_,srt_off_,srt_len_), \
482 vec : { alt_1, alt_2, alt_3, alt_4 } \
485 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
487 alt_1, alt_2, alt_3, alt_4, \
490 info_class INFO_TBL_CONST vec_info_5 info = { \
491 i : { layout : { bitmap : (StgWord)bitmap_ }, \
492 SRT_INFO(type,srt_,srt_off_,srt_len_), \
495 vec : { alt_1, alt_2, alt_3, alt_4, \
499 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
501 alt_1, alt_2, alt_3, alt_4, \
504 info_class INFO_TBL_CONST vec_info_6 info = { \
505 i : { layout : { bitmap : (StgWord)bitmap_ }, \
506 SRT_INFO(type,srt_,srt_off_,srt_len_), \
509 vec : { alt_1, alt_2, alt_3, alt_4, \
513 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
515 alt_1, alt_2, alt_3, alt_4, \
516 alt_5, alt_6, alt_7 \
518 info_class INFO_TBL_CONST vec_info_7 info = { \
519 i : { layout : { bitmap : (StgWord)bitmap_ }, \
520 SRT_INFO(type,srt_,srt_off_,srt_len_), \
523 vec : { alt_1, alt_2, alt_3, alt_4, \
524 alt_5, alt_6, alt_7 } \
527 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
529 alt_1, alt_2, alt_3, alt_4, \
530 alt_5, alt_6, alt_7, alt_8 \
532 info_class INFO_TBL_CONST vec_info_8 info = { \
533 i : { layout : { bitmap : (StgWord)bitmap_ }, \
534 SRT_INFO(type,srt_,srt_off_,srt_len_), \
537 vec : { alt_1, alt_2, alt_3, alt_4, \
538 alt_5, alt_6, alt_7, alt_8 } \
541 #endif /* TABLES_NEXT_TO_CODE */
543 /* For polymorphic activation records, we need both a direct return
544 * address and a return vector:
547 typedef vec_info_8 StgPolyInfoTable;
549 #ifndef TABLES_NEXT_TO_CODE
551 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
552 srt_, srt_off_, srt_len_, \
553 type, info_class, entry_class \
555 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
556 i : { layout : { bitmap : (StgWord)bitmap_ }, \
557 SRT_INFO(type,srt_,srt_off_,srt_len_), \
558 INIT_ENTRY(nm##_entry) \
573 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
574 srt_, srt_off_, srt_len_, \
575 type, info_class, entry_class \
577 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
589 layout : { bitmap : (StgWord)bitmap_ }, \
590 SRT_INFO(type,srt_,srt_off_,srt_len_), \
591 INIT_ENTRY(nm##_entry) \
598 static const StgSRT lbl = {
600 #define BITMAP(lbl,size,contents) \
601 static const StgLargeBitmap lbl = { \
602 (size*4+SIZEOF_VOID_P-1)/SIZEOF_VOID_P, { contents } };
604 #if SIZEOF_VOID_P == 8
605 #define BITMAP_SWITCH64(small, large) small
606 #define BITMAP64(first, second) \
607 (((StgWord32)(first)) | ((StgWord)(StgWord32)(second) << 32))
609 #define BITMAP_SWITCH64(small, large) large
610 #define BITMAP64(first, second) first, second
612 #define BITMAP32(x) ((StgWord32)(x))
615 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
616 an entry in an SRT table with a reference to a closure that's
617 living in a DLL. See elsewhere for reasons as to why we need
618 to distinguish these kinds of references.
619 (ToDo: fill in a more precise href.)
621 #ifdef ENABLE_WIN32_DLL_SUPPORT /* mingw DietHEP doesn't seem to care either way */
622 #define DLL_SRT_ENTRY(x) ((StgClosure*)(((char*)&DLL_IMPORT_DATA_VAR(x)) + 1))
624 #define DLL_SRT_ENTRY(x) no-can-do
627 #endif /* INFOMACROS_H */