1 /* ----------------------------------------------------------------------------
2 * $Id: InfoMacros.h,v 1.22 2003/05/14 09:14:01 simonmar Exp $
4 * (c) The GHC Team, 1998-2002
6 * Macros for building and deconstructing info tables.
8 * -------------------------------------------------------------------------- */
13 #define STD_INFO(srt_bitmap_, type_) \
14 srt_bitmap : srt_bitmap_, \
17 #define THUNK_INFO(srt_, srt_off_) \
18 srt : (StgSRT *)((StgClosure **)srt_+srt_off_)
20 #define FUN_GEN_INFO(srt_, srt_off_, fun_type_, arity_, bitmap_, slow_apply_) \
22 #define RET_INFO(srt_, srt_off_) \
23 srt : (StgSRT *)((StgClosure **)srt_+srt_off_)
26 #define PROF_INFO(type_str, desc_str) \
28 closure_type: type_str, \
29 closure_desc: desc_str, \
32 #define PROF_INFO(type_str, desc_str)
36 On the GranSim/GUM specific parts of the InfoTables (GRAN/PAR):
38 In both GranSim and GUM we use revertible black holes (RBH) when putting
39 an updatable closure into a packet for communication. The entry code for
40 an RBH performs standard blocking (as with any kind of BH). The info
41 table for the RBH resides just before the one for the std info
42 table. (NB: there is one RBH ITBL for every ITBL of an updatable
43 closure.) The @rbh_infoptr@ field in the ITBL points from the std ITBL to
44 the RBH ITBL and vice versa. This is used by the RBH_INFOPTR and
45 REVERT_INFOPTR macros to turn an updatable node into an RBH and vice
46 versa. Note, that the only case where we have to revert the RBH in its
47 original form is when a packet is sent back because of garbage collection
48 on another PE. In the RTS for GdH we will use this reversion mechanism in
49 order to deal with faults in the system.
50 ToDo: Check that RBHs are needed for all the info tables below. From a quick
51 check of the macros generated in the libs it seems that all of them are used
52 for generating THUNKs.
53 Possible optimisation: Note that any RBH ITBL is a fixed distance away from
54 the actual ITBL. We could inline this offset as a constant into the RTS and
55 avoid the rbh_infoptr fields altogether (Jim did that in the old RTS).
60 /* function/thunk info tables --------------------------------------------- */
62 #if defined(GRAN) || defined(PAR)
65 INFO_TABLE_THUNK(info, /* info-table label */ \
66 entry, /* entry code label */ \
67 ptrs, nptrs, /* closure layout info */\
68 srt_, srt_off_, srt_bitmap_, /* SRT info */ \
69 type, /* closure type */ \
70 info_class, entry_class, /* C storage classes */ \
71 prof_descr, prof_type) /* profiling info */ \
72 entry_class(stg_RBH_##entry); \
74 ED_RO_ StgInfoTable info; \
75 info_class const StgInfoTable stg_RBH_##info = { \
76 layout : { payload : {ptrs,nptrs} }, \
77 PROF_INFO(prof_type, prof_descr) \
78 SRT_INFO(RBH,srt_,srt_off_,srt_bitmap_), \
79 INCLUDE_RBH_INFO(info), \
80 INIT_ENTRY(stg_RBH_##entry) \
82 StgFunPtr stg_RBH_##entry (void) { \
84 JMP_(stg_RBH_entry); \
87 info_class const StgInfoTable info = { \
88 layout : { payload : {ptrs,nptrs} }, \
89 PROF_INFO(prof_type, prof_descr) \
90 SRT_INFO(type,srt_,srt_off_,srt_bitmap_), \
91 INCLUDE_RBH_INFO(stg_RBH_##info), \
98 INFO_TABLE_THUNK(info, /* info-table label */ \
99 entry, /* entry code label */ \
100 ptrs, nptrs, /* closure layout info */\
101 srt_, srt_off_, srt_bitmap_, /* SRT info */ \
102 type_, /* closure type */ \
103 info_class, entry_class, /* C storage classes */ \
104 prof_descr, prof_type) /* profiling info */ \
105 entry_class(entry); \
106 info_class const StgThunkInfoTable info = { \
108 layout : { payload : {ptrs,nptrs} }, \
109 PROF_INFO(prof_type, prof_descr) \
110 STD_INFO(srt_bitmap_, type_), \
113 THUNK_INFO(srt_,srt_off_), \
118 /* direct-return address info tables --------------------------------------*/
120 #if defined(GRAN) || defined(PAR)
123 INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_bitmap_, \
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 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_bitmap_), \
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 const StgInfoTable info = { \
142 layout : { bitmap : (StgWord)bitmap_ }, \
143 PROF_INFO(prof_type, prof_descr) \
144 SRT_INFO(type,srt_,srt_off_,srt_bitmap_), \
145 INCLUDE_RBH_INFO(stg_RBH_##info), \
152 INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_bitmap_, \
153 type_, info_class, entry_class, \
154 prof_descr, prof_type) \
155 entry_class(entry); \
156 info_class const StgRetInfoTable info = { \
158 layout : { bitmap : (StgWord)bitmap_ }, \
159 PROF_INFO(prof_type, prof_descr) \
160 STD_INFO(srt_bitmap_,type_), \
163 RET_INFO(srt_,srt_off_) \
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(stg_RBH_##entry); \
175 entry_class(entry); \
176 ED_ StgInfoTable info; \
177 info_class const StgInfoTable stg_RBH_##info = { \
178 layout : { payload : {ptrs,nptrs} }, \
179 PROF_INFO(prof_type, prof_descr) \
181 INCLUDE_RBH_INFO(info), \
182 INIT_ENTRY(stg_RBH_##entry) \
184 StgFunPtr stg_RBH_##entry (void) { \
186 JMP_(stg_RBH_entry); \
189 info_class const StgInfoTable info = { \
190 layout : { payload : {ptrs,nptrs} }, \
191 PROF_INFO(prof_type, prof_descr) \
193 INCLUDE_RBH_INFO(stg_RBH_##info), \
200 INFO_TABLE(info, entry, ptrs, nptrs, type, info_class, \
201 entry_class, prof_descr, prof_type) \
202 entry_class(entry); \
203 info_class const StgInfoTable info = { \
204 layout : { payload : {ptrs,nptrs} }, \
205 PROF_INFO(prof_type, prof_descr) \
212 /* special selector-thunk info table ---------------------------------------*/
214 #if defined(GRAN) || defined(PAR)
217 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
218 entry_class, prof_descr, prof_type) \
219 entry_class(stg_RBH_##entry); \
220 entry_class(entry); \
221 ED_RO_ StgInfoTable info; \
222 info_class const StgInfoTable stg_RBH_##info = { \
223 layout : { selector_offset : offset }, \
224 PROF_INFO(prof_type, prof_descr) \
226 INCLUDE_RBH_INFO(info), \
227 INIT_ENTRY(stg_RBH_##entry) \
229 StgFunPtr stg_RBH_##entry (void) { \
231 JMP_(stg_RBH_entry); \
234 info_class const StgInfoTable info = { \
235 layout : { selector_offset : offset }, \
236 PROF_INFO(prof_type, prof_descr) \
237 STD_INFO(THUNK_SELECTOR), \
238 INCLUDE_RBH_INFO(stg_RBH_##info), \
245 INFO_TABLE_SELECTOR(info, entry, offset, info_class, \
246 entry_class, prof_descr, prof_type) \
247 entry_class(entry); \
248 info_class const StgInfoTable info = { \
249 layout : { selector_offset : offset }, \
250 PROF_INFO(prof_type, prof_descr) \
251 STD_INFO(0,THUNK_SELECTOR), \
257 /* constructor info table --------------------------------------------------*/
260 INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class, \
261 entry_class, prof_descr, prof_type) \
262 entry_class(entry); \
263 info_class const StgInfoTable info = { \
264 layout : { payload : {ptrs,nptrs} }, \
265 PROF_INFO(prof_type, prof_descr) \
266 STD_INFO(tag_, type_), \
270 #define constrTag(con) (get_itbl(con)->srt_bitmap)
272 /* function info table -----------------------------------------------------*/
275 INFO_TABLE_FUN_GEN(info, /* info-table label */ \
276 entry, /* entry code label */ \
277 ptrs, nptrs, /* closure layout info */\
278 srt_, srt_off_, srt_bitmap_, /* SRT info */ \
279 fun_type_, arity_, bitmap_, slow_apply_, \
280 /* Function info */ \
281 type_, /* closure type */ \
282 info_class, entry_class, /* C storage classes */ \
283 prof_descr, prof_type) /* profiling info */ \
284 entry_class(entry); \
285 info_class const StgFunInfoTable info = { \
287 layout : { payload : {ptrs,nptrs} }, \
288 PROF_INFO(prof_type, prof_descr) \
289 STD_INFO(srt_bitmap_,type_), \
292 srt : (StgSRT *)((StgClosure **)srt_+srt_off_), \
294 fun_type : fun_type_, \
295 bitmap : (W_)bitmap_, \
296 slow_apply : slow_apply_ \
299 /* return-vectors ----------------------------------------------------------*/
301 /* vectored-return info tables have the vector slammed up against the
302 * start of the info table.
304 * A vectored-return address always has an SRT and a bitmap-style
305 * layout field, so we only need one macro for these.
308 #ifdef TABLES_NEXT_TO_CODE
345 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
348 info_class const vec_info_2 info = { \
352 layout : { bitmap : (StgWord)bitmap_ }, \
353 STD_INFO(srt_bitmap_,type_) \
355 RET_INFO(srt_,srt_off_) \
359 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
361 alt_1, alt_2, alt_3 \
363 info_class const vec_info_3 info = { \
364 { alt_3, alt_2, alt_1 }, \
367 layout : { bitmap : (StgWord)bitmap_ }, \
368 STD_INFO(srt_bitmap_,type_) \
370 RET_INFO(srt_,srt_off_) \
374 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
376 alt_1, alt_2, alt_3, alt_4 \
378 info_class const vec_info_4 info = { \
379 { alt_4, alt_3, alt_2, alt_1 }, \
382 layout : { bitmap : (StgWord)bitmap_ }, \
383 STD_INFO(srt_bitmap_,type_) \
385 RET_INFO(srt_,srt_off_) \
389 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
391 alt_1, alt_2, alt_3, alt_4, \
394 info_class const vec_info_5 info = { \
395 { alt_5, alt_4, alt_3, alt_2, \
399 layout : { bitmap : (StgWord)bitmap_ }, \
400 STD_INFO(srt_bitmap_,type_) \
402 RET_INFO(srt_,srt_off_) \
406 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
408 alt_1, alt_2, alt_3, alt_4, \
411 info_class const vec_info_6 info = { \
412 { alt_6, alt_5, alt_4, alt_3, \
416 layout : { bitmap : (StgWord)bitmap_ }, \
417 STD_INFO(srt_bitmap_,type_) \
419 RET_INFO(srt_,srt_off_) \
423 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
425 alt_1, alt_2, alt_3, alt_4, \
426 alt_5, alt_6, alt_7 \
428 info_class const vec_info_7 info = { \
429 { alt_7, alt_6, alt_5, alt_4, \
430 alt_3, alt_2, alt_1 }, \
433 layout : { bitmap : (StgWord)bitmap_ }, \
434 STD_INFO(srt_bitmap_,type_) \
436 RET_INFO(srt_,srt_off_) \
440 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
442 alt_1, alt_2, alt_3, alt_4, \
443 alt_5, alt_6, alt_7, alt_8 \
445 info_class const vec_info_8 info = { \
446 { alt_8, alt_7, alt_6, alt_5, \
447 alt_4, alt_3, alt_2, alt_1 }, \
450 layout : { bitmap : (StgWord)bitmap_ }, \
451 STD_INFO(srt_bitmap_,type_) \
453 RET_INFO(srt_,srt_off_) \
460 /* We have to define these structure to work around a bug in gcc: if we
461 * try to initialise the vector directly (it's defined as a zero-length
462 * array tacked on the end of the info table structor), then gcc silently
463 * throws away our vector table sometimes.
501 #define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
504 info_class const vec_info_2 info = { \
507 layout : { bitmap : (StgWord)bitmap_ }, \
508 STD_INFO(srt_bitmap_,type_) \
510 RET_INFO(srt_,srt_off_) \
514 #define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
516 alt_1, alt_2, alt_3 \
518 info_class const vec_info_3 info = { \
521 layout : { bitmap : (StgWord)bitmap_ }, \
522 STD_INFO(srt_bitmap_,type_) \
524 RET_INFO(srt_,srt_off_) \
526 vec : { alt_1, alt_2, alt_3 } \
529 #define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
531 alt_1, alt_2, alt_3, alt_4 \
533 info_class const vec_info_4 info = { \
536 layout : { bitmap : (StgWord)bitmap_ }, \
537 STD_INFO(srt_bitmap_,type_) \
539 RET_INFO(srt_,srt_off_) \
541 vec : { alt_1, alt_2, alt_3, alt_4 } \
544 #define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
546 alt_1, alt_2, alt_3, alt_4, \
549 info_class const vec_info_5 info = { \
552 layout : { bitmap : (StgWord)bitmap_ }, \
553 STD_INFO(srt_bitmap_,type_) \
555 RET_INFO(srt_,srt_off_) \
557 vec : { alt_1, alt_2, alt_3, alt_4, \
561 #define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
563 alt_1, alt_2, alt_3, alt_4, \
566 info_class const vec_info_6 info = { \
569 layout : { bitmap : (StgWord)bitmap_ }, \
570 STD_INFO(srt_bitmap_,type_) \
572 RET_INFO(srt_,srt_off_) \
574 vec : { alt_1, alt_2, alt_3, alt_4, \
578 #define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
580 alt_1, alt_2, alt_3, alt_4, \
581 alt_5, alt_6, alt_7 \
583 info_class const vec_info_7 info = { \
586 layout : { bitmap : (StgWord)bitmap_ }, \
587 STD_INFO(srt_bitmap_,type_) \
589 RET_INFO(srt_,srt_off_) \
591 vec : { alt_1, alt_2, alt_3, alt_4, \
592 alt_5, alt_6, alt_7 } \
595 #define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_bitmap_, \
597 alt_1, alt_2, alt_3, alt_4, \
598 alt_5, alt_6, alt_7, alt_8 \
600 info_class const vec_info_8 info = { \
603 layout : { bitmap : (StgWord)bitmap_ }, \
604 STD_INFO(srt_bitmap_,type_) \
606 RET_INFO(srt_,srt_off_) \
608 vec : { alt_1, alt_2, alt_3, alt_4, \
609 alt_5, alt_6, alt_7, alt_8 } \
612 #endif /* TABLES_NEXT_TO_CODE */
614 /* For polymorphic activation records, we need both a direct return
615 * address and a return vector:
618 typedef vec_info_8 StgPolyInfoTable;
620 #ifndef TABLES_NEXT_TO_CODE
622 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
623 srt_, srt_off_, srt_bitmap_, \
624 type_, info_class, entry_class \
626 info_class const vec_info_8 nm##_info = { \
630 bitmap : (StgWord)bitmap_ }, \
631 STD_INFO(srt_bitmap_, type_), \
632 INIT_ENTRY(nm##_ret) \
634 RET_INFO(srt_,srt_off_) \
649 #define VEC_POLY_INFO_TABLE(nm, bitmap_, \
650 srt_, srt_off_, srt_bitmap_, \
651 type_, info_class, entry_class \
653 info_class const vec_info_8 nm##_info = { \
667 bitmap : (StgWord)bitmap_ }, \
668 STD_INFO(srt_bitmap_, type_), \
669 INIT_ENTRY(nm##_ret) \
671 RET_INFO(srt_,srt_off_) \
678 static const StgSRT lbl = {
680 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
681 an entry in an SRT table with a reference to a closure that's
682 living in a DLL. See elsewhere for reasons as to why we need
683 to distinguish these kinds of references.
684 (ToDo: fill in a more precise href.)
686 #ifdef ENABLE_WIN32_DLL_SUPPORT /* mingw DietHEP doesn't seem to care either way */
687 #define DLL_SRT_ENTRY(x) ((StgClosure*)(((char*)&DLL_IMPORT_DATA_VAR(x)) + 1))
689 #define DLL_SRT_ENTRY(x) no-can-do
692 #endif /* INFOMACROS_H */