summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
Diffstat (limited to 'rts')
-rw-r--r--rts/sm/NonMoving.c13
-rw-r--r--rts/sm/NonMoving.h2
-rw-r--r--rts/sm/NonMovingMark.c9
-rw-r--r--rts/sm/NonMovingMark.h5
-rw-r--r--rts/sm/Storage.c14
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;
}