1 /* ----------------------------------------------------------------------------
2 * $Id: InfoTables.h,v 1.24 2001/12/18 19:42:41 sebc Exp $
4 * (c) The GHC Team, 1998-1999
8 * -------------------------------------------------------------------------- */
13 /* -----------------------------------------------------------------------------
15 -------------------------------------------------------------------------- */
22 /* -----------------------------------------------------------------------------
24 -------------------------------------------------------------------------- */
26 #if 0 && (defined(PAR) || defined(GRAN))
29 // ToDo: use this in StgInfoTable (mutually recursive) -- HWL
32 StgInfoTable *rbh_infoptr; /* infoptr to the RBH */
43 Copied from ghc-0.29; ToDo: check this code -- HWL
45 In the parallel system, all updatable closures have corresponding
46 revertible black holes. When we are assembly-mangling, we guarantee
47 that the revertible black hole code precedes the normal entry code, so
48 that the RBH info table resides at a fixed offset from the normal info
49 table. Otherwise, we add the RBH info table pointer to the end of the
50 normal info table and vice versa.
52 Currently has to use a !RBH_MAGIC_OFFSET setting.
53 Still todo: init of par.infoptr field in all infotables!!
56 #if defined(PAR) || defined(GRAN)
58 # ifdef RBH_MAGIC_OFFSET
60 # error magic offset not yet implemented
62 # define RBH_INFO_WORDS 0
63 # define INCLUDE_RBH_INFO(infoptr)
65 # define RBH_INFOPTR(infoptr) (((P_)infoptr) - RBH_MAGIC_OFFSET)
66 # define REVERT_INFOPTR(infoptr) (((P_)infoptr) + RBH_MAGIC_OFFSET)
70 # define RBH_INFO_WORDS 1
71 # define INCLUDE_RBH_INFO(info) rbh_infoptr : &(info)
73 # define RBH_INFOPTR(infoptr) (((StgInfoTable *)(infoptr))->rbh_infoptr)
74 # define REVERT_INFOPTR(infoptr) (((StgInfoTable *)(infoptr))->rbh_infoptr)
78 /* see ParallelRts.h */
80 //StgClosure *convertToRBH(StgClosure *closure);
82 //void convertFromRBH(StgClosure *closure);
84 //void convertToFetchMe(StgPtr closure, globalAddr *ga);
89 /* -----------------------------------------------------------------------------
91 -------------------------------------------------------------------------- */
97 /* -----------------------------------------------------------------------------
99 -------------------------------------------------------------------------- */
107 #else /* !DEBUG_CLOSURE */
113 #endif /* DEBUG_CLOSURE */
115 /* The type flags provide quick access to certain properties of a closure. */
117 #define _HNF (1<<0) /* head normal form? */
118 #define _BTM (1<<1) /* bitmap-style layout? */
119 #define _NS (1<<2) /* non-sparkable */
120 #define _STA (1<<3) /* static? */
121 #define _THU (1<<4) /* thunk? */
122 #define _MUT (1<<5) /* mutable? */
123 #define _UPT (1<<6) /* unpointed? */
124 #define _SRT (1<<7) /* has an SRT? */
125 #define _IND (1<<8) /* is an indirection? */
127 #define isSTATIC(flags) ((flags) &_STA)
128 #define isMUTABLE(flags) ((flags) &_MUT)
129 #define isBITMAP(flags) ((flags) &_BTM)
130 #define isTHUNK(flags) ((flags) &_THU)
131 #define isUNPOINTED(flags) ((flags) &_UPT)
132 #define hasSRT(flags) ((flags) &_SRT)
134 extern StgWord16 closure_flags[];
136 #define closureFlags(c) (closure_flags[get_itbl(c)->type])
138 #define closure_HNF(c) ( closureFlags(c) & _HNF)
139 #define closure_BITMAP(c) ( closureFlags(c) & _BTM)
140 #define closure_NON_SPARK(c) ( (closureFlags(c) & _NS))
141 #define closure_SHOULD_SPARK(c) (!(closureFlags(c) & _NS))
142 #define closure_STATIC(c) ( closureFlags(c) & _STA)
143 #define closure_THUNK(c) ( closureFlags(c) & _THU)
144 #define closure_MUTABLE(c) ( closureFlags(c) & _MUT)
145 #define closure_UNPOINTED(c) ( closureFlags(c) & _UPT)
146 #define closure_SRT(c) ( closureFlags(c) & _SRT)
147 #define closure_IND(c) ( closureFlags(c) & _IND)
149 /* same as above but for info-ptr rather than closure */
150 #define ipFlags(ip) (closure_flags[ip->type])
152 #define ip_HNF(ip) ( ipFlags(ip) & _HNF)
153 #define ip_BITMAP(ip) ( ipFlags(ip) & _BTM)
154 #define ip_SHOULD_SPARK(ip) (!(ipFlags(ip) & _NS))
155 #define ip_STATIC(ip) ( ipFlags(ip) & _STA)
156 #define ip_THUNK(ip) ( ipFlags(ip) & _THU)
157 #define ip_MUTABLE(ip) ( ipFlags(ip) & _MUT)
158 #define ip_UNPOINTED(ip) ( ipFlags(ip) & _UPT)
159 #define ip_SRT(ip) ( ipFlags(ip) & _SRT)
160 #define ip_IND(ip) ( ipFlags(ip) & _IND)
162 /* -----------------------------------------------------------------------------
164 -------------------------------------------------------------------------- */
166 /* A large bitmap. Small 32-bit ones live in the info table, but sometimes
167 * 32 bits isn't enough and we have to generate a larger one. (sizes
168 * differ for 64-bit machines.
173 StgWord bitmap[FLEXIBLE_ARRAY];
177 * Stuff describing the closure layout. Well, actually, it might
178 * contain the selector index for a THUNK_SELECTOR. If we're on a
179 * 64-bit architecture then we can enlarge some of these fields, since
180 * the union contains a pointer field.
185 #if SIZEOF_VOID_P == 8
186 StgWord32 ptrs; /* number of pointers */
187 StgWord32 nptrs; /* number of non-pointers */
189 StgWord16 ptrs; /* number of pointers */
190 StgWord16 nptrs; /* number of non-pointers */
194 StgWord bitmap; /* bit pattern, 1 = pointer, 0 = non-pointer */
195 StgWord selector_offset; /* used in THUNK_SELECTORs */
196 StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
201 * Info tables. All info tables are the same type, to simplify code
202 * generation. However, the mangler removes any unused SRT fields
203 * from the asm to save space (convention: if srt_len is zero, or the
204 * type is a CONSTR_ type, then the SRT field isn't present.
207 typedef StgClosure* StgSRT[];
210 * The entry code pointer must be the first word of an info table.
211 * See the comment in ghc/rts/Storage.h (Plan C) for details.
213 typedef struct _StgInfoTable {
214 #ifndef TABLES_NEXT_TO_CODE
217 StgSRT *srt; /* pointer to the SRT table */
218 #if defined(PAR) || defined(GRAN)
219 struct _StgInfoTable *rbh_infoptr;
230 StgClosureInfo layout; /* closure layout info (pointer-sized) */
231 #if SIZEOF_VOID_P == 8
232 StgWord32 type; /* } These 2 elements fit into 64 bits */
233 StgWord32 srt_len; /* } */
235 StgWord type : 16; /* } These 2 elements fit into 32 bits */
236 StgWord srt_len : 16; /* } */
238 #ifdef TABLES_NEXT_TO_CODE
239 StgCode code[FLEXIBLE_ARRAY];
241 StgFunPtr vector[FLEXIBLE_ARRAY];
245 /* Info tables are read-only, therefore we uniformly declare them with
246 * C's const attribute. This isn't just a nice thing to do: it's
247 * necessary because the garbage collector has to distinguish between
248 * closure pointers and info table pointers when traversing the
249 * stack. We distinguish the two by checking whether the pointer is
250 * into text-space or not.
253 #define INFO_TBL_CONST const
255 #endif /* INFOTABLES_H */