diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c
index c43213043ef0c20e92db44da2165ad2120814320..d222d9c1f3c0e0d71aa0c53c5eae21b162fec7d0 100644
--- a/rts/sm/NonMoving.c
+++ b/rts/sm/NonMoving.c
@@ -375,7 +375,6 @@ memcount nonmoving_live_words = 0;
 #if defined(THREADED_RTS)
 static void* nonmovingConcurrentMark(void *mark_queue);
 #endif
-static void nonmovingClearBitmap(struct NonmovingSegment *seg);
 static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO **resurrected_threads);
 
 static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block_size)
@@ -682,7 +681,7 @@ void nonmovingAddCapabilities(uint32_t new_n_caps)
     nonmovingHeap.n_caps = new_n_caps;
 }
 
-static inline void nonmovingClearBitmap(struct NonmovingSegment *seg)
+void nonmovingClearBitmap(struct NonmovingSegment *seg)
 {
     unsigned int n = nonmovingSegmentBlockCount(seg);
     memset(seg->bitmap, 0, n);
@@ -696,9 +695,6 @@ static void nonmovingPrepareMark(void)
     static_flag =
         static_flag == STATIC_FLAG_A ? STATIC_FLAG_B : STATIC_FLAG_A;
 
-    // Should have been cleared by the last sweep
-    ASSERT(nonmovingHeap.sweep_list == NULL);
-
     nonmovingBumpEpoch();
     for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) {
         struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx];
@@ -1087,7 +1083,6 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
     nonmovingSweepStableNameTable();
 
     nonmovingSweep();
-    ASSERT(nonmovingHeap.sweep_list == NULL);
     debugTrace(DEBUG_nonmoving_gc, "Finished sweeping.");
     traceConcSweepEnd();
 #if defined(DEBUG)
diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h
index b3d4e14065cd718327b2fd16fa84b12a81e9a93b..36ecd8b0afc618fcd5c07452ee1fb61c32656d81 100644
--- a/rts/sm/NonMoving.h
+++ b/rts/sm/NonMoving.h
@@ -130,6 +130,7 @@ void nonmovingCollect(StgWeak **dead_weaks,
 void *nonmovingAllocate(Capability *cap, StgWord sz);
 void nonmovingAddCapabilities(uint32_t new_n_caps);
 void nonmovingPushFreeSegment(struct NonmovingSegment *seg);
+void nonmovingClearBitmap(struct NonmovingSegment *seg);
 
 
 INLINE_HEADER struct NonmovingSegmentInfo *nonmovingSegmentInfo(struct NonmovingSegment *seg) {
diff --git a/rts/sm/NonMovingSweep.c b/rts/sm/NonMovingSweep.c
index ead0e1cee8e804eb49b9514b2f009db9d570207b..2b8db9e4c6853735a47b34be0bb47d4dc04f9f70 100644
--- a/rts/sm/NonMovingSweep.c
+++ b/rts/sm/NonMovingSweep.c
@@ -127,6 +127,8 @@ clear_segment_free_blocks(struct NonmovingSegment* seg)
 
 GNUC_ATTR_HOT void nonmovingSweep(void)
 {
+    struct NonmovingSegment *new_sweep_list = NULL;
+
     while (nonmovingHeap.sweep_list) {
         struct NonmovingSegment *seg = nonmovingHeap.sweep_list;
 
@@ -146,12 +148,19 @@ GNUC_ATTR_HOT void nonmovingSweep(void)
             nonmovingPushActiveSegment(seg);
             break;
         case SEGMENT_FILLED:
-            nonmovingPushFilledSegment(seg);
+            // Clear bitmap
+            nonmovingClearBitmap(seg);
+            // Set snapshot
+            nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
+            seg->link = new_sweep_list;
+            new_sweep_list = seg;
             break;
         default:
             barf("nonmovingSweep: weird sweep return: %d\n", ret);
         }
     }
+
+    nonmovingHeap.sweep_list = new_sweep_list;
 }
 
 /* Must a closure remain on the mutable list?