Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/gc/check-heap.c
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/check-heap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 250 - (view) (download) (as text)

1 : monnier 249 /* check-heap.c
2 :     *
3 :     * COPYRIGHT (c) 1994 by AT&T Bell Laboratories.
4 :     */
5 :    
6 :     #include "ml-base.h"
7 :     #include "card-map.h"
8 :     #include "heap.h"
9 :     #include "c-globals-tbl.h"
10 :    
11 :     #ifndef CHECK_HEAP
12 :     # error CHECK_HEAP must be defined too
13 :     #endif
14 :    
15 :     /* local routines */
16 :     PVT void CheckRecordArena (arena_t *ap);
17 :     PVT void CheckPairArena (arena_t *ap);
18 :     PVT void CheckStringArena (arena_t *ap);
19 :     PVT void CheckArrayArena (arena_t *ap, card_map_t *cm);
20 :     PVT int CheckPtr (ml_val_t *p, ml_val_t w, int srcGen, int srcKind, int dstKind);
21 :    
22 :     PVT int ErrCount = 0;
23 :    
24 :     /* CheckPtr dstKind values */
25 :     #define OBJC_NEWFLG (1 << OBJC_new)
26 :     #define OBJC_RECFLG (1 << OBJC_record)
27 :     #define OBJC_PAIRFLG (1 << OBJC_pair)
28 :     #define OBJC_STRFLG (1 << OBJC_string)
29 :     #define OBJC_ARRFLG (1 << OBJC_array)
30 :     #define OBJC_any \
31 :     (OBJC_NEWFLG|OBJC_RECFLG|OBJC_PAIRFLG|OBJC_STRFLG|OBJC_ARRFLG)
32 :    
33 :     #define ERROR { \
34 :     if (++ErrCount > 100) { \
35 :     Die("CheckHeap: too many errors\n"); \
36 :     } \
37 :     }
38 :    
39 :    
40 :     /* CheckHeap:
41 :     *
42 :     * Check the heap for consistency after a garbage collection (or blast out).
43 :     */
44 :     void CheckHeap (heap_t *heap, int maxSweptGen)
45 :     {
46 :     int i, j;
47 :    
48 :     ErrCount = 0;
49 :    
50 :     SayDebug ("Checking heap (%d generations) ...\n", maxSweptGen);
51 :     for (i = 0; i < maxSweptGen; i++) {
52 :     gen_t *g = heap->gen[i];
53 :    
54 :     CheckRecordArena (g->arena[RECORD_INDX]);
55 :     CheckPairArena (g->arena[PAIR_INDX]);
56 :     CheckStringArena (g->arena[STRING_INDX]);
57 :     CheckArrayArena (g->arena[ARRAY_INDX], g->dirty);
58 :     }
59 :     SayDebug ("... done\n");
60 :    
61 :     if (ErrCount > 0)
62 :     Die ("CheckHeap --- inconsistent heap\n");
63 :    
64 :     } /* end of CheckHeap */
65 :    
66 :     /* CheckRecordArena:
67 :     *
68 :     * Check the record arena.
69 :     */
70 :     PVT void CheckRecordArena (arena_t *ap)
71 :     {
72 :     ml_val_t *p, *stop, desc, w;
73 :     int i, len;
74 :     int gen = EXTRACT_GEN(ap->id);
75 :    
76 :     if (! isACTIVE(ap))
77 :     return;
78 :    
79 :     SayDebug (" records [%d]: [%#x..%#x:%#x)\n",
80 :     gen, ap->tospBase, ap->nextw, ap->tospTop);
81 :    
82 :     p = ap->tospBase;
83 :     stop = ap->nextw;
84 :     while (p < stop) {
85 :     desc = *p++;
86 :     if (! isDESC(desc)) {
87 :     ERROR;
88 :     SayDebug (
89 :     "** @%#x: expected descriptor, but found %#x in record arena\n",
90 :     p-1, desc);
91 :     return;
92 :     }
93 :     switch (GET_TAG(desc)) {
94 :     case DTAG_record:
95 :     len = GET_LEN(desc);
96 :     for (i = 0; i < len; i++, p++) {
97 :     w = *p;
98 :     if (isDESC(w)) {
99 :     ERROR;
100 :     SayDebug (
101 :     "** @%#x: unexpected descriptor %#x in slot %d of %d\n",
102 :     p, w, i, GET_LEN(desc));
103 :     return;
104 :     }
105 :     else if (isBOXED(w)) {
106 :     CheckPtr(p, w, gen, OBJC_record, OBJC_any);
107 :     }
108 :     }
109 :     break;
110 :     case DTAG_arr_hdr:
111 :     case DTAG_vec_hdr:
112 :     switch (GET_LEN(desc)) {
113 :     case SEQ_poly:
114 :     if (GET_TAG(desc) == DTAG_arr_hdr)
115 :     CheckPtr (p, *p, gen, OBJC_record, OBJC_ARRFLG);
116 :     else
117 :     CheckPtr (p, *p, gen, OBJC_record, OBJC_RECFLG|OBJC_PAIRFLG);
118 :     break;
119 :     case SEQ_word8:
120 :     case SEQ_word16:
121 :     case SEQ_word31:
122 :     case SEQ_word32:
123 :     case SEQ_real32:
124 :     case SEQ_real64:
125 :     CheckPtr (p, *p, gen, OBJC_record, OBJC_STRFLG);
126 :     break;
127 :     default:
128 :     ERROR;
129 :     SayDebug ("** @%#x: strange sequence kind %d in record arena\n",
130 :     p-1, GET_LEN(desc));
131 :     return;
132 :     }
133 :     if (! isUNBOXED(p[1])) {
134 :     ERROR;
135 :     SayDebug ("** @%#x: sequence header length field not an in (%#x)\n",
136 :     p+1, p[1]);
137 :     }
138 :     p += 2;
139 :     break;
140 :     default:
141 :     ERROR;
142 :     SayDebug ("** @%#x: strange tag (%#x) in record arena\n",
143 :     p-1, GET_TAG(desc));
144 :     return;
145 :     } /* end of switch */
146 :     }
147 :    
148 :     } /* end of CheckRecordArena */
149 :    
150 :     /* CheckPairArena:
151 :     */
152 :     PVT void CheckPairArena (arena_t *ap)
153 :     {
154 :     ml_val_t *p, *stop, w;
155 :     int gen = EXTRACT_GEN(ap->id);
156 :    
157 :     if (! isACTIVE(ap))
158 :     return;
159 :    
160 :     SayDebug (" pairs [%d]: [%#x..%#x:%#x)\n",
161 :     gen, ap->tospBase, ap->nextw, ap->tospTop);
162 :    
163 :     p = ap->tospBase + 2;
164 :     stop = ap->nextw;
165 :     while (p < stop) {
166 :     w = *p++;
167 :     if (isDESC(w)) {
168 :     ERROR;
169 :     SayDebug (
170 :     "** @%#x: unexpected descriptor %#x in pair arena\n",
171 :     p-1, w);
172 :     return;
173 :     }
174 :     else if (isBOXED(w)) {
175 :     CheckPtr(p, w, gen, OBJC_pair, OBJC_any);
176 :     }
177 :     }
178 :    
179 :     } /* end of CheckPairArena */
180 :    
181 :     /* CheckStringArena:
182 :     *
183 :     * Check a string arena for consistency.
184 :     */
185 :     PVT void CheckStringArena (arena_t *ap)
186 :     {
187 :     ml_val_t *p, *stop, *prevDesc, desc, next;
188 :     int len;
189 :     int gen = EXTRACT_GEN(ap->id);
190 :    
191 :     if (! isACTIVE(ap))
192 :     return;
193 :    
194 :     SayDebug (" strings [%d]: [%#x..%#x:%#x)\n",
195 :     gen, ap->tospBase, ap->nextw, ap->tospTop);
196 :    
197 :     p = ap->tospBase;
198 :     stop = ap->nextw;
199 :     prevDesc = NIL(ml_val_t *);
200 :     while (p < stop) {
201 :     desc = *p++;
202 :     if (isDESC(desc)) {
203 :     switch (GET_TAG(desc)) {
204 :     case DTAG_raw32:
205 :     case DTAG_raw64:
206 :     len = GET_LEN(desc);
207 :     break;
208 :     default:
209 :     ERROR;
210 :     SayDebug ("** @%#x: strange tag (%#x) in string arena\n",
211 :     p-1, GET_TAG(desc));
212 :     if (prevDesc != NIL(ml_val_t *))
213 :     SayDebug (" previous string started @ %#x\n", prevDesc);
214 :     return;
215 :     }
216 :     prevDesc = p-1;
217 :     p += len;
218 :     }
219 :     #ifdef ALIGN_REALDS
220 :     else if ((desc == 0) && (((Addr_t)p & WORD_SZB) != 0))
221 :     /* assume this is alignment padding */
222 :     continue;
223 :     #endif
224 :     else {
225 :     ERROR;
226 :     SayDebug (
227 :     "** @%#x: expected descriptor, but found %#x in string arena\n",
228 :     p-1, desc);
229 :     if (prevDesc != NIL(ml_val_t *))
230 :     SayDebug (" previous string started @ %#x\n", prevDesc);
231 :     return;
232 :     }
233 :     }
234 :    
235 :     } /* end of CheckStringArena */
236 :    
237 :     /* CheckArrayArena:
238 :     */
239 :     PVT void CheckArrayArena (arena_t *ap, card_map_t *cm)
240 :     {
241 :     ml_val_t *p, *stop, desc, w;
242 :     int i, j, len;
243 :     int gen = EXTRACT_GEN(ap->id);
244 :    
245 :     if (! isACTIVE(ap))
246 :     return;
247 :    
248 :     SayDebug (" arrays [%d]: [%#x..%#x:%#x)\n",
249 :     gen, ap->tospBase, ap->nextw, ap->tospTop);
250 :    
251 :     p = ap->tospBase;
252 :     stop = ap->nextw;
253 :     while (p < stop) {
254 :     desc = *p++;
255 :     if (! isDESC(desc)) {
256 :     ERROR;
257 :     SayDebug (
258 :     "** @%#x: expected descriptor, but found %#x in array arena\n",
259 :     p-1, desc);
260 :     return;
261 :     }
262 :     switch (GET_TAG(desc)) {
263 :     case DTAG_arr_data:
264 :     len = GET_LEN(desc);
265 :     break;
266 :     case DTAG_special:
267 :     len = 1;
268 :     break;
269 :     default:
270 :     ERROR;
271 :     SayDebug ("** @%#x: strange tag (%#x) in array arena\n",
272 :     p-1, GET_TAG(desc));
273 :     return;
274 :     } /* end of switch */
275 :     for (i = 0; i < len; i++, p++) {
276 :     w = *p;
277 :     if (isDESC(w)) {
278 :     ERROR;
279 :     SayDebug (
280 :     "** @%#x: unexpected descriptor %#x in array slot %d of %d\n",
281 :     p, w, i, GET_LEN(desc));
282 :     for (p -= (i+1), j = 0; j <= len; j++, p++) {
283 :     SayDebug (" %#x: %#10x\n", p, *p);
284 :     }
285 :     return;
286 :     }
287 :     else if (isBOXED(w)) {
288 :     CheckPtr(p, w, gen, OBJC_array, OBJC_any);
289 :     }
290 :     }
291 :     }
292 :    
293 :     } /* end of CheckArrayArena */
294 :    
295 :     /* CheckPtr:
296 :     */
297 :     PVT int CheckPtr (ml_val_t *p, ml_val_t w, int srcGen, int srcKind, int dstKind)
298 :     {
299 :     aid_t aid = ADDR_TO_PAGEID(BIBOP, w);
300 :     int dstGen = EXTRACT_GEN(aid);
301 :     int objc = EXTRACT_OBJC(aid);
302 :    
303 :     switch (objc) {
304 :     case OBJC_record:
305 :     case OBJC_pair:
306 :     case OBJC_string:
307 :     case OBJC_array:
308 :     if (!(dstKind & (1 << objc))) {
309 :     ERROR;
310 :     SayDebug (
311 :     "** @%#x: sequence data kind mismatch (expected %d, found %d)\n",
312 :     p, dstKind, objc);
313 :     }
314 :     if (dstGen < srcGen) {
315 :     if (srcKind != OBJC_array) {
316 :     ERROR;
317 :     SayDebug (
318 :     "** @%#x: reference to younger object @%#x (gen = %d)\n",
319 :     p, w, dstGen);
320 :     }
321 :     }
322 :     if ((objc != OBJC_pair) && (! isDESC(((ml_val_t *)w)[-1]))) {
323 :     ERROR;
324 :     SayDebug ("** @%#x: reference into object middle @#x\n", p, w);
325 :     }
326 :     break;
327 :     case OBJC_bigobj:
328 :     break;
329 :     case OBJC_new:
330 :     ERROR;
331 :     SayDebug ("** @%#x: unexpected new-space reference\n", p);
332 :     dstGen = MAX_NUM_GENS;
333 :     break;
334 :     default:
335 :     if (aid == AID_UNMAPPED) {
336 :     if (AddrToCSymbol(w) == NIL(const char *)) {
337 :     ERROR;
338 :     SayDebug (
339 :     "** @%#x: reference to unregistered external address %#x\n",
340 :     p, w);
341 :     }
342 :     dstGen = MAX_NUM_GENS;
343 :     }
344 :     else Die("bogus object class in BIBOP\n");
345 :     break;
346 :     } /* end of switch */
347 :    
348 :     return dstGen;
349 :    
350 :     } /* end of CheckPtr */
351 :    

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0