calling resurrectThreads() (fixes #5314).
This avoids a lot of problems, because resurrectThreads() may
overwrite some closures in the heap, leaving slop behind. The bug in
instances, this fix avoids them all in one go.
// reset waiting_for_gc *before* GC, so that when the GC threads
// emerge they don't immediately re-enter the GC.
waiting_for_gc = 0;
- GarbageCollect(force_major || heap_census, gc_type, cap);
+ GarbageCollect(force_major || heap_census, heap_census, gc_type, cap);
#else
- GarbageCollect(force_major || heap_census, 0, cap);
+ GarbageCollect(force_major || heap_census, heap_census, 0, cap);
#endif
traceEventGcEnd(cap);
ASSERT(checkSparkCountInvariant());
#endif
+ // The heap census itself is done during GarbageCollect().
if (heap_census) {
- debugTrace(DEBUG_sched, "performing heap census");
- heapCensus();
- performHeapProfile = rtsFalse;
+ performHeapProfile = rtsFalse;
}
#if defined(THREADED_RTS)
void
GarbageCollect (rtsBool force_major_gc,
+ rtsBool do_heap_census,
nat gc_type USED_IF_THREADS,
Capability *cap)
{
// fill slop.
IF_DEBUG(sanity, checkSanity(rtsTrue /* after GC */, major_gc));
+ // If a heap census is due, we need to do it before
+ // resurrectThreads(), for the same reason as checkSanity above:
+ // resurrectThreads() will overwrite some closures and leave slop
+ // behind.
+ if (do_heap_census) {
+ debugTrace(DEBUG_sched, "performing heap census");
+ heapCensus();
+ }
+
// send exceptions to any threads which were about to die
RELEASE_SM_LOCK;
resurrectThreads(resurrected_threads);
#include "BeginPrivate.h"
-void GarbageCollect(rtsBool force_major_gc, nat gc_type, Capability *cap);
+void GarbageCollect (rtsBool force_major_gc,
+ rtsBool do_heap_census,
+ nat gc_type, Capability *cap);
typedef void (*evac_fn)(void *user, StgClosure **root);