diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/sm/NonMoving.c | 13 | ||||
-rw-r--r-- | rts/sm/NonMoving.h | 2 | ||||
-rw-r--r-- | rts/sm/NonMovingMark.c | 9 | ||||
-rw-r--r-- | rts/sm/NonMovingMark.h | 5 | ||||
-rw-r--r-- | rts/sm/Storage.c | 14 |
5 files changed, 36 insertions, 7 deletions
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c index e7ce4ea1d3..66cc512c12 100644 --- a/rts/sm/NonMoving.c +++ b/rts/sm/NonMoving.c @@ -395,7 +395,8 @@ Mutex concurrent_coll_finished_lock; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The nonmoving collector uses an approximate heuristic for reporting live * data quantity. Specifically, during mark we record how much live data we - * find in nonmoving_live_words. At the end of mark we declare this amount to + * find in nonmoving_segment_live_words. At the end of mark this is combined with nonmoving_large_words + * and nonmoving_compact_words, and we declare this amount to * be how much live data we have on in the nonmoving heap (by setting * oldest_gen->live_estimate). * @@ -540,7 +541,7 @@ Mutex concurrent_coll_finished_lock; * */ -memcount nonmoving_live_words = 0; +memcount nonmoving_segment_live_words = 0; // See Note [Sync phase marking budget]. MarkBudget sync_phase_marking_budget = 200000; @@ -682,10 +683,11 @@ static void nonmovingPrepareMark(void) dbl_link_onto(bd, &nonmoving_large_objects); } n_nonmoving_large_blocks += oldest_gen->n_large_blocks; + nonmoving_large_words += oldest_gen->n_large_words; oldest_gen->large_objects = NULL; oldest_gen->n_large_words = 0; oldest_gen->n_large_blocks = 0; - nonmoving_live_words = 0; + nonmoving_segment_live_words = 0; // Clear compact object mark bits for (bdescr *bd = nonmoving_compact_objects; bd; bd = bd->link) { @@ -700,6 +702,7 @@ static void nonmovingPrepareMark(void) dbl_link_onto(bd, &nonmoving_compact_objects); } n_nonmoving_compact_blocks += oldest_gen->n_compact_blocks; + nonmoving_compact_words += oldest_gen->n_compact_blocks * BLOCK_SIZE_W; oldest_gen->n_compact_blocks = 0; oldest_gen->compact_objects = NULL; // TODO (osa): what about "in import" stuff?? @@ -1053,7 +1056,9 @@ concurrent_marking: freeMarkQueue(mark_queue); stgFree(mark_queue); - oldest_gen->live_estimate = nonmoving_live_words; + nonmoving_large_words = countOccupied(nonmoving_marked_large_objects); + nonmoving_compact_words = n_nonmoving_marked_compact_blocks * BLOCK_SIZE_W; + oldest_gen->live_estimate = nonmoving_segment_live_words + nonmoving_large_words + nonmoving_compact_words; oldest_gen->n_old_blocks = 0; resizeGenerations(); diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h index 3ee6225b3e..870e5fa9e4 100644 --- a/rts/sm/NonMoving.h +++ b/rts/sm/NonMoving.h @@ -122,7 +122,7 @@ struct NonmovingHeap { extern struct NonmovingHeap nonmovingHeap; -extern memcount nonmoving_live_words; +extern memcount nonmoving_segment_live_words; #if defined(THREADED_RTS) extern bool concurrent_coll_running; diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index fffabdd97f..b0931f5767 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -76,6 +76,10 @@ static bool is_nonmoving_weak(StgWeak *weak); * consequently will trace the pointers of only one object per block. However, * this is okay since the only type of pinned object supported by GHC is the * pinned ByteArray#, which has no pointers. + * + * We need to take care that the stats department is made aware of the amount of + * live large (and compact) objects, since they no longer live on gen[i]->large_objects. + * Failing to do so caused #17574. */ bdescr *nonmoving_large_objects = NULL; @@ -83,6 +87,9 @@ bdescr *nonmoving_marked_large_objects = NULL; memcount n_nonmoving_large_blocks = 0; memcount n_nonmoving_marked_large_blocks = 0; +memcount nonmoving_large_words = 0; +memcount nonmoving_compact_words = 0; + bdescr *nonmoving_compact_objects = NULL; bdescr *nonmoving_marked_compact_objects = NULL; memcount n_nonmoving_compact_blocks = 0; @@ -1745,7 +1752,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p); nonmoving_block_idx block_idx = nonmovingGetBlockIdx((StgPtr) p); nonmovingSetMark(seg, block_idx); - nonmoving_live_words += nonmovingSegmentBlockSize(seg) / sizeof(W_); + nonmoving_segment_live_words += nonmovingSegmentBlockSize(seg) / sizeof(W_); } // If we found a indirection to shortcut keep going. diff --git a/rts/sm/NonMovingMark.h b/rts/sm/NonMovingMark.h index 763192ff4b..27fb9e2452 100644 --- a/rts/sm/NonMovingMark.h +++ b/rts/sm/NonMovingMark.h @@ -127,6 +127,11 @@ extern bdescr *nonmoving_large_objects, *nonmoving_marked_large_objects, extern memcount n_nonmoving_large_blocks, n_nonmoving_marked_large_blocks, n_nonmoving_compact_blocks, n_nonmoving_marked_compact_blocks; +// The size of live large/compact objects in words. +// Only updated at the end of nonmoving GC. +extern memcount nonmoving_large_words, + nonmoving_compact_words; + extern StgTSO *nonmoving_old_threads; extern StgWeak *nonmoving_old_weak_ptr_list; extern StgTSO *nonmoving_threads; diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 8bb3fc79d8..6d6500df9a 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -42,6 +42,7 @@ #include "GC.h" #include "Evac.h" #include "NonMovingAllocate.h" +#include "sm/NonMovingMark.h" #if defined(ios_HOST_OS) || defined(darwin_HOST_OS) #include "Hash.h" #endif @@ -1615,7 +1616,12 @@ W_ genLiveWords (generation *gen) W_ genLiveBlocks (generation *gen) { - return gen->n_blocks + gen->n_large_blocks + gen->n_compact_blocks; + W_ nonmoving_blocks = 0; + // The nonmoving heap contains some blocks that live outside the regular generation structure. + if (gen == oldest_gen && RtsFlags.GcFlags.useNonmoving){ + nonmoving_blocks = n_nonmoving_large_blocks + n_nonmoving_marked_large_blocks + n_nonmoving_compact_blocks + n_nonmoving_marked_compact_blocks; + } + return gen->n_blocks + gen->n_large_blocks + gen->n_compact_blocks + nonmoving_blocks; } W_ gcThreadLiveWords (uint32_t i, uint32_t g) @@ -1711,6 +1717,9 @@ StgWord calcTotalLargeObjectsW (void) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { totalW += generations[g].n_large_words; } + + totalW += nonmoving_large_words; + return totalW; } @@ -1722,6 +1731,9 @@ StgWord calcTotalCompactW (void) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { totalW += generations[g].n_compact_blocks * BLOCK_SIZE_W; } + + totalW += nonmoving_compact_words; + return totalW; } |