1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
/* ----------------------------------------------------------------------------
* $Id: InfoTables.h,v 1.17 1999/07/16 09:41:12 panne Exp $
*
* (c) The GHC Team, 1998-1999
*
* Info Tables
*
* -------------------------------------------------------------------------- */
#ifndef INFOTABLES_H
#define INFOTABLES_H
/* -----------------------------------------------------------------------------
Profiling info
-------------------------------------------------------------------------- */
#ifdef PROFILING
#define PROF_INFO_WORDS n
typedef struct {
/* nothing yet */
} StgProfInfo;
#else /* !PROFILING */
#define PROF_INFO_WORDS 0
typedef struct {
/* empty */
} StgProfInfo;
#endif /* PROFILING */
/* -----------------------------------------------------------------------------
Parallelism info
-------------------------------------------------------------------------- */
#ifdef PAR
#define PAR_INFO_WORDS 0
typedef struct {
/* empty */
} StgParInfo;
#else /* !PAR */
#define PAR_INFO_WORDS 0
typedef struct {
/* empty */
} StgParInfo;
#endif /* PAR */
/* -----------------------------------------------------------------------------
Debugging info
-------------------------------------------------------------------------- */
#ifdef DEBUG_CLOSURE
#define DEBUG_INFO_WORDS n
typedef struct {
... whatever ...
} StgDebugInfo;
#else /* !DEBUG_CLOSURE */
#define DEBUG_INFO_WORDS 0
typedef struct {
/* empty */
} StgDebugInfo;
#endif /* DEBUG_CLOSURE */
/* The type flags provide quick access to certain properties of a closure. */
#define _HNF (1<<0) /* head normal form? */
#define _BTM (1<<1) /* bitmap-style layout? */
#define _NS (1<<2) /* non-sparkable */
#define _STA (1<<3) /* static? */
#define _THU (1<<4) /* thunk? */
#define _MUT (1<<5) /* mutable? */
#define _UPT (1<<6) /* unpointed? */
#define _SRT (1<<7) /* has an SRT? */
#define isSTATIC(flags) ((flags) &_STA)
#define isMUTABLE(flags) ((flags) &_MUT)
#define isBITMAP(flags) ((flags) &_BTM)
#define isTHUNK(flags) ((flags) &_THU)
#define isUNPOINTED(flags) ((flags) &_UPT)
#define hasSRT(flags) ((flags) &_SRT)
extern StgWord16 closure_flags[];
#define closureFlags(c) (closure_flags[get_itbl(c)->type])
#define closure_STATIC(c) ( closureFlags(c) & _STA)
#define closure_SHOULD_SPARK(c) (!(closureFlags(c) & _NS))
#define closure_MUTABLE(c) ( closureFlags(c) & _MUT)
#define closure_UNPOINTED(c) ( closureFlags(c) & _UPT)
/* -----------------------------------------------------------------------------
Info Tables
-------------------------------------------------------------------------- */
/* A large bitmap. Small 32-bit ones live in the info table, but sometimes
* 32 bits isn't enough and we have to generate a larger one. (sizes
* differ for 64-bit machines.
*/
typedef struct {
StgWord size;
StgWord bitmap[0];
} StgLargeBitmap;
/*
* Stuff describing the closure layout. Well, actually, it might
* contain the selector index for a THUNK_SELECTOR. If we're on a
* 64-bit architecture then we can enlarge some of these fields, since
* the union contains a pointer field.
*/
typedef union {
struct {
#if SIZEOF_VOID_P == 8
StgWord32 ptrs; /* number of pointers */
StgWord32 nptrs; /* number of non-pointers */
#else
StgWord16 ptrs; /* number of pointers */
StgWord16 nptrs; /* number of non-pointers */
#endif
} payload;
StgWord bitmap; /* bit pattern, 1 = pointer, 0 = non-pointer */
StgWord selector_offset; /* used in THUNK_SELECTORs */
StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
} StgClosureInfo;
/*
* Info tables. All info tables are the same type, to simplify code
* generation. However, the mangler removes any unused SRT fields
* from the asm to save space (convention: if srt_len is zero, or the
* type is a CONSTR_ type, then the SRT field isn't present.
*/
typedef StgClosure* StgSRT[];
typedef struct _StgInfoTable {
StgSRT *srt; /* pointer to the SRT table */
#ifdef PAR
StgParInfo par;
#endif
#ifdef PROFILING
/* StgProfInfo prof; */
#endif
#ifdef DEBUG_CLOSURE
StgDebugInfo debug;
#endif
StgClosureInfo layout; /* closure layout info (pointer-sized) */
#if SIZEOF_VOID_P == 8
StgWord32 type; /* } These 2 elements fit into 64 bits */
StgWord32 srt_len; /* } */
#else
StgWord type : 16; /* } These 2 elements fit into 32 bits */
StgWord srt_len : 16; /* } */
#endif
#ifdef TABLES_NEXT_TO_CODE
StgCode code[0];
#else
StgFunPtr entry;
StgFunPtr vector[0];
#endif
} StgInfoTable;
/* Info tables are read-only, therefore we uniformly declare them with
* C's const attribute. This isn't just a nice thing to do: it's
* necessary because the garbage collector has to distinguish between
* closure pointers and info table pointers when traversing the
* stack. We distinguish the two by checking whether the pointer is
* into text-space or not.
*/
#define INFO_TBL_CONST const
#endif /* INFOTABLES_H */
|