summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-03-03 23:42:14 -0500
committerBen Gamari <ben@smart-cactus.org>2020-03-03 23:42:14 -0500
commit56d4e0056ba55f0b3d4d4fb55e7425472e917d8b (patch)
tree369f651cb3bd5a388f6b579d0667cc72acc7b6e4
parent924af4dbf42eab8800ddfb02c5398ccf4b5f9c71 (diff)
downloadhaskell-56d4e0056ba55f0b3d4d4fb55e7425472e917d8b.tar.gz
Don't traverse filled segment list in pause
-rw-r--r--rts/sm/NonMoving.c40
-rw-r--r--rts/sm/NonMoving.h1
2 files changed, 23 insertions, 18 deletions
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c
index 2dd201f0f9..2bd81a3cb8 100644
--- a/rts/sm/NonMoving.c
+++ b/rts/sm/NonMoving.c
@@ -708,25 +708,8 @@ static void nonmovingPrepareMark(void)
nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
}
- // Update filled segments' snapshot pointers and move to sweep_list
- uint32_t n_filled = 0;
- struct NonmovingSegment *const filled = alloca->filled;
+ alloca->saved_filled = alloca->filled;
alloca->filled = NULL;
- if (filled) {
- struct NonmovingSegment *seg = filled;
- while (true) {
- // Set snapshot
- nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
- n_filled++;
- if (seg->link)
- seg = seg->link;
- else
- break;
- }
- // add filled segments to sweep_list
- seg->link = nonmovingHeap.sweep_list;
- nonmovingHeap.sweep_list = filled;
- }
// N.B. It's not necessary to update snapshot pointers of active segments;
// they were set after they were swept and haven't seen any allocation
@@ -950,6 +933,27 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
debugTrace(DEBUG_nonmoving_gc, "Starting mark...");
stat_startNonmovingGc();
+ // Updated filled segments' snapshot pointers and move to sweep list
+ for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) {
+ struct NonmovingSegment *filled = nonmovingHeap.allocators[alloca_idx]->saved_filled;
+ uint32_t n_filled = 0;
+ if (filled) {
+ struct NonmovingSegment *seg = filled;
+ while (true) {
+ // Set snapshot
+ nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
+ n_filled++;
+ if (seg->link)
+ seg = seg->link;
+ else
+ break;
+ }
+ // add filled segments to sweep_list
+ seg->link = nonmovingHeap.sweep_list;
+ nonmovingHeap.sweep_list = filled;
+ }
+ }
+
// Do concurrent marking; most of the heap will get marked here.
nonmovingMarkThreadsWeaks(mark_queue);
diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h
index 36ecd8b0af..6eabcb8493 100644
--- a/rts/sm/NonMoving.h
+++ b/rts/sm/NonMoving.h
@@ -62,6 +62,7 @@ struct NonmovingSegment {
// A non-moving allocator for a particular block size
struct NonmovingAllocator {
struct NonmovingSegment *filled;
+ struct NonmovingSegment *saved_filled;
struct NonmovingSegment *active;
// indexed by capability number
struct NonmovingSegment *current[];