summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-11-30 21:55:58 -0500
committerBen Gamari <ben@smart-cactus.org>2019-12-01 16:13:07 -0500
commita3541436e6eb96b0a1bc3a2c2a60905c85e66e0e (patch)
treebeb2dc807ffee91ca7d709525083171c1be16510
parent7f72b540288bbdb32a6750dd64b9d366501ed10c (diff)
downloadhaskell-a3541436e6eb96b0a1bc3a2c2a60905c85e66e0e.tar.gz
nonmoving: Clear segment bitmaps during sweepwip/gc/clear-bitmap-during-sweep
Previously we would clear the bitmaps of segments which we are going to sweep during the preparatory pause. However, this is unnecessary: the existence of the mark epoch ensures that the sweep will correctly identify non-reachable objects, even if we do not clear the bitmap. We now defer clearing the bitmap to sweep, which happens concurrently with mutation.
-rw-r--r--rts/sm/NonMoving.c9
-rw-r--r--rts/sm/NonMoving.h1
-rw-r--r--rts/sm/NonMovingSweep.c1
3 files changed, 4 insertions, 7 deletions
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c
index 50cf784aab..e9daf91bde 100644
--- a/rts/sm/NonMoving.c
+++ b/rts/sm/NonMoving.c
@@ -374,7 +374,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)
@@ -681,7 +680,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);
@@ -715,13 +714,9 @@ static void nonmovingPrepareMark(void)
if (filled) {
struct NonmovingSegment *seg = filled;
while (true) {
- n_filled++;
- prefetchForRead(seg->link);
- // Clear bitmap
- prefetchForWrite(seg->link->bitmap);
- nonmovingClearBitmap(seg);
// Set snapshot
nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
+ n_filled++;
if (seg->link)
seg = seg->link;
else
diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h
index b3d4e14065..36ecd8b0af 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 cf5fcd70d7..a136f5f5f4 100644
--- a/rts/sm/NonMovingSweep.c
+++ b/rts/sm/NonMovingSweep.c
@@ -65,6 +65,7 @@ nonmovingSweepSegment(struct NonmovingSegment *seg)
} else {
ASSERT(seg->next_free == 0);
ASSERT(nonmovingSegmentInfo(seg)->next_free_snap == 0);
+ nonmovingClearBitmap(seg);
return SEGMENT_FREE;
}
}