[Git][ghc/ghc][wip/T22264-9.2] 5 commits: NonMovingSweep: Wibbles

Ben Gamari (@bgamari) gitlab at gitlab.haskell.org
Sun Oct 23 03:15:46 UTC 2022



Ben Gamari pushed to branch wip/T22264-9.2 at Glasgow Haskell Compiler / GHC


Commits:
27c49628 by Ben Gamari at 2022-10-22T23:12:31-04:00
NonMovingSweep: Wibbles

- - - - -
02d93484 by Ben Gamari at 2022-10-22T23:15:19-04:00
nonmoving: Fix tracking of FILLED_SWEEPING segments

Previously we only updated the state of the segment at the head of each
allocator's filled list.

- - - - -
229c36ad by Ben Gamari at 2022-10-22T23:15:19-04:00
nonmoving: Assert state of swept segments

- - - - -
8f18270f by Ben Gamari at 2022-10-22T23:15:19-04:00
nonmoving: Sanity check nonmoving large objects and compacts

- - - - -
3b6da4af by Ben Gamari at 2022-10-22T23:15:19-04:00
nonmoving: Post-sweep sanity checking

- - - - -


4 changed files:

- rts/sm/NonMoving.c
- rts/sm/NonMoving.h
- rts/sm/NonMovingSweep.c
- rts/sm/Sanity.c


Changes:

=====================================
rts/sm/NonMoving.c
=====================================
@@ -26,8 +26,11 @@
 #include "NonMovingCensus.h"
 #include "StablePtr.h" // markStablePtrTable
 #include "Schedule.h" // markScheduler
+#include "Sanity.h"
 #include "Weak.h" // scheduleFinalizers
 
+#define NONCONCURRENT_SWEEP
+
 struct NonmovingHeap nonmovingHeap;
 
 uint8_t nonmovingMarkEpoch = 1;
@@ -1063,6 +1066,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
             while (true) {
                 // Set snapshot
                 nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
+                SET_SEGMENT_STATE(seg, FILLED_SWEEPING);
                 n_filled++;
                 if (seg->link) {
                     seg = seg->link;
@@ -1071,7 +1075,6 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
                 }
             }
             // add filled segments to sweep_list
-            SET_SEGMENT_STATE(seg, FILLED_SWEEPING);
             seg->link = nonmovingHeap.sweep_list;
             nonmovingHeap.sweep_list = filled;
         }
@@ -1180,7 +1183,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
 #endif
 
     // Everything has been marked; allow the mutators to proceed
-#if defined(THREADED_RTS)
+#if defined(THREADED_RTS) && !defined(NONCONCURRENT_SWEEP)
     nonmoving_write_barrier_enabled = false;
     nonmovingFinishFlush(task);
 #endif
@@ -1219,6 +1222,15 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
         nonmovingTraceAllocatorCensus();
 #endif
 
+#if defined(THREADED_RTS) && defined(NONCONCURRENT_SWEEP)
+#if defined(DEBUG)
+    checkNonmovingHeap(&nonmovingHeap);
+    checkSanity(true, true);
+#endif
+    nonmoving_write_barrier_enabled = false;
+    nonmovingFinishFlush(task);
+#endif
+
     // TODO: Remainder of things done by GarbageCollect (update stats)
 
 #if defined(THREADED_RTS)


=====================================
rts/sm/NonMoving.h
=====================================
@@ -46,8 +46,10 @@ enum NonmovingSegmentState {
 };
 
 #define SET_SEGMENT_STATE(seg, st) (seg)->state = (st)
+#define ASSERT_SEGMENT_STATE(seg, st) ASSERT((seg)->state == (st))
 #else
 #define SET_SEGMENT_STATE(_seg,_st)
+#define ASSERT_SEGMENT_STATE(_seg, _st)
 #endif
 
 // A non-moving heap segment


=====================================
rts/sm/NonMovingSweep.c
=====================================
@@ -31,6 +31,7 @@ enum SweepResult {
 GNUC_ATTR_HOT static enum SweepResult
 nonmovingSweepSegment(struct NonmovingSegment *seg)
 {
+    ASSERT_SEGMENT_STATE(seg, FILLED_SWEEPING);
     const nonmoving_block_idx blk_cnt = nonmovingSegmentBlockCount(seg);
     bool found_free = false;
     bool found_live = false;
@@ -39,20 +40,20 @@ nonmovingSweepSegment(struct NonmovingSegment *seg)
     {
         if (seg->bitmap[i] == nonmovingMarkEpoch) {
             found_live = true;
-        } else if (!found_free) {
-            // This is the first free block we've found; set next_free,
-            // next_free_snap, and the scan pointer.
-            found_free = true;
-            seg->next_free = i;
-            nonmovingSegmentInfo(seg)->next_free_snap = i;
-            Bdescr((P_)seg)->u.scan = (P_)nonmovingSegmentGetBlock(seg, i);
-            seg->bitmap[i] = 0;
         } else {
             seg->bitmap[i] = 0;
+            if (!found_free) {
+                // This is the first free block we've found; set next_free,
+                // next_free_snap, and the scan pointer.
+                found_free = true;
+                seg->next_free = i;
+                nonmovingSegmentInfo(seg)->next_free_snap = i;
+                Bdescr((P_)seg)->u.scan = (P_)nonmovingSegmentGetBlock(seg, i);
+            }
         }
 
         if (found_free && found_live) {
-            // zero the remaining dead object's mark bits
+            // zero the remaining dead objects mark bits
             for (; i < nonmovingSegmentBlockCount(seg); ++i) {
                 if (seg->bitmap[i] != nonmovingMarkEpoch) {
                     seg->bitmap[i] = 0;
@@ -118,7 +119,8 @@ clear_segment_free_blocks(struct NonmovingSegment* seg)
 {
     unsigned int block_size = nonmovingSegmentBlockSize(seg);
     for (unsigned int p_idx = 0; p_idx < nonmovingSegmentBlockCount(seg); ++p_idx) {
-        // after mark, so bit not set == dead
+        // N.B. nonmovingSweepSegment helpfully clears the bitmap entries of
+        // dead blocks
         if (nonmovingGetMark(seg, p_idx) == 0) {
             memset(nonmovingSegmentGetBlock(seg, p_idx), 0, block_size);
         }


=====================================
rts/sm/Sanity.c
=====================================
@@ -44,6 +44,8 @@ static void  checkLargeBitmap    ( StgPtr payload, StgLargeBitmap*, uint32_t );
 static void  checkClosureShallow ( const StgClosure * );
 static void  checkSTACK          (StgStack *stack);
 
+static void  checkCompactObjects (bdescr *bd);
+
 static W_    countNonMovingSegments ( struct NonmovingSegment *segs );
 static W_    countNonMovingHeap     ( struct NonmovingHeap *heap );
 
@@ -618,6 +620,9 @@ static void checkNonmovingSegments (struct NonmovingSegment *seg)
 
 void checkNonmovingHeap (const struct NonmovingHeap *heap)
 {
+    checkLargeObjects(nonmoving_large_objects);
+    checkLargeObjects(nonmoving_marked_large_objects);
+    checkCompactObjects(nonmoving_compact_objects);
     for (unsigned int i=0; i < NONMOVING_ALLOCA_CNT; i++) {
         const struct NonmovingAllocator *alloc = heap->allocators[i];
         checkNonmovingSegments(alloc->filled);



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/279279db1bc106c3e0008cb056d7421b55aac4e4...3b6da4afdbd3d1951df4d4f635115132b3cb14bf

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/279279db1bc106c3e0008cb056d7421b55aac4e4...3b6da4afdbd3d1951df4d4f635115132b3cb14bf
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20221022/629c2262/attachment-0001.html>


More information about the ghc-commits mailing list