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.
17 #define SET_MARK_BIT(closure) \
19 if (closure <= HeapLim) /* tested heap range for GCgn */ \
21 long _hp_word = ((P_)closure) - HeapBase; \
22 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
23 DEBUG_SET_MARK(closure, _hp_word); \
24 BitArray[_hp_word / BITS_IN(BitWord)] |= \
25 1L << (_hp_word & (BITS_IN(BitWord) - 1)); \
29 #define CLEAR_MARK_BIT(closure) \
31 long _hp_word = ((P_)closure) - HeapBase; \
32 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
33 BitArray[_hp_word / BITS_IN(BitWord)] &= \
34 ~(1L << (_hp_word & (BITS_IN(BitWord) - 1))); \
39 #define SET_MARK_BIT(closure) \
41 long _hp_word = ((P_)closure) - HeapBase; \
42 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
43 DEBUG_SET_MARK(closure, _hp_word); \
44 BitArray[_hp_word / BITS_IN(BitWord)] |= \
45 1L << (_hp_word & (BITS_IN(BitWord) - 1)); \
48 #define CLEAR_MARK_BIT(closure) \
50 long _hp_word = ((P_)closure) - HeapBase; \
51 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
52 BitArray[_hp_word / BITS_IN(BitWord)] &= \
53 ~(1L << (_hp_word & (BITS_IN(BitWord) - 1))); \
58 Macros from hell for frobbing bits in the bit array while marking. We
59 maintain a counter after the mark bit that tells us which pointers
60 we've visited in a closure. The bits in this counter may span word
61 boundaries, and require some considerable ickiness to get munged into
62 one word so Mr C Programmer can use them.
64 Three variants follow. The first is for closures which contain fewer
65 pointers than there are bits in a word.
69 #define GM_MASK(x) ((1L << (x)) - 1)
71 #define GET_MARKED_PTRS(dest,closure,ptrs) \
73 long hw = ((P_)(closure)) - HeapBase + 1; \
74 BitWord *bw = BitArray + (hw / BITS_IN(BitWord)); \
75 int offset = hw & (BITS_IN(BitWord) - 1); \
76 int bat = BITS_IN(BitWord) - offset; \
78 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
80 (dest) = (ptrs) <= bat ? \
81 bw[0] >> offset & GM_MASK(ptrs) : \
83 (bw[1] & GM_MASK((ptrs) - bat)) << bat; \
86 /* hw is the offset in words of closure from HeapBase + 1.
88 bw points to the BitArray word containing the bit corresponding
89 to the *second* word of the closure [hence +1 above]
90 (the bit corresp first word is the mark bit)
92 offset is the offset (in bits, from LS end, zero indexed) within *bw
93 of the first bit of value in *bw,
95 bat is offset from the other end of the word; that's the same
96 as the number of bits available to store value in *bw.
99 NOTA BENE: this code is awfully conservative. In order to store a
100 value which ranges 0--ptrs we use a field of ptrs bits wide. We
101 only need a field of log(ptrs) wide!
105 /* "ptrs" is actually used as the width of the bit-field
106 in which we store "val". */
108 #define SET_MARKED_PTRS(closure,ptrs,val) \
110 long hw = ((P_)(closure)) - HeapBase + 1; \
111 BitWord *bw = BitArray + (hw / BITS_IN(BitWord)); \
112 int offset = hw & (BITS_IN(BitWord) - 1); \
113 int bat = BITS_IN(BitWord) - offset; \
116 ASSERT( (ptrs) < BITS_IN(BitWord) ); \
117 ASSERT(!IS_STATIC(INFO_PTR(closure))); \
119 bits = bw[0] & ~(GM_MASK(ptrs) << offset); \
120 bw[0] = bits | (val) << offset; \
121 if ((ptrs) > bat) { \
122 bits = bw[1] & ~GM_MASK((ptrs) - bat); \
123 bw[1] = bits | ((val) >> bat); \
126 /* NB Since ptrs < BITS_IN(BitWord)
127 we can be sure that the conditional will only happen if bat is strictly
128 *smaller* than BITS_IN(BitWord), and hence the right shift in the
132 * These are for the GEN family, which may blow up the GM_MASK macro.
135 /* If there are more ptrs than bits in a word, we still
136 use just one word to store the value; value is bound to
137 be < 2**(bits-in-word - 1) */
139 #define __MIN__(a,b) (((a) < (b)) ? (a) : (b))
141 #define GET_GEN_MARKED_PTRS(dest,closure,ptrs) \
142 GET_MARKED_PTRS(dest,closure,__MIN__(ptrs,BITS_IN(BitWord)-1))
144 #define SET_GEN_MARKED_PTRS(closure,ptrs,val) \
145 SET_MARKED_PTRS(closure,__MIN__(ptrs,BITS_IN(BitWord)-1),val)
147 /* Be very careful to use the following macro only for dynamic closures! */
149 #define IS_MARK_BIT_SET(closure) \
150 ((BitArray[(((P_)closure) - HeapBase) / BITS_IN(BitWord)] >> \
151 ((((P_)closure) - HeapBase) & (BITS_IN(BitWord) - 1))) & 0x1)
156 Don't set the mark bit when changing to marking in the next pointer.
159 #define INIT_MARK_NODE(dbg,ptrs) \
161 DEBUG_PRSTART(dbg, ptrs); \
162 LINK_GLOBALADDRESS(Mark); \
163 SET_MARK_BIT(Mark); \
166 #define CONTINUE_MARKING_NODE(dbg,pos) \
168 DEBUG_PRIN(dbg, pos); \
172 @JUMP_MARK@ and @JUMP_MARK_RETURN@ define how to jump to the marking
173 entry code for a child closure (\tr{Mark}), or to the return code for
174 its parent (\tr{MStack}), when marking's been completed.
178 JMP_(PRMARK_CODE(INFO_PTR(Mark)))
180 #define JUMP_MARK_RETURN \
181 JMP_(PRRETURN_CODE(INFO_PTR(MStack)))
184 Initialise the marking stack to mark from the first pointer in the
185 closure (as specified by \tr{first_ptr}). The type of the closure is
186 given by \tr{closure_ptr}.
189 #define INIT_MSTACK_FROM(closure_ptr,first_ptr) \
191 P_ temp = (P_) closure_ptr(Mark, first_ptr); \
192 closure_ptr(Mark, first_ptr) = (W_) MStack; \
193 /*fprintf(stderr,"first_ptr=%d;temp=%lx;Mark=%lx;MStack=%lx\n",first_ptr,temp,Mark,MStack);*/ \
200 Initialise the marking stack to mark from the first pointer in
201 the closure. The type of the closure is given by \tr{closure_ptr}.
204 #define INIT_MSTACK(closure_ptr) \
205 INIT_MSTACK_FROM(closure_ptr,1)
208 Move to the next pointer after \tr{pos} in the closure whose
209 type is given by \tr{closure_ptr}.
212 #define MOVE_TO_NEXT_PTR(closure_ptr,pos) \
214 P_ temp = (P_) closure_ptr(MStack, pos+1); \
215 closure_ptr(MStack, pos+1) = closure_ptr(MStack, pos); \
216 closure_ptr(MStack, pos) = (W_) Mark; \
222 Pop the mark stack at \tr{pos}, having flushed all pointers in
226 #define POP_MSTACK(dbg,closure_ptr,pos) \
228 RESTORE_MSTACK(dbg,closure_ptr,pos); \
232 #define RESTORE_MSTACK(dbg,closure_ptr,pos) \
235 DEBUG_PRLAST(dbg, pos); \
237 MStack = (P_) closure_ptr(Mark, pos); \
238 closure_ptr(Mark, pos) = (W_) temp; \
242 Define some debugging macros.
247 #define DEBUG_PRSTART(type, ptrsvar) \
248 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
249 fprintf(stderr, "PRMark Start (%s): 0x%lx, info 0x%lx ptrs %ld\n", \
250 type, Mark, INFO_PTR(Mark), ptrsvar)
252 #define DEBUG_PRIN(type, posvar) \
253 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
254 fprintf(stderr, "PRRet In (%s): 0x%lx, info 0x%lx pos %ld\n", \
255 type, MStack, INFO_PTR(MStack), posvar)
257 #define DEBUG_PRLAST(type, ptrvar) \
258 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
259 fprintf(stderr, "PRRet Last (%s): 0x%lx, info 0x%lx ptrs %ld\n", \
260 type, MStack, INFO_PTR(MStack), ptrvar)
262 #define DEBUG_PR_MARKED \
263 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
264 fprintf(stderr, "PRMark Marked : 0x%lx, info 0x%lx\n", \
265 Mark, INFO_PTR(Mark))
267 #define DEBUG_PR_STAT \
268 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
269 fprintf(stderr, "PRMark Static : 0x%lx, info 0x%lx\n", \
270 Mark, INFO_PTR(Mark))
272 #define DEBUG_PR_IND \
273 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
274 fprintf(stderr, "PRMark Ind : 0x%lx -> PRMark(0x%lx), info 0x%lx\n", \
275 Mark, IND_CLOSURE_PTR(Mark), INFO_PTR(Mark))
277 #define DEBUG_PR_CAF \
278 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
279 fprintf(stderr, "PRMark Caf : 0x%lx -> PRMark(0x%lx), info 0x%lx\n", \
280 Mark, IND_CLOSURE_PTR(Mark), INFO_PTR(Mark))
282 #define DEBUG_PR_CONST \
283 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
284 fprintf(stderr, "PRMark Const : 0x%lx -> 0x%lx, info 0x%lx\n", \
285 Mark, CONST_STATIC_CLOSURE(INFO_PTR(Mark)), INFO_PTR(Mark))
287 #define DEBUG_PR_CHARLIKE \
288 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
289 fprintf(stderr, "PRMark CharLike (%lx) : 0x%lx -> 0x%lx, info 0x%lx\n", \
290 CHARLIKE_VALUE(Mark), Mark, CHARLIKE_CLOSURE(CHARLIKE_VALUE(Mark)), INFO_PTR(Mark))
292 #define DEBUG_PR_INTLIKE_TO_STATIC \
293 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
294 fprintf(stderr, "PRMark IntLike to Static (%ld) : 0x%lx -> 0x%lx, info 0x%lx\n", \
295 INTLIKE_VALUE(Mark), Mark, INTLIKE_CLOSURE(INTLIKE_VALUE(Mark)), INFO_PTR(Mark))
297 #define DEBUG_PR_INTLIKE_IN_HEAP \
298 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
299 fprintf(stderr, "PRMark IntLike in Heap (%ld) : 0x%lx, info 0x%lx\n", \
300 INTLIKE_VALUE(Mark), Mark, INFO_PTR(Mark))
302 #define DEBUG_PR_OLDIND \
303 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING) \
304 fprintf(stderr, "PRMark OldRoot Ind : 0x%lx -> PRMark(0x%lx), info 0x%lx\n", \
305 Mark, IND_CLOSURE_PTR(Mark), INFO_PTR(Mark))
309 #define DEBUG_PRSTART(type, ptrvar)
310 #define DEBUG_PRIN(type, posvar)
311 #define DEBUG_PRLAST(type, ptrvar)
312 #define DEBUG_PR_MARKED
313 #define DEBUG_PR_STAT
316 #define DEBUG_PR_CONST
317 #define DEBUG_PR_CHARLIKE
318 #define DEBUG_PR_INTLIKE_TO_STATIC
319 #define DEBUG_PR_INTLIKE_IN_HEAP
320 #define DEBUG_PR_OLDIND
324 #endif /* SMMARKDEFS_H */