CNF.c:insertCompactHash doesn't correctly dirty regions
Consider CNF.c:insertCompactHash
:
void
insertCompactHash (Capability *cap,
StgCompactNFData *str,
StgClosure *p, StgClosure *to)
{
insertHashTable(str->hash, (StgWord)p, (const void*)to);
const StgInfoTable *strinfo = &str->header.info;
if (strinfo == &stg_COMPACT_NFDATA_CLEAN_info) {
strinfo = &stg_COMPACT_NFDATA_DIRTY_info;
recordClosureMutated(cap, (StgClosure*)str);
}
}
At first glance this looks reasonable. However, note how we are dirtying the region:
strinfo = &stg_COMPACT_NFDATA_DIRTY_info;
This does not do at all what we want; it simply sets the local variable, not the info table pointer.
For this reason compact regions with sharing preservation enabled get added to the mut_list
once for every object in the region. Terrible!