1 /* ----------------------------------------------------------------------------
2 * $Id: InfoMacros.h,v 1.18 2002/02/26 05:03:27 sof 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 /* Why no empty array initializer in the 'else' branch? sof 2/02 */
39 #ifdef USE_MINIINTERPRETER
40 #define INIT_VECTOR vector : {}
46 On the GranSim/GUM specific parts of the InfoTables (GRAN/PAR):
48 In both GranSim and GUM we use revertible black holes (RBH) when putting
49 an updatable closure into a packet for communication. The entry code for
50 an RBH performs standard blocking (as with any kind of BH). The info
51 table for the RBH resides just before the one for the std info
52 table. (NB: there is one RBH ITBL for every ITBL of an updatable
53 closure.) The @rbh_infoptr@ field in the ITBL points from the std ITBL to
54 the RBH ITBL and vice versa. This is used by the RBH_INFOPTR and
55 REVERT_INFOPTR macros to turn an updatable node into an RBH and vice
56 versa. Note, that the only case where we have to revert the RBH in its
57 original form is when a packet is sent back because of garbage collection
58 on another PE. In the RTS for GdH we will use this reversion mechanism in
59 order to deal with faults in the system.
60 ToDo: Check that RBHs are needed for all the info tables below. From a quick
61 check of the macros generated in the libs it seems that all of them are used
62 for generating THUNKs.
63 Possible optimisation: Note that any RBH ITBL is a fixed distance away from
64 the actual ITBL. We could inline this offset as a constant into the RTS and
65 avoid the rbh_infoptr fields altogether (Jim did that in the old RTS).
70 /* function/thunk info tables --------------------------------------------- */
72 #if defined(GRAN) || defined(PAR)
75 INFO_TABLE_SRT(info, /* info-table label */ \
76 entry, /* entry code label */ \
77 ptrs, nptrs, /* closure layout info */\
78 srt_, srt_off_, srt_len_, /* SRT info */ \
79 type, /* closure type */ \
80 info_class, entry_class, /* C storage classes */ \
81 prof_descr, prof_type) /* profiling info */ \
82 entry_class(stg_RBH_##entry); \
84 ED_RO_ StgInfoTable info; \
85 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
86 layout : { payload : {ptrs,nptrs} }, \
87 PROF_INFO(prof_type, prof_descr) \
88 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
89 INCLUDE_RBH_INFO(info), \
90 INIT_ENTRY(stg_RBH_##entry), \
93 StgFunPtr stg_RBH_##entry (void) { \
95 JMP_(stg_RBH_entry); \
98 info_class INFO_TBL_CONST StgInfoTable info = { \
99 layout : { payload : {ptrs,nptrs} }, \
100 PROF_INFO(prof_type, prof_descr) \
101 SRT_INFO(type,srt_,srt_off_,srt_len_), \
102 INCLUDE_RBH_INFO(stg_RBH_##info), \
110 INFO_TABLE_SRT(info, /* info-table label */ \
111 entry, /* entry code label */ \
112 ptrs, nptrs, /* closure layout info */\
113 srt_, srt_off_, srt_len_, /* SRT info */ \
114 type, /* closure type */ \
115 info_class, entry_class, /* C storage classes */ \
116 prof_descr, prof_type) /* profiling info */ \
117 entry_class(entry); \
118 info_class INFO_TBL_CONST StgInfoTable info = { \
119 layout : { payload : {ptrs,nptrs} }, \
120 PROF_INFO(prof_type, prof_descr) \
121 SRT_INFO(type,srt_,srt_off_,srt_len_), \
128 /* direct-return address info tables --------------------------------------*/
130 #if defined(GRAN) || defined(PAR)
133 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
134 type, info_class, entry_class, \
135 prof_descr, prof_type) \
136 entry_class(stg_RBH_##entry); \
137 entry_class(entry); \
138 ED_RO_ StgInfoTable info; \
139 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
140 layout : { bitmap : (StgWord)bitmap_ }, \
141 PROF_INFO(prof_type, prof_descr) \
142 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
143 INCLUDE_RBH_INFO(info), \
144 INIT_ENTRY(stg_RBH_##entry), \
147 StgFunPtr stg_RBH_##entry (void) { \
149 JMP_(stg_RBH_entry); \
152 info_class INFO_TBL_CONST StgInfoTable info = { \
153 layout : { bitmap : (StgWord)bitmap_ }, \
154 PROF_INFO(prof_type, prof_descr) \
155 SRT_INFO(type,srt_,srt_off_,srt_len_), \
156 INCLUDE_RBH_INFO(stg_RBH_##info), \
164 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
165 type, info_class, entry_class, \
166 prof_descr, prof_type) \
167 entry_class(entry); \
168 info_class INFO_TBL_CONST StgInfoTable info = { \
169 layout : { bitmap : (StgWord)bitmap_ }, \
170 PROF_INFO(prof_type, prof_descr) \
171 SRT_INFO(type,srt_,srt_off_,srt_len_), \
177 /* info-table without an SRT -----------------------------------------------*/
179 #if defined(GRAN) || defined(PAR)
182 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
183 entry_class, prof_descr, prof_type) \
184 entry_class(stg_RBH_##entry); \
185 entry_class(entry); \
186 ED_ StgInfoTable info; \
187 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
188 layout : { payload : {ptrs,nptrs} }, \
189 PROF_INFO(prof_type, prof_descr) \
191 INCLUDE_RBH_INFO(info), \
192 INIT_ENTRY(stg_RBH_##entry), \
195 StgFunPtr stg_RBH_##entry (void) { \
197 JMP_(stg_RBH_entry); \
200 info_class INFO_TBL_CONST StgInfoTable info = { \
201 layout : { payload : {ptrs,nptrs} }, \
202 PROF_INFO(prof_type, prof_descr) \
204 INCLUDE_RBH_INFO(stg_RBH_##info), \
212 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
213 entry_class, prof_descr, prof_type) \
214 entry_class(entry); \
215 info_class INFO_TBL_CONST StgInfoTable info = { \
216 layout : { payload : {ptrs,nptrs} }, \
217 PROF_INFO(prof_type, prof_descr) \
225 /* special selector-thunk info table ---------------------------------------*/
227 #if defined(GRAN) || defined(PAR)
230 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
231 entry_class, prof_descr, prof_type) \
232 entry_class(stg_RBH_##entry); \
233 entry_class(entry); \
234 ED_RO_ StgInfoTable info; \
235 info_class INFO_TBL_CONST StgInfoTable stg_RBH_##info = { \
236 layout : { selector_offset : offset }, \
237 PROF_INFO(prof_type, prof_descr) \
239 INCLUDE_RBH_INFO(info), \
240 INIT_ENTRY(stg_RBH_##entry), \
243 StgFunPtr stg_RBH_##entry (void) { \
245 JMP_(stg_RBH_entry); \
248 info_class INFO_TBL_CONST StgInfoTable info = { \
249 layout : { selector_offset : offset }, \
250 PROF_INFO(prof_type, prof_descr) \
251 STD_INFO(THUNK_SELECTOR), \
252 INCLUDE_RBH_INFO(stg_RBH_##info), \
260 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
261 entry_class, prof_descr, prof_type) \
262 entry_class(entry); \
263 info_class INFO_TBL_CONST StgInfoTable info = { \
264 layout : { selector_offset : offset }, \
265 PROF_INFO(prof_type, prof_descr) \
266 STD_INFO(THUNK_SELECTOR), \
273 /* constructor info table --------------------------------------------------*/
276 INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class, \
277 entry_class, prof_descr, prof_type) \
278 entry_class(entry); \
279 info_class INFO_TBL_CONST StgInfoTable info = { \
280 layout : { payload : {ptrs,nptrs} }, \
281 PROF_INFO(prof_type, prof_descr) \
282 CONSTR_INFO(type_,tag_), \
287 #define constrTag(con) (get_itbl(con)->srt_len)
289 /* return-vectors ----------------------------------------------------------*/
291 /* vectored-return info tables have the vector slammed up against the
292 * start of the info table.
294 * A vectored-return address always has an SRT and a bitmap-style
295 * layout field, so we only need one macro for these.
298 #ifdef TABLES_NEXT_TO_CODE
335 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
338 info_class INFO_TBL_CONST vec_info_2 info = { \
341 layout : { bitmap : (StgWord)bitmap_ }, \
342 SRT_INFO(type,srt_,srt_off_,srt_len_) \
346 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
348 alt_1, alt_2, alt_3 \
350 info_class INFO_TBL_CONST vec_info_3 info = { \
351 { alt_3, alt_2, alt_1 }, \
353 layout : { bitmap : (StgWord)bitmap_ }, \
354 SRT_INFO(type,srt_,srt_off_,srt_len_) \
358 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
360 alt_1, alt_2, alt_3, alt_4 \
362 info_class INFO_TBL_CONST vec_info_4 info = { \
363 { alt_4, alt_3, alt_2, alt_1 }, \
365 layout : { bitmap : (StgWord)bitmap_ }, \
366 SRT_INFO(type,srt_,srt_off_,srt_len_) \
370 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
372 alt_1, alt_2, alt_3, alt_4, \
375 info_class INFO_TBL_CONST vec_info_5 info = { \
376 { alt_5, alt_4, alt_3, alt_2, \
379 layout : { bitmap : (StgWord)bitmap_ }, \
380 SRT_INFO(type,srt_,srt_off_,srt_len_) \
384 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
386 alt_1, alt_2, alt_3, alt_4, \
389 info_class INFO_TBL_CONST vec_info_6 info = { \
390 { alt_6, alt_5, alt_4, alt_3, \
393 layout : { bitmap : (StgWord)bitmap_ }, \
394 SRT_INFO(type,srt_,srt_off_,srt_len_) \
398 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
400 alt_1, alt_2, alt_3, alt_4, \
401 alt_5, alt_6, alt_7 \
403 info_class INFO_TBL_CONST vec_info_7 info = { \
404 { alt_7, alt_6, alt_5, alt_4, \
405 alt_3, alt_2, alt_1 }, \
407 layout : { bitmap : (StgWord)bitmap_ }, \
408 SRT_INFO(type,srt_,srt_off_,srt_len_) \
412 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
414 alt_1, alt_2, alt_3, alt_4, \
415 alt_5, alt_6, alt_7, alt_8 \
417 info_class INFO_TBL_CONST vec_info_8 info = { \
418 { alt_8, alt_7, alt_6, alt_5, \
419 alt_4, alt_3, alt_2, alt_1 }, \
421 layout : { bitmap : (StgWord)bitmap_ }, \
422 SRT_INFO(type,srt_,srt_off_,srt_len_) \
429 /* We have to define these structure to work around a bug in gcc: if we
430 * try to initialise the vector directly (it's defined as a zero-length
431 * array tacked on the end of the info table structor), then gcc silently
432 * throws away our vector table sometimes.
470 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
473 info_class INFO_TBL_CONST vec_info_2 info = { \
474 i : { layout : { bitmap : (StgWord)bitmap_ }, \
475 SRT_INFO(type,srt_,srt_off_,srt_len_), \
478 vec : { alt_1, alt_2 } \
481 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
483 alt_1, alt_2, alt_3 \
485 info_class INFO_TBL_CONST vec_info_3 info = { \
486 i : { layout : { bitmap : (StgWord)bitmap_ }, \
487 SRT_INFO(type,srt_,srt_off_,srt_len_), \
490 vec : { alt_1, alt_2, alt_3 } \
493 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
495 alt_1, alt_2, alt_3, alt_4 \
497 info_class INFO_TBL_CONST vec_info_4 info = { \
498 i : { layout : { bitmap : (StgWord)bitmap_ }, \
499 SRT_INFO(type,srt_,srt_off_,srt_len_), \
502 vec : { alt_1, alt_2, alt_3, alt_4 } \
505 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
507 alt_1, alt_2, alt_3, alt_4, \
510 info_class INFO_TBL_CONST vec_info_5 info = { \
511 i : { layout : { bitmap : (StgWord)bitmap_ }, \
512 SRT_INFO(type,srt_,srt_off_,srt_len_), \
515 vec : { alt_1, alt_2, alt_3, alt_4, \
519 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
521 alt_1, alt_2, alt_3, alt_4, \
524 info_class INFO_TBL_CONST vec_info_6 info = { \
525 i : { layout : { bitmap : (StgWord)bitmap_ }, \
526 SRT_INFO(type,srt_,srt_off_,srt_len_), \
529 vec : { alt_1, alt_2, alt_3, alt_4, \
533 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
535 alt_1, alt_2, alt_3, alt_4, \
536 alt_5, alt_6, alt_7 \
538 info_class INFO_TBL_CONST vec_info_7 info = { \
539 i : { layout : { bitmap : (StgWord)bitmap_ }, \
540 SRT_INFO(type,srt_,srt_off_,srt_len_), \
543 vec : { alt_1, alt_2, alt_3, alt_4, \
544 alt_5, alt_6, alt_7 } \
547 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
549 alt_1, alt_2, alt_3, alt_4, \
550 alt_5, alt_6, alt_7, alt_8 \
552 info_class INFO_TBL_CONST vec_info_8 info = { \
553 i : { layout : { bitmap : (StgWord)bitmap_ }, \
554 SRT_INFO(type,srt_,srt_off_,srt_len_), \
557 vec : { alt_1, alt_2, alt_3, alt_4, \
558 alt_5, alt_6, alt_7, alt_8 } \
561 #endif /* TABLES_NEXT_TO_CODE */
563 /* For polymorphic activation records, we need both a direct return
564 * address and a return vector:
567 typedef vec_info_8 StgPolyInfoTable;
569 #ifndef TABLES_NEXT_TO_CODE
571 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
572 srt_, srt_off_, srt_len_, \
573 type, info_class, entry_class \
575 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
576 i : { layout : { bitmap : (StgWord)bitmap_ }, \
577 SRT_INFO(type,srt_,srt_off_,srt_len_), \
578 INIT_ENTRY(nm##_entry), \
594 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
595 srt_, srt_off_, srt_len_, \
596 type, info_class, entry_class \
598 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
610 layout : { bitmap : (StgWord)bitmap_ }, \
611 SRT_INFO(type,srt_,srt_off_,srt_len_), \
612 INIT_ENTRY(nm##_entry) \
619 static const StgSRT lbl = {
621 #define BITMAP(lbl,size,contents) \
622 static const StgLargeBitmap lbl = { \
623 (size*4+SIZEOF_VOID_P-1)/SIZEOF_VOID_P, { contents } };
625 #if SIZEOF_VOID_P == 8
626 #define BITMAP_SWITCH64(small, large) small
627 #define BITMAP64(first, second) \
628 (((StgWord32)(first)) | ((StgWord)(StgWord32)(second) << 32))
630 #define BITMAP_SWITCH64(small, large) large
631 #define BITMAP64(first, second) first, second
633 #define BITMAP32(x) ((StgWord32)(x))
636 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
637 an entry in an SRT table with a reference to a closure that's
638 living in a DLL. See elsewhere for reasons as to why we need
639 to distinguish these kinds of references.
640 (ToDo: fill in a more precise href.)
642 #ifdef ENABLE_WIN32_DLL_SUPPORT /* mingw DietHEP doesn't seem to care either way */
643 #define DLL_SRT_ENTRY(x) ((StgClosure*)(((char*)&DLL_IMPORT_DATA_VAR(x)) + 1))
645 #define DLL_SRT_ENTRY(x) no-can-do
648 #endif /* INFOMACROS_H */