The checkHeap function assumed the allocated part of the block contained only
alive objects and slops. This was not true for blocks that are collected using
mark sweep. The code in this patch skip the test for this kind of blocks.
#define BF_FRAGMENTED 64
/* we know about this block (for finding leaks) */
#define BF_KNOWN 128
+/* Block was swept in the last generation */
+#define BF_SWEPT 256
/* Finding the block descriptor for a given block -------------------------- */
if (!(bd->flags & BF_FRAGMENTED)) {
bd->flags |= BF_MARKED;
}
+
+ // BF_SWEPT should be marked only for blocks that are being
+ // collected in sweep()
+ bd->flags &= ~BF_SWEPT;
}
}
}
#endif
for (; bd != NULL; bd = bd->link) {
- p = bd->start;
- while (p < bd->free) {
- nat size = checkClosure((StgClosure *)p);
- /* This is the smallest size of closure that can live in the heap */
- ASSERT( size >= MIN_PAYLOAD_SIZE + sizeofW(StgHeader) );
- p += size;
+ if(!(bd->flags & BF_SWEPT)) {
+ p = bd->start;
+ while (p < bd->free) {
+ nat size = checkClosure((StgClosure *)p);
+ /* This is the smallest size of closure that can live in the heap */
+ ASSERT( size >= MIN_PAYLOAD_SIZE + sizeofW(StgHeader) );
+ p += size;
- /* skip over slop */
- while (p < bd->free &&
- (*p < 0x1000 || !LOOKS_LIKE_INFO_PTR(*p))) { p++; }
+ /* skip over slop */
+ while (p < bd->free &&
+ (*p < 0x1000 || !LOOKS_LIKE_INFO_PTR(*p))) { p++; }
+ }
}
}
}
fragd++;
bd->flags |= BF_FRAGMENTED;
}
+
+ bd->flags |= BF_SWEPT;
}
}