Commit 226ea0f9 authored by Ben Gamari's avatar Ben Gamari 🐢

NonMoving: Move block size to block descriptor

parent e5258987
...@@ -88,17 +88,22 @@ typedef struct bdescr_ { ...@@ -88,17 +88,22 @@ typedef struct bdescr_ {
StgPtr start; // [READ ONLY] start addr of memory StgPtr start; // [READ ONLY] start addr of memory
StgPtr free; // First free byte of memory. union {
// allocGroup() sets this to the value of start. StgPtr free; // First free byte of memory.
// NB. during use this value should lie // allocGroup() sets this to the value of start.
// between start and start + blocks * // NB. during use this value should lie
// BLOCK_SIZE. Values outside this // between start and start + blocks *
// range are reserved for use by the // BLOCK_SIZE. Values outside this
// block allocator. In particular, the // range are reserved for use by the
// value (StgPtr)(-1) is used to // block allocator. In particular, the
// indicate that a block is unallocated. // value (StgPtr)(-1) is used to
// // indicate that a block is unallocated.
// Unused by the non-moving allocator. //
// Unused by the non-moving allocator.
struct NonmovingSegmentInfo {
StgWord8 log_block_size;
} nonmoving_segment;
};
struct bdescr_ *link; // used for chaining blocks together struct bdescr_ *link; // used for chaining blocks together
......
...@@ -205,13 +205,14 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * ...@@ -205,13 +205,14 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO *
static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block_size) static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block_size)
{ {
bdescr *bd = Bdescr((P_) seg);
seg->link = NULL; seg->link = NULL;
seg->todo_link = NULL; seg->todo_link = NULL;
seg->next_free = 0; seg->next_free = 0;
seg->next_free_snap = 0; seg->next_free_snap = 0;
seg->log_block_size = log_block_size;
nonmovingClearBitmap(seg); 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. // Add a segment to the free list.
......
...@@ -39,12 +39,16 @@ struct NonmovingSegment { ...@@ -39,12 +39,16 @@ struct NonmovingSegment {
struct NonmovingSegment *todo_link; // NULL when not in todo list 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; // index of the next unallocated block
nonmoving_block_idx next_free_snap; // snapshot of next_free 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 uint8_t bitmap[]; // liveness bitmap
// After the liveness bitmap comes the data blocks. Note that we need to // 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 // 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 // of the word size since GHC assumes that all object pointers are
// so-aligned. // 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 // 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); ...@@ -123,8 +127,13 @@ void *nonmovingAllocate(Capability *cap, StgWord sz);
void nonmovingAddCapabilities(uint32_t new_n_caps); void nonmovingAddCapabilities(uint32_t new_n_caps);
void nonmovingPushFreeSegment(struct NonmovingSegment *seg); 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) { 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. // Add a segment to the appropriate active list.
......
...@@ -812,7 +812,7 @@ static MarkQueueEnt markQueuePop (MarkQueue *q) ...@@ -812,7 +812,7 @@ static MarkQueueEnt markQueuePop (MarkQueue *q)
// MarkQueueEnt encoding always places the pointer to the object to be // MarkQueueEnt encoding always places the pointer to the object to be
// marked first. // marked first.
prefetchForRead(&new.mark_closure.p->header.info); 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; q->prefetch_queue[i] = new;
i = (i + 1) % MARK_PREFETCH_QUEUE_DEPTH; i = (i + 1) % MARK_PREFETCH_QUEUE_DEPTH;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment