Move the call to heapCensus() into GarbageCollect(), just before
authorSimon Marlow <marlowsd@gmail.com>
Wed, 20 Jul 2011 14:29:54 +0000 (15:29 +0100)
committerSimon Marlow <marlowsd@gmail.com>
Wed, 20 Jul 2011 15:23:29 +0000 (16:23 +0100)
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.

rts/Schedule.c
rts/sm/GC.c
rts/sm/GC.h

index 2a2cc22..834e3eb 100644 (file)
@@ -1443,9 +1443,9 @@ delete_threads_and_gc:
     // 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);
 
@@ -1473,10 +1473,9 @@ delete_threads_and_gc:
     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)
index 9f69a4c..396992c 100644 (file)
@@ -171,6 +171,7 @@ StgPtr mark_sp;            // pointer to the next unallocated mark stack entry
 
 void
 GarbageCollect (rtsBool force_major_gc, 
+                rtsBool do_heap_census,
                 nat gc_type USED_IF_THREADS,
                 Capability *cap)
 {
@@ -661,6 +662,15 @@ GarbageCollect (rtsBool force_major_gc,
   // 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);
index 38fc87c..eb18023 100644 (file)
@@ -16,7 +16,9 @@
 
 #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);