1 /* ----------------------------------------------------------------------------
2 * $Id: InfoMacros.h,v 1.11 2000/04/05 15:27:59 simonmar 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(RBH_##entry); \
83 ED_RO_ StgInfoTable info; \
84 info_class INFO_TBL_CONST StgInfoTable 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(RBH_##entry), \
92 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
93 info_class INFO_TBL_CONST StgInfoTable info = { \
94 layout : { payload : {ptrs,nptrs} }, \
95 PROF_INFO(prof_type, prof_descr) \
96 SRT_INFO(type,srt_,srt_off_,srt_len_), \
97 INCLUDE_RBH_INFO(RBH_##info), \
105 INFO_TABLE_SRT(info, /* info-table label */ \
106 entry, /* entry code label */ \
107 ptrs, nptrs, /* closure layout info */\
108 srt_, srt_off_, srt_len_, /* SRT info */ \
109 type, /* closure type */ \
110 info_class, entry_class, /* C storage classes */ \
111 prof_descr, prof_type) /* profiling info */ \
112 entry_class(entry); \
113 info_class INFO_TBL_CONST StgInfoTable info = { \
114 layout : { payload : {ptrs,nptrs} }, \
115 PROF_INFO(prof_type, prof_descr) \
116 SRT_INFO(type,srt_,srt_off_,srt_len_), \
123 /* direct-return address info tables --------------------------------------*/
125 #if defined(GRAN) || defined(PAR)
128 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
129 type, info_class, entry_class, \
130 prof_descr, prof_type) \
131 entry_class(RBH_##entry); \
132 entry_class(entry); \
133 ED_RO_ StgInfoTable info; \
134 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
135 layout : { bitmap : (StgWord32)bitmap_ }, \
136 PROF_INFO(prof_type, prof_descr) \
137 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
138 INCLUDE_RBH_INFO(info), \
139 INIT_ENTRY(RBH_##entry), \
142 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
143 info_class INFO_TBL_CONST StgInfoTable info = { \
144 layout : { bitmap : (StgWord32)bitmap_ }, \
145 PROF_INFO(prof_type, prof_descr) \
146 SRT_INFO(type,srt_,srt_off_,srt_len_), \
147 INCLUDE_RBH_INFO(RBH_##info), \
154 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
155 type, info_class, entry_class, \
156 prof_descr, prof_type) \
157 entry_class(entry); \
158 info_class INFO_TBL_CONST StgInfoTable info = { \
159 layout : { bitmap : (StgWord32)bitmap_ }, \
160 PROF_INFO(prof_type, prof_descr) \
161 SRT_INFO(type,srt_,srt_off_,srt_len_), \
167 /* info-table without an SRT -----------------------------------------------*/
169 #if defined(GRAN) || defined(PAR)
172 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
173 entry_class, prof_descr, prof_type) \
174 entry_class(RBH_##entry); \
175 entry_class(entry); \
176 ED_RO_ StgInfoTable info; \
177 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
178 layout : { payload : {ptrs,nptrs} }, \
179 PROF_INFO(prof_type, prof_descr) \
181 INCLUDE_RBH_INFO(info), \
182 INIT_ENTRY(RBH_##entry), \
185 StgFunPtr RBH_##entry (void) { JMP_(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(RBH_##info), \
198 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
199 entry_class, prof_descr, prof_type) \
200 entry_class(entry); \
201 info_class INFO_TBL_CONST StgInfoTable info = { \
202 layout : { payload : {ptrs,nptrs} }, \
203 PROF_INFO(prof_type, prof_descr) \
211 /* special selector-thunk info table ---------------------------------------*/
213 #if defined(GRAN) || defined(PAR)
216 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
217 entry_class, prof_descr, prof_type) \
218 entry_class(RBH_##entry); \
219 entry_class(entry); \
220 ED_RO_ StgInfoTable info; \
221 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
222 layout : { selector_offset : offset }, \
223 PROF_INFO(prof_type, prof_descr) \
225 INCLUDE_RBH_INFO(info), \
226 INIT_ENTRY(RBH_##entry), \
229 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
230 info_class INFO_TBL_CONST StgInfoTable info = { \
231 layout : { selector_offset : offset }, \
232 PROF_INFO(prof_type, prof_descr) \
233 STD_INFO(THUNK_SELECTOR), \
234 INCLUDE_RBH_INFO(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), \
255 /* constructor info table --------------------------------------------------*/
258 INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class, \
259 entry_class, prof_descr, prof_type) \
260 entry_class(entry); \
261 info_class INFO_TBL_CONST StgInfoTable info = { \
262 layout : { payload : {ptrs,nptrs} }, \
263 PROF_INFO(prof_type, prof_descr) \
264 CONSTR_INFO(type_,tag_), \
269 #define constrTag(con) (get_itbl(con)->srt_len)
271 /* return-vectors ----------------------------------------------------------*/
273 /* vectored-return info tables have the vector slammed up against the
274 * start of the info table.
276 * A vectored-return address always has an SRT and a bitmap-style
277 * layout field, so we only need one macro for these.
280 #ifdef TABLES_NEXT_TO_CODE
317 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
320 info_class INFO_TBL_CONST vec_info_2 info = { \
323 layout : { bitmap : (StgWord32)bitmap_ }, \
324 SRT_INFO(type,srt_,srt_off_,srt_len_) \
328 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
330 alt_1, alt_2, alt_3 \
332 info_class INFO_TBL_CONST vec_info_3 info = { \
333 { alt_3, alt_2, alt_1 }, \
335 layout : { bitmap : (StgWord32)bitmap_ }, \
336 SRT_INFO(type,srt_,srt_off_,srt_len_) \
340 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
342 alt_1, alt_2, alt_3, alt_4 \
344 info_class INFO_TBL_CONST vec_info_4 info = { \
345 { alt_4, alt_3, alt_2, alt_1 }, \
347 layout : { bitmap : (StgWord32)bitmap_ }, \
348 SRT_INFO(type,srt_,srt_off_,srt_len_) \
352 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
354 alt_1, alt_2, alt_3, alt_4, \
357 info_class INFO_TBL_CONST vec_info_5 info = { \
358 { alt_5, alt_4, alt_3, alt_2, \
361 layout : { bitmap : (StgWord32)bitmap_ }, \
362 SRT_INFO(type,srt_,srt_off_,srt_len_) \
366 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
368 alt_1, alt_2, alt_3, alt_4, \
371 info_class INFO_TBL_CONST vec_info_6 info = { \
372 { alt_6, alt_5, alt_4, alt_3, \
375 layout : { bitmap : (StgWord32)bitmap_ }, \
376 SRT_INFO(type,srt_,srt_off_,srt_len_) \
380 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
382 alt_1, alt_2, alt_3, alt_4, \
383 alt_5, alt_6, alt_7 \
385 info_class INFO_TBL_CONST vec_info_7 info = { \
386 { alt_7, alt_6, alt_5, alt_4, \
387 alt_3, alt_2, alt_1 }, \
389 layout : { bitmap : (StgWord32)bitmap_ }, \
390 SRT_INFO(type,srt_,srt_off_,srt_len_) \
394 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
396 alt_1, alt_2, alt_3, alt_4, \
397 alt_5, alt_6, alt_7, alt_8 \
399 info_class INFO_TBL_CONST vec_info_8 info = { \
400 { alt_8, alt_7, alt_6, alt_5, \
401 alt_4, alt_3, alt_2, alt_1 }, \
403 layout : { bitmap : (StgWord32)bitmap_ }, \
404 SRT_INFO(type,srt_,srt_off_,srt_len_) \
411 /* We have to define these structure to work around a bug in gcc: if we
412 * try to initialise the vector directly (it's defined as a zero-length
413 * array tacked on the end of the info table structor), then gcc silently
414 * throws away our vector table sometimes.
452 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
455 info_class INFO_TBL_CONST vec_info_2 info = { \
456 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
457 SRT_INFO(type,srt_,srt_off_,srt_len_), \
460 vec : { alt_1, alt_2 } \
463 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
465 alt_1, alt_2, alt_3 \
467 info_class INFO_TBL_CONST vec_info_3 info = { \
468 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
469 SRT_INFO(type,srt_,srt_off_,srt_len_), \
472 vec : { alt_1, alt_2, alt_3 } \
475 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
477 alt_1, alt_2, alt_3, alt_4 \
479 info_class INFO_TBL_CONST vec_info_4 info = { \
480 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
481 SRT_INFO(type,srt_,srt_off_,srt_len_), \
484 vec : { alt_1, alt_2, alt_3, alt_4 } \
487 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
489 alt_1, alt_2, alt_3, alt_4, \
492 info_class INFO_TBL_CONST vec_info_5 info = { \
493 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
494 SRT_INFO(type,srt_,srt_off_,srt_len_), \
497 vec : { alt_1, alt_2, alt_3, alt_4, \
501 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
503 alt_1, alt_2, alt_3, alt_4, \
506 info_class INFO_TBL_CONST vec_info_6 info = { \
507 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
508 SRT_INFO(type,srt_,srt_off_,srt_len_), \
511 vec : { alt_1, alt_2, alt_3, alt_4, \
515 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
517 alt_1, alt_2, alt_3, alt_4, \
518 alt_5, alt_6, alt_7 \
520 info_class INFO_TBL_CONST vec_info_7 info = { \
521 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
522 SRT_INFO(type,srt_,srt_off_,srt_len_), \
525 vec : { alt_1, alt_2, alt_3, alt_4, \
526 alt_5, alt_6, alt_7 } \
529 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
531 alt_1, alt_2, alt_3, alt_4, \
532 alt_5, alt_6, alt_7, alt_8 \
534 info_class INFO_TBL_CONST vec_info_8 info = { \
535 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
536 SRT_INFO(type,srt_,srt_off_,srt_len_), \
539 vec : { alt_1, alt_2, alt_3, alt_4, \
540 alt_5, alt_6, alt_7, alt_8 } \
543 #endif /* TABLES_NEXT_TO_CODE */
545 /* For polymorphic activation records, we need both a direct return
546 * address and a return vector:
549 typedef vec_info_8 StgPolyInfoTable;
551 #ifndef TABLES_NEXT_TO_CODE
553 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
554 srt_, srt_off_, srt_len_, \
555 type, info_class, entry_class \
557 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
558 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
559 SRT_INFO(type,srt_,srt_off_,srt_len_), \
560 INIT_ENTRY(nm##_entry), \
576 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
577 srt_, srt_off_, srt_len_, \
578 type, info_class, entry_class \
580 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
592 layout : { bitmap : (StgWord32)bitmap_ }, \
593 SRT_INFO(type,srt_,srt_off_,srt_len_), \
594 INIT_ENTRY(nm##_entry) \
601 static const StgSRT lbl = {
603 #define BITMAP(lbl,size) \
604 static const StgLargeBitmap lbl = { size, {
606 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
607 an entry in an SRT table with a reference to a closure that's
608 living in a DLL. See elsewhere for reasons as to why we need
609 to distinguish these kinds of references.
610 (ToDo: fill in a more precise href.)
612 #ifdef HAVE_WIN32_DLL_SUPPORT
613 #define DLL_SRT_ENTRY(x) ((StgClosure*)(((char*)&DLL_IMPORT_DATA_VAR(x)) + 1))
615 #define DLL_SRT_ENTRY(x) no-can-do
618 #endif /* INFOMACROS_H */