[project @ 2002-05-14 08:15:49 by matthewc]
[ghc-hetmet.git] / ghc / includes / InfoTables.h
1 /* ----------------------------------------------------------------------------
2  * $Id: InfoTables.h,v 1.27 2002/05/14 08:15:49 matthewc Exp $
3  * 
4  * (c) The GHC Team, 1998-1999
5  *
6  * Info Tables
7  *
8  * -------------------------------------------------------------------------- */
9
10 #ifndef INFOTABLES_H
11 #define INFOTABLES_H
12
13 /* -----------------------------------------------------------------------------
14    Profiling info
15    -------------------------------------------------------------------------- */
16
17 typedef struct {
18     char *closure_type;
19     char *closure_desc;
20 } StgProfInfo;
21
22 /* -----------------------------------------------------------------------------
23    Parallelism info
24    -------------------------------------------------------------------------- */
25
26 #if 0 && (defined(PAR) || defined(GRAN))
27
28 // CURRENTLY UNUSED
29 // ToDo: use this in StgInfoTable (mutually recursive) -- HWL
30
31 typedef struct {
32   StgInfoTable *rbh_infoptr;     /* infoptr to the RBH  */
33 } StgParInfo;
34
35 #endif /* 0 */
36
37 /*
38    Copied from ghc-0.29; ToDo: check this code -- HWL
39
40    In the parallel system, all updatable closures have corresponding
41    revertible black holes.  When we are assembly-mangling, we guarantee
42    that the revertible black hole code precedes the normal entry code, so
43    that the RBH info table resides at a fixed offset from the normal info
44    table.  Otherwise, we add the RBH info table pointer to the end of the
45    normal info table and vice versa.
46
47    Currently has to use a !RBH_MAGIC_OFFSET setting.
48    Still todo: init of par.infoptr field in all infotables!!
49 */
50
51 #if defined(PAR) || defined(GRAN)
52
53 # ifdef RBH_MAGIC_OFFSET
54
55 #  error magic offset not yet implemented
56
57 #  define RBH_INFO_WORDS    0
58 #  define INCLUDE_RBH_INFO(infoptr)
59
60 #  define RBH_INFOPTR(infoptr)      (((P_)infoptr) - RBH_MAGIC_OFFSET)
61 #  define REVERT_INFOPTR(infoptr)   (((P_)infoptr) + RBH_MAGIC_OFFSET)
62
63 # else
64
65 #  define RBH_INFO_WORDS    1
66 #  define INCLUDE_RBH_INFO(info)    rbh_infoptr : &(info)
67
68 #  define RBH_INFOPTR(infoptr)      (((StgInfoTable *)(infoptr))->rbh_infoptr)
69 #  define REVERT_INFOPTR(infoptr)   (((StgInfoTable *)(infoptr))->rbh_infoptr)
70
71 # endif
72
73 /* see ParallelRts.h */
74 // EXTFUN(RBH_entry);
75 //StgClosure *convertToRBH(StgClosure *closure);
76 //#if defined(GRAN)
77 //void convertFromRBH(StgClosure *closure);
78 //#elif defined(PAR)
79 //void convertToFetchMe(StgPtr closure, globalAddr *ga);
80 //#endif
81
82 #endif
83
84 /* -----------------------------------------------------------------------------
85    Ticky info
86    -------------------------------------------------------------------------- */
87
88 typedef struct {
89     /* empty */
90 } StgTickyInfo;
91
92 /* -----------------------------------------------------------------------------
93    Debugging info
94    -------------------------------------------------------------------------- */
95
96 #ifdef DEBUG_CLOSURE
97
98 typedef struct {
99         ... whatever ...
100 } StgDebugInfo;
101
102 #else /* !DEBUG_CLOSURE */
103
104 typedef struct {
105         /* empty */
106 } StgDebugInfo;
107
108 #endif /* DEBUG_CLOSURE */
109
110 /* -----------------------------------------------------------------------------
111    Closure flags
112    -------------------------------------------------------------------------- */
113
114 /* The type flags provide quick access to certain properties of a closure. */
115
116 #define _HNF (1<<0)  /* head normal form?    */
117 #define _BTM (1<<1)  /* bitmap-style layout? */
118 #define _NS  (1<<2)  /* non-sparkable        */
119 #define _STA (1<<3)  /* static?              */
120 #define _THU (1<<4)  /* thunk?               */
121 #define _MUT (1<<5)  /* mutable?             */
122 #define _UPT (1<<6)  /* unpointed?           */
123 #define _SRT (1<<7)  /* has an SRT?          */
124 #define _IND (1<<8)  /* is an indirection?   */
125
126 #define isSTATIC(flags)    ((flags) &_STA)
127 #define isMUTABLE(flags)   ((flags) &_MUT)
128 #define isBITMAP(flags)    ((flags) &_BTM)
129 #define isTHUNK(flags)     ((flags) &_THU)
130 #define isUNPOINTED(flags) ((flags) &_UPT)
131 #define hasSRT(flags)      ((flags) &_SRT)
132
133 extern StgWord16 closure_flags[];
134
135 #define closureFlags(c)         (closure_flags[get_itbl(c)->type])
136
137 #define closure_HNF(c)          (  closureFlags(c) & _HNF)
138 #define closure_BITMAP(c)       (  closureFlags(c) & _BTM)
139 #define closure_NON_SPARK(c)    ( (closureFlags(c) & _NS))
140 #define closure_SHOULD_SPARK(c) (!(closureFlags(c) & _NS))
141 #define closure_STATIC(c)       (  closureFlags(c) & _STA)
142 #define closure_THUNK(c)        (  closureFlags(c) & _THU)
143 #define closure_MUTABLE(c)      (  closureFlags(c) & _MUT)
144 #define closure_UNPOINTED(c)    (  closureFlags(c) & _UPT)
145 #define closure_SRT(c)          (  closureFlags(c) & _SRT)
146 #define closure_IND(c)          (  closureFlags(c) & _IND)
147
148 /* same as above but for info-ptr rather than closure */
149 #define ipFlags(ip)             (closure_flags[ip->type])
150
151 #define ip_HNF(ip)               (  ipFlags(ip) & _HNF)
152 #define ip_BITMAP(ip)            (  ipFlags(ip) & _BTM)
153 #define ip_SHOULD_SPARK(ip)      (!(ipFlags(ip) & _NS))
154 #define ip_STATIC(ip)            (  ipFlags(ip) & _STA)
155 #define ip_THUNK(ip)             (  ipFlags(ip) & _THU)
156 #define ip_MUTABLE(ip)           (  ipFlags(ip) & _MUT)
157 #define ip_UNPOINTED(ip)         (  ipFlags(ip) & _UPT)
158 #define ip_SRT(ip)               (  ipFlags(ip) & _SRT)
159 #define ip_IND(ip)               (  ipFlags(ip) & _IND)
160
161 /* -----------------------------------------------------------------------------
162    Info Tables
163    -------------------------------------------------------------------------- */
164
165 /* A large bitmap.  Small 32-bit ones live in the info table, but sometimes
166  * 32 bits isn't enough and we have to generate a larger one.  (sizes
167  * differ for 64-bit machines.
168  */
169
170 typedef struct {
171   StgWord size;
172   StgWord bitmap[FLEXIBLE_ARRAY];
173 } StgLargeBitmap;
174
175 /*
176  * Stuff describing the closure layout.  Well, actually, it might
177  * contain the selector index for a THUNK_SELECTOR.  If we're on a
178  * 64-bit architecture then we can enlarge some of these fields, since
179  * the union contains a pointer field.
180  */
181
182 typedef union {
183   struct {
184 #if SIZEOF_VOID_P == 8
185     StgWord32 ptrs;             /* number of pointers     */
186     StgWord32 nptrs;            /* number of non-pointers */
187 #else
188     StgWord16 ptrs;             /* number of pointers     */
189     StgWord16 nptrs;            /* number of non-pointers */
190 #endif
191   } payload;
192
193   StgWord bitmap;               /* bit pattern, 1 = pointer, 0 = non-pointer */
194   StgWord selector_offset;      /* used in THUNK_SELECTORs */
195   StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
196   
197 } StgClosureInfo;
198
199 /*
200  * Info tables.  All info tables are the same type, to simplify code
201  * generation.  However, the mangler removes any unused SRT fields
202  * from the asm to save space (convention: if srt_len is zero, or the
203  * type is a CONSTR_ type, then the SRT field isn't present.
204  */
205
206 typedef StgClosure* StgSRT[];
207
208 /*
209  * The entry code pointer must be the first word of an info table.
210  * See the comment in ghc/rts/Storage.h (Plan C) for details.
211  */
212 typedef struct _StgInfoTable {
213 #ifndef TABLES_NEXT_TO_CODE
214     StgFunPtr       entry;
215 #endif
216     StgSRT         *srt;        /* pointer to the SRT table */
217 #if defined(PAR) || defined(GRAN)
218     struct _StgInfoTable    *rbh_infoptr;
219 #endif
220 #ifdef PROFILING
221     StgProfInfo     prof;
222 #endif
223 #ifdef TICKY
224     StgTickyInfo    ticky;
225 #endif
226 #ifdef DEBUG_CLOSURE
227     StgDebugInfo    debug;
228 #endif
229     StgClosureInfo  layout;     /* closure layout info (pointer-sized) */
230 #if SIZEOF_VOID_P == 8
231     StgWord32       type;       /* } These 2 elements fit into 64 bits */
232     StgWord32       srt_len;    /* }                                   */
233 #else
234     StgWord         type : 16;  /* } These 2 elements fit into 32 bits */
235     StgWord         srt_len : 16; /* }                                   */
236 #endif
237 #ifdef TABLES_NEXT_TO_CODE
238     StgCode         code[FLEXIBLE_ARRAY];
239 #else
240     StgFunPtr       vector[FLEXIBLE_ARRAY];
241 #endif
242 } StgInfoTable;
243
244 /* Info tables are read-only, therefore we uniformly declare them with
245  * C's const attribute.  This isn't just a nice thing to do: it's
246  * necessary because the garbage collector has to distinguish between 
247  * closure pointers and info table pointers when traversing the
248  * stack.  We distinguish the two by checking whether the pointer is
249  * into text-space or not.
250  */
251
252 #if ia64_TARGET_ARCH
253 /* We need to give the compiler a gentle hint to put it in text-space */
254 #define INFO_TBL_CONST  const __attribute__((section (".text")))
255 #else
256 #define INFO_TBL_CONST  const
257 #endif
258
259 #endif /* INFOTABLES_H */