1 /* ----------------------------------------------------------------------------
2 * $Id: InfoMacros.h,v 1.9 2000/01/13 14:34:00 hwloidl 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_) \
28 #ifdef USE_MINIINTERPRETER
29 #define INIT_VECTOR {}
35 On the GRAN/PAR specific parts of the InfoTables:
37 In both GranSim and GUM we use revertible black holes (RBH) when putting
38 an updatable closure into a packet for communication. The entry code for
39 an RBH performs standard blocking (as with any kind of BH). The info
40 table for the RBH resides just before the one for the std info
41 table. (NB: there is one RBH ITBL for every ITBL of an updatable
42 closure.) The @rbh_infoptr@ field in the ITBL points from the std ITBL to
43 the RBH ITBL and vice versa. This is used by the RBH_INFOPTR and
44 REVERT_INFOPTR macros to turn an updatable node into an RBH and vice
45 versa. Note, that the only case where we have to revert the RBH in its
46 original form is when a packet is sent back because of garbage collection
47 on another PE. In the RTS for GdH we will use this reversion mechanism in
48 order to deal with faults in the system.
49 ToDo: Check that RBHs are needed for all the info tables below. From a quick
50 check of the macros generated in the libs it seems that all of them are used
51 for generating THUNKs.
52 Possible optimisation: Note that any RBH ITBL is a fixed distance away from
53 the actual ITBL. We could inline this offset as a constant into the RTS and
54 avoid the rbh_infoptr fields altogether (Jim did that in the old RTS).
59 /* function/thunk info tables --------------------------------------------- */
61 #if defined(GRAN) || defined(PAR)
64 INFO_TABLE_SRT(info, /* info-table label */ \
65 entry, /* entry code label */ \
66 ptrs, nptrs, /* closure layout info */\
67 srt_, srt_off_, srt_len_, /* SRT info */ \
68 type, /* closure type */ \
69 info_class, entry_class, /* C storage classes */ \
70 prof_descr, prof_type) /* profiling info */ \
71 entry_class(RBH_##entry); \
73 info_class INFO_TBL_CONST StgInfoTable info; \
74 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
75 layout : { payload : {ptrs,nptrs} }, \
76 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
77 INCLUDE_RBH_INFO(info), \
78 INIT_ENTRY(RBH_##entry), \
81 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
82 info_class INFO_TBL_CONST StgInfoTable info = { \
83 layout : { payload : {ptrs,nptrs} }, \
84 SRT_INFO(type,srt_,srt_off_,srt_len_), \
85 INCLUDE_RBH_INFO(RBH_##info), \
93 INFO_TABLE_SRT(info, /* info-table label */ \
94 entry, /* entry code label */ \
95 ptrs, nptrs, /* closure layout info */\
96 srt_, srt_off_, srt_len_, /* SRT info */ \
97 type, /* closure type */ \
98 info_class, entry_class, /* C storage classes */ \
99 prof_descr, prof_type) /* profiling info */ \
100 entry_class(entry); \
101 info_class INFO_TBL_CONST StgInfoTable info = { \
102 layout : { payload : {ptrs,nptrs} }, \
103 SRT_INFO(type,srt_,srt_off_,srt_len_), \
110 /* direct-return address info tables --------------------------------------*/
112 #if defined(GRAN) || defined(PAR)
115 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
116 type, info_class, entry_class, \
117 prof_descr, prof_type) \
118 entry_class(RBH_##entry); \
119 entry_class(entry); \
120 info_class INFO_TBL_CONST StgInfoTable info; \
121 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
122 layout : { bitmap : (StgWord32)bitmap_ }, \
123 SRT_INFO(RBH,srt_,srt_off_,srt_len_), \
124 INCLUDE_RBH_INFO(info), \
125 INIT_ENTRY(RBH_##entry), \
128 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
129 info_class INFO_TBL_CONST StgInfoTable info = { \
130 layout : { bitmap : (StgWord32)bitmap_ }, \
131 SRT_INFO(type,srt_,srt_off_,srt_len_), \
132 INCLUDE_RBH_INFO(RBH_##info), \
139 INFO_TABLE_SRT_BITMAP(info, entry, bitmap_, srt_, srt_off_, srt_len_, \
140 type, info_class, entry_class, \
141 prof_descr, prof_type) \
142 entry_class(entry); \
143 info_class INFO_TBL_CONST StgInfoTable info = { \
144 layout : { bitmap : (StgWord32)bitmap_ }, \
145 SRT_INFO(type,srt_,srt_off_,srt_len_), \
151 /* info-table without an SRT -----------------------------------------------*/
153 #if defined(GRAN) || defined(PAR)
156 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
157 entry_class, prof_descr, prof_type) \
158 entry_class(RBH_##entry); \
159 entry_class(entry); \
160 info_class INFO_TBL_CONST StgInfoTable info; \
161 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
162 layout : { payload : {ptrs,nptrs} }, \
164 INCLUDE_RBH_INFO(info), \
165 INIT_ENTRY(RBH_##entry), \
168 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
169 info_class INFO_TBL_CONST StgInfoTable info = { \
170 layout : { payload : {ptrs,nptrs} }, \
172 INCLUDE_RBH_INFO(RBH_##info), \
180 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
181 entry_class, prof_descr, prof_type) \
182 entry_class(entry); \
183 info_class INFO_TBL_CONST StgInfoTable info = { \
184 layout : { payload : {ptrs,nptrs} }, \
192 /* special selector-thunk info table ---------------------------------------*/
194 #if defined(GRAN) || defined(PAR)
197 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
198 entry_class, prof_descr, prof_type) \
199 entry_class(RBH_##entry); \
200 entry_class(entry); \
201 info_class INFO_TBL_CONST StgInfoTable info; \
202 info_class INFO_TBL_CONST StgInfoTable RBH_##info = { \
203 layout : { selector_offset : offset }, \
205 INCLUDE_RBH_INFO(info), \
206 INIT_ENTRY(RBH_##entry), \
209 StgFunPtr RBH_##entry (void) { JMP_(RBH_entry); } ; \
210 info_class INFO_TBL_CONST StgInfoTable info = { \
211 layout : { selector_offset : offset }, \
212 STD_INFO(THUNK_SELECTOR), \
213 INCLUDE_RBH_INFO(RBH_##info), \
221 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
222 entry_class, prof_descr, prof_type) \
223 entry_class(entry); \
224 info_class INFO_TBL_CONST StgInfoTable info = { \
225 layout : { selector_offset : offset }, \
226 STD_INFO(THUNK_SELECTOR), \
233 /* constructor info table --------------------------------------------------*/
236 INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class, \
237 entry_class, prof_descr, prof_type) \
238 entry_class(entry); \
239 info_class INFO_TBL_CONST StgInfoTable info = { \
240 layout : { payload : {ptrs,nptrs} }, \
241 CONSTR_INFO(type_,tag_), \
246 #define constrTag(con) (get_itbl(con)->srt_len)
248 /* return-vectors ----------------------------------------------------------*/
250 /* vectored-return info tables have the vector slammed up against the
251 * start of the info table.
253 * A vectored-return address always has an SRT and a bitmap-style
254 * layout field, so we only need one macro for these.
257 #ifdef TABLES_NEXT_TO_CODE
294 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
297 info_class INFO_TBL_CONST vec_info_2 info = { \
300 layout : { bitmap : (StgWord32)bitmap_ }, \
301 SRT_INFO(type,srt_,srt_off_,srt_len_) \
305 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
307 alt_1, alt_2, alt_3 \
309 info_class INFO_TBL_CONST vec_info_3 info = { \
310 { alt_3, alt_2, alt_1 }, \
312 layout : { bitmap : (StgWord32)bitmap_ }, \
313 SRT_INFO(type,srt_,srt_off_,srt_len_) \
317 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
319 alt_1, alt_2, alt_3, alt_4 \
321 info_class INFO_TBL_CONST vec_info_4 info = { \
322 { alt_4, alt_3, alt_2, alt_1 }, \
324 layout : { bitmap : (StgWord32)bitmap_ }, \
325 SRT_INFO(type,srt_,srt_off_,srt_len_) \
329 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
331 alt_1, alt_2, alt_3, alt_4, \
334 info_class INFO_TBL_CONST vec_info_5 info = { \
335 { alt_5, alt_4, alt_3, alt_2, \
338 layout : { bitmap : (StgWord32)bitmap_ }, \
339 SRT_INFO(type,srt_,srt_off_,srt_len_) \
343 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
345 alt_1, alt_2, alt_3, alt_4, \
348 info_class INFO_TBL_CONST vec_info_6 info = { \
349 { alt_6, alt_5, alt_4, alt_3, \
352 layout : { bitmap : (StgWord32)bitmap_ }, \
353 SRT_INFO(type,srt_,srt_off_,srt_len_) \
357 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
359 alt_1, alt_2, alt_3, alt_4, \
360 alt_5, alt_6, alt_7 \
362 info_class INFO_TBL_CONST vec_info_7 info = { \
363 { alt_7, alt_6, alt_5, alt_4, \
364 alt_3, alt_2, alt_1 }, \
366 layout : { bitmap : (StgWord32)bitmap_ }, \
367 SRT_INFO(type,srt_,srt_off_,srt_len_) \
371 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
373 alt_1, alt_2, alt_3, alt_4, \
374 alt_5, alt_6, alt_7, alt_8 \
376 info_class INFO_TBL_CONST vec_info_8 info = { \
377 { alt_8, alt_7, alt_6, alt_5, \
378 alt_4, alt_3, alt_2, alt_1 }, \
380 layout : { bitmap : (StgWord32)bitmap_ }, \
381 SRT_INFO(type,srt_,srt_off_,srt_len_) \
388 /* We have to define these structure to work around a bug in gcc: if we
389 * try to initialise the vector directly (it's defined as a zero-length
390 * array tacked on the end of the info table structor), then gcc silently
391 * throws away our vector table sometimes.
429 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_, \
432 info_class INFO_TBL_CONST vec_info_2 info = { \
433 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
434 SRT_INFO(type,srt_,srt_off_,srt_len_), \
437 vec : { alt_1, alt_2 } \
440 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_, \
442 alt_1, alt_2, alt_3 \
444 info_class INFO_TBL_CONST vec_info_3 info = { \
445 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
446 SRT_INFO(type,srt_,srt_off_,srt_len_), \
449 vec : { alt_1, alt_2, alt_3 } \
452 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_, \
454 alt_1, alt_2, alt_3, alt_4 \
456 info_class INFO_TBL_CONST vec_info_4 info = { \
457 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
458 SRT_INFO(type,srt_,srt_off_,srt_len_), \
461 vec : { alt_1, alt_2, alt_3, alt_4 } \
464 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_, \
466 alt_1, alt_2, alt_3, alt_4, \
469 info_class INFO_TBL_CONST vec_info_5 info = { \
470 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
471 SRT_INFO(type,srt_,srt_off_,srt_len_), \
474 vec : { alt_1, alt_2, alt_3, alt_4, \
478 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_, \
480 alt_1, alt_2, alt_3, alt_4, \
483 info_class INFO_TBL_CONST vec_info_6 info = { \
484 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
485 SRT_INFO(type,srt_,srt_off_,srt_len_), \
488 vec : { alt_1, alt_2, alt_3, alt_4, \
492 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_, \
494 alt_1, alt_2, alt_3, alt_4, \
495 alt_5, alt_6, alt_7 \
497 info_class INFO_TBL_CONST vec_info_7 info = { \
498 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
499 SRT_INFO(type,srt_,srt_off_,srt_len_), \
502 vec : { alt_1, alt_2, alt_3, alt_4, \
503 alt_5, alt_6, alt_7 } \
506 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_, \
508 alt_1, alt_2, alt_3, alt_4, \
509 alt_5, alt_6, alt_7, alt_8 \
511 info_class INFO_TBL_CONST vec_info_8 info = { \
512 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
513 SRT_INFO(type,srt_,srt_off_,srt_len_), \
516 vec : { alt_1, alt_2, alt_3, alt_4, \
517 alt_5, alt_6, alt_7, alt_8 } \
520 #endif /* TABLES_NEXT_TO_CODE */
522 /* For polymorphic activation records, we need both a direct return
523 * address and a return vector:
526 typedef vec_info_8 StgPolyInfoTable;
528 #ifndef TABLES_NEXT_TO_CODE
530 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
531 srt_, srt_off_, srt_len_, \
532 type, info_class, entry_class \
534 info_class INFO_TBL_CONST vec_info_8 nm##_info = { \
535 i : { layout : { bitmap : (StgWord32)bitmap_ }, \
536 SRT_INFO(type,srt_,srt_off_,srt_len_), \
537 INIT_ENTRY(nm##_entry), \
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 = { \
569 layout : { bitmap : (StgWord32)bitmap_ }, \
570 SRT_INFO(type,srt_,srt_off_,srt_len_), \
571 INIT_ENTRY(nm##_entry) \
578 static const StgSRT lbl = {
580 #define BITMAP(lbl,size) \
581 static const StgLargeBitmap lbl = { size, {
583 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
584 an entry in an SRT table with a reference to a closure that's
585 living in a DLL. See elsewhere for reasons as to why we need
586 to distinguish these kinds of references.
587 (ToDo: fill in a more precise href.)
589 #ifdef HAVE_WIN32_DLL_SUPPORT
590 #define DLL_SRT_ENTRY(x) ((StgClosure*)(((char*)&DLL_IMPORT_DATA_VAR(x)) + 1))
592 #define DLL_SRT_ENTRY(x) no-can-do
595 #endif /* INFOMACROS_H */