summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-02-26 13:05:16 -0500
committerBen Gamari <ben@smart-cactus.org>2020-02-26 20:15:26 -0500
commite4e9a7ba3abc991d3583371da4681560a7b67bd2 (patch)
treee4dffe97d9cd8bc4fb63679559182651254ab79d
parent1b1067d14b656bbbfa7c47f156ec2700c9751549 (diff)
downloadhaskell-wip/gc/nonmoving-compact-fix.tar.gz
nonmoving: Fix marking in compact regionswip/gc/nonmoving-compact-fix
Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator.
-rw-r--r--rts/sm/NonMovingMark.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index 81000566cb..6d70ca21dd 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -1276,9 +1276,19 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
// Not in the snapshot
return;
}
- if (bd->flags & BF_MARKED) {
- goto done;
+
+ if (! (bd->flags & BF_MARKED)) {
+ dbl_link_remove(bd, &nonmoving_compact_objects);
+ dbl_link_onto(bd, &nonmoving_marked_compact_objects);
+ StgWord blocks = str->totalW / BLOCK_SIZE_W;
+ n_nonmoving_compact_blocks -= blocks;
+ n_nonmoving_marked_compact_blocks += blocks;
+ bd->flags |= BF_MARKED;
}
+
+ // N.B. the object being marked is in a compact region so by
+ // definition there is no need to do any tracing here.
+ goto done;
} else if (bd->flags & BF_LARGE) {
if (! (bd->flags & BF_NONMOVING_SWEEPING)) {
// Not in the snapshot
@@ -1611,15 +1621,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
* the object's pointers since in the case of marking stacks there may be a
* mutator waiting for us to finish so it can start execution.
*/
- if (bd->flags & BF_COMPACT) {
- StgCompactNFData *str = objectGetCompact((StgClosure*)p);
- dbl_link_remove(bd, &nonmoving_compact_objects);
- dbl_link_onto(bd, &nonmoving_marked_compact_objects);
- StgWord blocks = str->totalW / BLOCK_SIZE_W;
- n_nonmoving_compact_blocks -= blocks;
- n_nonmoving_marked_compact_blocks += blocks;
- bd->flags |= BF_MARKED;
- } else if (bd->flags & BF_LARGE) {
+ if (bd->flags & BF_LARGE) {
/* Marking a large object isn't idempotent since we move it to
* nonmoving_marked_large_objects; to ensure that we don't repeatedly
* mark a large object, we only set BF_MARKED on large objects in the