summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-05-17 13:38:36 -0400
committerBen Gamari <ben@smart-cactus.org>2019-10-22 12:20:37 -0400
commitdd8d1b4928a9f82d2abfe0926c9ef3b5a20758b5 (patch)
treed649be6c5a49919f4103e557dedaf5eaa015a705
parent6dcef5eedaee9a9ecd8b0e41c5f5b93512e6f6c9 (diff)
downloadhaskell-dd8d1b4928a9f82d2abfe0926c9ef3b5a20758b5.tar.gz
NonMoving: Move next_free_snap to block descriptorwip/gc/segment-header-to-bdescr
-rw-r--r--includes/rts/storage/Block.h1
-rw-r--r--rts/sm/NonMoving.c8
-rw-r--r--rts/sm/NonMoving.h11
-rw-r--r--rts/sm/NonMovingMark.c4
-rw-r--r--rts/sm/NonMovingSweep.c4
-rw-r--r--rts/sm/Sanity.c2
6 files changed, 18 insertions, 12 deletions
diff --git a/includes/rts/storage/Block.h b/includes/rts/storage/Block.h
index 3887ac2980..4afc3689cb 100644
--- a/includes/rts/storage/Block.h
+++ b/includes/rts/storage/Block.h
@@ -102,6 +102,7 @@ typedef struct bdescr_ {
// Unused by the non-moving allocator.
struct NonmovingSegmentInfo {
StgWord8 log_block_size;
+ StgWord16 next_free_snap;
} nonmoving_segment;
};
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c
index 5a6b9e7837..95a6fb1273 100644
--- a/rts/sm/NonMoving.c
+++ b/rts/sm/NonMoving.c
@@ -208,9 +208,9 @@ static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block
seg->link = NULL;
seg->todo_link = NULL;
seg->next_free = 0;
- seg->next_free_snap = 0;
nonmovingClearBitmap(seg);
bd->nonmoving_segment.log_block_size = log_block_size;
+ bd->nonmoving_segment.next_free_snap = 0;
bd->u.scan = nonmovingSegmentGetBlock(seg, 0);
}
@@ -386,7 +386,7 @@ void *nonmovingAllocate(Capability *cap, StgWord sz)
// Update live data estimate.
// See Note [Live data accounting in nonmoving collector].
- unsigned int new_blocks = block_count - current->next_free_snap;
+ unsigned int new_blocks = block_count - nonmovingSegmentInfo(current)->next_free_snap;
unsigned int block_size = 1 << log_block_size;
atomic_inc(&oldest_gen->live_estimate, new_blocks * block_size / sizeof(W_));
@@ -530,7 +530,7 @@ static void nonmovingPrepareMark(void)
// Update current segments' snapshot pointers
for (uint32_t cap_n = 0; cap_n < n_capabilities; ++cap_n) {
struct NonmovingSegment *seg = alloca->current[cap_n];
- seg->next_free_snap = seg->next_free;
+ nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
}
// Update filled segments' snapshot pointers and move to sweep_list
@@ -546,7 +546,7 @@ static void nonmovingPrepareMark(void)
prefetchForWrite(seg->link->bitmap);
nonmovingClearBitmap(seg);
// Set snapshot
- seg->next_free_snap = seg->next_free;
+ nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free;
if (seg->link)
seg = seg->link;
else
diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h
index e6569a853e..2a553f0a0d 100644
--- a/rts/sm/NonMoving.h
+++ b/rts/sm/NonMoving.h
@@ -38,7 +38,6 @@ struct NonmovingSegment {
struct NonmovingSegment *link; // for linking together segments into lists
struct NonmovingSegment *todo_link; // NULL when not in todo list
nonmoving_block_idx next_free; // index of the next unallocated block
- nonmoving_block_idx next_free_snap; // snapshot of next_free
uint8_t bitmap[]; // liveness bitmap
// After the liveness bitmap comes the data blocks. Note that we need to
// ensure that the size of this struct (including the bitmap) is a multiple
@@ -49,6 +48,11 @@ struct NonmovingSegment {
// NonmovingBlockInfo stored in the segment's block descriptor. Namely:
//
// * the block size can be found in nonmovingBlockInfo(seg)->log_block_size.
+ // * the next_free snapshot can be found in
+ // nonmovingBlockInfo(seg)->next_free_snap.
+ //
+ // This allows us to mark a nonmoving closure without bringing the
+ // NonmovingSegment header into cache.
};
// This is how we mark end of todo lists. Not NULL because todo_link == NULL
@@ -281,8 +285,9 @@ INLINE_HEADER bool nonmovingClosureMarked(StgPtr p)
// segment is in the set of segments that will be swept this collection cycle.
INLINE_HEADER bool nonmovingSegmentBeingSwept(struct NonmovingSegment *seg)
{
- unsigned int n = nonmovingSegmentBlockCount(seg);
- return seg->next_free_snap >= n;
+ struct NonmovingSegmentInfo *seginfo = nonmovingSegmentInfo(seg);
+ unsigned int n = nonmovingBlockCountFromSize(seginfo->log_block_size);
+ return seginfo->next_free_snap >= n;
}
// Can be called during a major collection to determine whether a particular
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index 6e34096037..0c91befcd6 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -1251,7 +1251,7 @@ mark_closure (MarkQueue *queue, StgClosure *p, StgClosure **origin)
return;
StgClosure *snapshot_loc =
- (StgClosure *) nonmovingSegmentGetBlock(seg, seg->next_free_snap);
+ (StgClosure *) nonmovingSegmentGetBlock(seg, nonmovingSegmentInfo(seg)->next_free_snap);
if (p >= snapshot_loc && mark == 0) {
/*
* In this case we are looking at a block that wasn't allocated
@@ -1656,7 +1656,7 @@ bool nonmovingIsAlive (StgClosure *p)
struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p);
nonmoving_block_idx i = nonmovingGetBlockIdx((StgPtr) p);
uint8_t mark = nonmovingGetMark(seg, i);
- if (i >= seg->next_free_snap) {
+ if (i >= nonmovingSegmentInfo(seg)->next_free_snap) {
// If the object is allocated after next_free_snap then one of the
// following must be true:
//
diff --git a/rts/sm/NonMovingSweep.c b/rts/sm/NonMovingSweep.c
index 7af5508afc..3ee27ef3b4 100644
--- a/rts/sm/NonMovingSweep.c
+++ b/rts/sm/NonMovingSweep.c
@@ -41,7 +41,7 @@ nonmovingSweepSegment(struct NonmovingSegment *seg)
} else if (!found_free) {
found_free = true;
seg->next_free = i;
- seg->next_free_snap = i;
+ nonmovingSegmentInfo(seg)->next_free_snap = i;
Bdescr((P_)seg)->u.scan = (P_)nonmovingSegmentGetBlock(seg, i);
seg->bitmap[i] = 0;
} else {
@@ -63,7 +63,7 @@ nonmovingSweepSegment(struct NonmovingSegment *seg)
return SEGMENT_FILLED;
} else {
ASSERT(seg->next_free == 0);
- ASSERT(seg->next_free_snap == 0);
+ ASSERT(nonmovingSegmentInfo(seg)->next_free_snap == 0);
return SEGMENT_FREE;
}
}
diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c
index 0159488856..99671e9c61 100644
--- a/rts/sm/Sanity.c
+++ b/rts/sm/Sanity.c
@@ -497,7 +497,7 @@ static void checkNonmovingSegments (struct NonmovingSegment *seg)
if (seg->bitmap[i] == nonmovingMarkEpoch) {
StgPtr p = nonmovingSegmentGetBlock(seg, i);
checkClosure((StgClosure *) p);
- } else if (i < seg->next_free_snap){
+ } else if (i < nonmovingSegmentInfo(seg)->next_free_snap){
seg->bitmap[i] = 0;
}
}