1 %****************************************************************************
3 \section[SMmarkDefs.lh]{Definitions used by Pointer-Reversing Mark code}
5 % (c) P. Sansom, K. Hammond, Glasgow University, January 26th 1993.
7 %****************************************************************************
9 Describe how to set the mark bit for a closure.
14 #define SET_MARK_BIT(closure) \
16 if (closure <= HeapLim) /* tested heap range for GCgn */ \
18 long _hp_word = ((P_)closure) - HeapBase; \
19 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
20 DEBUG_SET_MARK(closure, _hp_word); \
21 BitArray[_hp_word / BITS_IN(BitWord)] |= \
22 1L << (_hp_word & (BITS_IN(BitWord) - 1)); \
26 #define CLEAR_MARK_BIT(closure) \
28 long _hp_word = ((P_)closure) - HeapBase; \
29 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
30 BitArray[_hp_word / BITS_IN(BitWord)] &= \
31 ~(1L << (_hp_word & (BITS_IN(BitWord) - 1))); \
36 #define SET_MARK_BIT(closure) \
38 long _hp_word = ((P_)closure) - HeapBase; \
39 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
40 DEBUG_SET_MARK(closure, _hp_word); \
41 BitArray[_hp_word / BITS_IN(BitWord)] |= \
42 1L << (_hp_word & (BITS_IN(BitWord) - 1)); \
45 #define CLEAR_MARK_BIT(closure) \
47 long _hp_word = ((P_)closure) - HeapBase; \
48 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
49 BitArray[_hp_word / BITS_IN(BitWord)] &= \
50 ~(1L << (_hp_word & (BITS_IN(BitWord) - 1))); \
55 Macros from hell for frobbing bits in the bit array while marking. We
56 maintain a counter after the mark bit that tells us which pointers
57 we've visited in a closure. The bits in this counter may span word
58 boundaries, and require some considerable ickiness to get munged into
59 one word so Mr C Programmer can use them.
61 Three variants follow. The first is for closures which contain fewer
62 pointers than there are bits in a word.
66 #define GM_MASK(x) ((1L << (x)) - 1)
68 #define GET_MARKED_PTRS(dest,closure,ptrs) \
70 long hw = ((P_)(closure)) - HeapBase + 1; \
71 BitWord *bw = BitArray + (hw / BITS_IN(BitWord)); \
72 int offset = hw & (BITS_IN(BitWord) - 1); \
73 int bat = BITS_IN(BitWord) - offset; \
75 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
77 (dest) = (ptrs) <= bat ? \
78 bw[0] >> offset & GM_MASK(ptrs) : \
80 (bw[1] & GM_MASK((ptrs) - bat)) << bat; \
83 /* hw is the offset in words of closure from HeapBase + 1.
85 bw points to the BitArray word containing the bit corresponding
86 to the *second* word of the closure [hence +1 above]
87 (the bit corresp first word is the mark bit)
89 offset is the offset (in bits, from LS end, zero indexed) within *bw
90 of the first bit of value in *bw,
92 bat is offset from the other end of the word; that's the same
93 as the number of bits available to store value in *bw.
96 NOTA BENE: this code is awfully conservative. In order to store a
97 value which ranges 0--ptrs we use a field of ptrs bits wide. We
98 only need a field of log(ptrs) wide!
102 /* "ptrs" is actually used as the width of the bit-field
103 in which we store "val". */
105 #define SET_MARKED_PTRS(closure,ptrs,val) \
107 long hw = ((P_)(closure)) - HeapBase + 1; \
108 BitWord *bw = BitArray + (hw / BITS_IN(BitWord)); \
109 int offset = hw & (BITS_IN(BitWord) - 1); \
110 int bat = BITS_IN(BitWord) - offset; \
113 ASSERT( (ptrs) < BITS_IN(BitWord) ); \
114 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
116 bits = bw[0] & ~(GM_MASK(ptrs) << offset); \
117 bw[0] = bits | (val) << offset; \
118 if ((ptrs) > bat) { \
119 bits = bw[1] & ~GM_MASK((ptrs) - bat); \
120 bw[1] = bits | ((val) >> bat); \
123 /* NB Since ptrs < BITS_IN(BitWord)
124 we can be sure that the conditional will only happen if bat is strictly
125 *smaller* than BITS_IN(BitWord), and hence the right shift in the
129 * These are for the GEN family, which may blow up the GM_MASK macro.
132 /* If there are more ptrs than bits in a word, we still
133 use just one word to store the value; value is bound to
134 be < 2**(bits-in-word - 1) */
136 #define __MIN__(a,b) (((a) < (b)) ? (a) : (b))
138 #define GET_GEN_MARKED_PTRS(dest,closure,ptrs) \
139 GET_MARKED_PTRS(dest,closure,__MIN__(ptrs,BITS_IN(BitWord)-1))
141 #define SET_GEN_MARKED_PTRS(closure,ptrs,val) \
142 SET_MARKED_PTRS(closure,__MIN__(ptrs,BITS_IN(BitWord)-1),val)
144 /* Be very careful to use the following macro only for dynamic closures! */
146 #define IS_MARK_BIT_SET(closure) \
147 ((BitArray[(((P_)closure) - HeapBase) / BITS_IN(BitWord)] >> \
148 ((((P_)closure) - HeapBase) & (BITS_IN(BitWord) - 1))) & 0x1)
153 Don't set the mark bit when changing to marking in the next pointer.
156 #define INIT_MARK_NODE(dbg,ptrs) \
158 DEBUG_PRSTART(dbg, ptrs); \
159 LINK_GLOBALADDRESS(Mark); \
160 SET_MARK_BIT(Mark); \
163 #define CONTINUE_MARKING_NODE(dbg,pos) \
165 DEBUG_PRIN(dbg, pos); \
169 @JUMP_MARK@ and @JUMP_MARK_RETURN@ define how to jump to the marking
170 entry code for a child closure (\tr{Mark}), or to the return code for
171 its parent (\tr{MStack}), when marking's been completed.
175 JMP_(PRMARK_CODE(INFO_PTR(Mark)))
177 #define JUMP_MARK_RETURN \
178 JMP_(PRRETURN_CODE(INFO_PTR(MStack)))
181 Initialise the marking stack to mark from the first pointer in the
182 closure (as specified by \tr{first_ptr}). The type of the closure is
183 given by \tr{closure_ptr}.
186 #define INIT_MSTACK_FROM(closure_ptr,first_ptr) \
188 P_ temp = (P_) closure_ptr(Mark, first_ptr); \
189 closure_ptr(Mark, first_ptr) = (W_) MStack; \
190 /*fprintf(stderr,"first_ptr=%d;temp=%lx;Mark=%lx;MStack=%lx\n",first_ptr,temp,Mark,MStack);*/ \
197 Initialise the marking stack to mark from the first pointer in
198 the closure. The type of the closure is given by \tr{closure_ptr}.
201 #define INIT_MSTACK(closure_ptr) \
202 INIT_MSTACK_FROM(closure_ptr,1)
205 Move to the next pointer after \tr{pos} in the closure whose
206 type is given by \tr{closure_ptr}.
209 #define MOVE_TO_NEXT_PTR(closure_ptr,pos) \
211 P_ temp = (P_) closure_ptr(MStack, pos+1); \
212 closure_ptr(MStack, pos+1) = closure_ptr(MStack, pos); \
213 closure_ptr(MStack, pos) = (W_) Mark; \
219 Pop the mark stack at \tr{pos}, having flushed all pointers in
223 #define POP_MSTACK(dbg,closure_ptr,pos) \
225 RESTORE_MSTACK(dbg,closure_ptr,pos); \
229 #define RESTORE_MSTACK(dbg,closure_ptr,pos) \
232 DEBUG_PRLAST(dbg, pos); \
234 MStack = (P_) closure_ptr(Mark, pos); \
235 closure_ptr(Mark, pos) = (W_) temp; \
239 Define some debugging macros.
242 #if defined(_GC_DEBUG)
244 #define DEBUG_PRSTART(type, ptrsvar) \
246 fprintf(stderr, "PRMark Start (%s): 0x%lx, info 0x%lx ptrs %ld\n", \
247 type, Mark, INFO_PTR(Mark), ptrsvar)
249 #define DEBUG_PRIN(type, posvar) \
251 fprintf(stderr, "PRRet In (%s): 0x%lx, info 0x%lx pos %ld\n", \
252 type, MStack, INFO_PTR(MStack), posvar)
254 #define DEBUG_PRLAST(type, ptrvar) \
256 fprintf(stderr, "PRRet Last (%s): 0x%lx, info 0x%lx ptrs %ld\n", \
257 type, MStack, INFO_PTR(MStack), ptrvar)
259 #define DEBUG_PR_MARKED \
261 fprintf(stderr, "PRMark Marked : 0x%lx, info 0x%lx\n", \
262 Mark, INFO_PTR(Mark))
264 #define DEBUG_PR_STAT \
266 fprintf(stderr, "PRMark Static : 0x%lx, info 0x%lx\n", \
267 Mark, INFO_PTR(Mark))
269 #define DEBUG_PR_IND \
271 fprintf(stderr, "PRMark Ind : 0x%lx -> PRMark(0x%lx), info 0x%lx\n", \
272 Mark, IND_CLOSURE_PTR(Mark), INFO_PTR(Mark))
274 #define DEBUG_PR_CAF \
276 fprintf(stderr, "PRMark Caf : 0x%lx -> PRMark(0x%lx), info 0x%lx\n", \
277 Mark, IND_CLOSURE_PTR(Mark), INFO_PTR(Mark))
279 #define DEBUG_PR_CONST \
281 fprintf(stderr, "PRMark Const : 0x%lx -> 0x%lx, info 0x%lx\n", \
282 Mark, CONST_STATIC_CLOSURE(INFO_PTR(Mark)), INFO_PTR(Mark))
284 #define DEBUG_PR_CHARLIKE \
286 fprintf(stderr, "PRMark CharLike (%lx) : 0x%lx -> 0x%lx, info 0x%lx\n", \
287 CHARLIKE_VALUE(Mark), Mark, CHARLIKE_CLOSURE(CHARLIKE_VALUE(Mark)), INFO_PTR(Mark))
289 #define DEBUG_PR_INTLIKE_TO_STATIC \
291 fprintf(stderr, "PRMark IntLike to Static (%ld) : 0x%lx -> 0x%lx, info 0x%lx\n", \
292 INTLIKE_VALUE(Mark), Mark, INTLIKE_CLOSURE(INTLIKE_VALUE(Mark)), INFO_PTR(Mark))
294 #define DEBUG_PR_INTLIKE_IN_HEAP \
296 fprintf(stderr, "PRMark IntLike in Heap (%ld) : 0x%lx, info 0x%lx\n", \
297 INTLIKE_VALUE(Mark), Mark, INFO_PTR(Mark))
299 #define DEBUG_PR_OLDIND \
301 fprintf(stderr, "PRMark OldRoot Ind : 0x%lx -> PRMark(0x%lx), info 0x%lx\n", \
302 Mark, IND_CLOSURE_PTR(Mark), INFO_PTR(Mark))
306 #define DEBUG_PRSTART(type, ptrvar)
307 #define DEBUG_PRIN(type, posvar)
308 #define DEBUG_PRLAST(type, ptrvar)
309 #define DEBUG_PR_MARKED
310 #define DEBUG_PR_STAT
313 #define DEBUG_PR_CONST
314 #define DEBUG_PR_CHARLIKE
315 #define DEBUG_PR_INTLIKE_TO_STATIC
316 #define DEBUG_PR_INTLIKE_IN_HEAP
317 #define DEBUG_PR_OLDIND