diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-03-03 23:42:14 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-03-03 23:42:14 -0500 |
commit | 56d4e0056ba55f0b3d4d4fb55e7425472e917d8b (patch) | |
tree | 369f651cb3bd5a388f6b579d0667cc72acc7b6e4 | |
parent | 924af4dbf42eab8800ddfb02c5398ccf4b5f9c71 (diff) | |
download | haskell-56d4e0056ba55f0b3d4d4fb55e7425472e917d8b.tar.gz |
Don't traverse filled segment list in pause
-rw-r--r-- | rts/sm/NonMoving.c | 40 | ||||
-rw-r--r-- | rts/sm/NonMoving.h | 1 |
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[]; |