summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/rts/storage/Block.h27
-rw-r--r--rts/sm/NonMoving.c5
-rw-r--r--rts/sm/NonMoving.h13
-rw-r--r--rts/sm/NonMovingMark.c2
4 files changed, 31 insertions, 16 deletions
diff --git a/includes/rts/storage/Block.h b/includes/rts/storage/Block.h
index 32cf98958f..3887ac2980 100644
--- a/includes/rts/storage/Block.h
+++ b/includes/rts/storage/Block.h
@@ -88,17 +88,22 @@ typedef struct bdescr_ {
StgPtr start; // [READ ONLY] start addr of memory
- StgPtr free; // First free byte of memory.
- // allocGroup() sets this to the value of start.
- // NB. during use this value should lie
- // between start and start + blocks *
- // BLOCK_SIZE. Values outside this
- // range are reserved for use by the
- // block allocator. In particular, the
- // value (StgPtr)(-1) is used to
- // indicate that a block is unallocated.
- //
- // Unused by the non-moving allocator.
+ union {
+ StgPtr free; // First free byte of memory.
+ // allocGroup() sets this to the value of start.
+ // NB. during use this value should lie
+ // between start and start + blocks *
+ // BLOCK_SIZE. Values outside this
+ // range are reserved for use by the
+ // block allocator. In particular, the
+ // value (StgPtr)(-1) is used to
+ // indicate that a block is unallocated.
+ //
+ // Unused by the non-moving allocator.
+ struct NonmovingSegmentInfo {
+ StgWord8 log_block_size;
+ } nonmoving_segment;
+ };
struct bdescr_ *link; // used for chaining blocks together
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c
index e11a029b5a..5a6b9e7837 100644
--- a/rts/sm/NonMoving.c
+++ b/rts/sm/NonMoving.c
@@ -204,13 +204,14 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block_size)
{
+ bdescr *bd = Bdescr((P_) seg);
seg->link = NULL;
seg->todo_link = NULL;
seg->next_free = 0;
seg->next_free_snap = 0;
- seg->log_block_size = log_block_size;
nonmovingClearBitmap(seg);
- Bdescr((P_)seg)->u.scan = nonmovingSegmentGetBlock(seg, 0);
+ bd->nonmoving_segment.log_block_size = log_block_size;
+ bd->u.scan = nonmovingSegmentGetBlock(seg, 0);
}
// Add a segment to the free list.
diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h
index 2a5de5d4b9..e6569a853e 100644
--- a/rts/sm/NonMoving.h
+++ b/rts/sm/NonMoving.h
@@ -39,12 +39,16 @@ struct NonmovingSegment {
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 log_block_size; // log2 of block size in bytes
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
// of the word size since GHC assumes that all object pointers are
// so-aligned.
+
+ // N.B. There are also bits of information which are stored in the
+ // NonmovingBlockInfo stored in the segment's block descriptor. Namely:
+ //
+ // * the block size can be found in nonmovingBlockInfo(seg)->log_block_size.
};
// This is how we mark end of todo lists. Not NULL because todo_link == NULL
@@ -123,8 +127,13 @@ void *nonmovingAllocate(Capability *cap, StgWord sz);
void nonmovingAddCapabilities(uint32_t new_n_caps);
void nonmovingPushFreeSegment(struct NonmovingSegment *seg);
+
+INLINE_HEADER struct NonmovingSegmentInfo *nonmovingSegmentInfo(struct NonmovingSegment *seg) {
+ return &Bdescr((StgPtr) seg)->nonmoving_segment;
+}
+
INLINE_HEADER uint8_t nonmovingSegmentLogBlockSize(struct NonmovingSegment *seg) {
- return seg->log_block_size;
+ return nonmovingSegmentInfo(seg)->log_block_size;
}
// Add a segment to the appropriate active list.
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index 578d811fcb..6e34096037 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -809,7 +809,7 @@ static MarkQueueEnt markQueuePop (MarkQueue *q)
// MarkQueueEnt encoding always places the pointer to the object to be
// marked first.
prefetchForRead(&new.mark_closure.p->header.info);
- prefetchForRead(&nonmovingGetSegment_unchecked((StgPtr) new.mark_closure.p)->log_block_size);
+ prefetchForRead(Bdescr((StgPtr) new.mark_closure.p));
q->prefetch_queue[i] = new;
i = (i + 1) % MARK_PREFETCH_QUEUE_DEPTH;
}