diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/sm/NonMoving.c | 43 | ||||
-rw-r--r-- | rts/sm/NonMoving.h | 1 |
2 files changed, 26 insertions, 18 deletions
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c index fe9d22b479..bdf22dc37b 100644 --- a/rts/sm/NonMoving.c +++ b/rts/sm/NonMoving.c @@ -727,25 +727,10 @@ 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; + // Save the filled segments for later processing during the concurrent + // mark phase. + 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 @@ -969,6 +954,28 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * debugTrace(DEBUG_nonmoving_gc, "Starting mark..."); stat_startNonmovingGc(); + // Walk the list of filled segments that we collected during preparation, + // updated their snapshot pointers and move them to the 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[]; |