diff options
-rw-r--r-- | includes/rts/storage/Block.h | 27 | ||||
-rw-r--r-- | rts/sm/NonMoving.c | 5 | ||||
-rw-r--r-- | rts/sm/NonMoving.h | 13 | ||||
-rw-r--r-- | rts/sm/NonMovingMark.c | 2 |
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; } |