diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-07-22 18:57:34 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-07-25 23:32:06 -0400 |
commit | 4b08797380a0a0a789844c17c6ed1570b62dc119 (patch) | |
tree | cce93561638adc91582a327329198bc26ca6e4b0 | |
parent | 82a0991a73130f2cb70bd8ccaaff30cffd1dd2b0 (diff) | |
download | haskell-4b08797380a0a0a789844c17c6ed1570b62dc119.tar.gz |
rts/nonmoving: Track segment state
It can often be useful during debugging to be able to determine the
state of a nonmoving segment. Introduce some state, enabled by DEBUG, to
track this.
(cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f)
-rw-r--r-- | rts/sm/NonMoving.c | 5 | ||||
-rw-r--r-- | rts/sm/NonMoving.h | 24 |
2 files changed, 28 insertions, 1 deletions
diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c index a918f422cf..ad140ff495 100644 --- a/rts/sm/NonMoving.c +++ b/rts/sm/NonMoving.c @@ -504,6 +504,7 @@ static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block seg->link = NULL; seg->todo_link = NULL; seg->next_free = 0; + SET_SEGMENT_STATE(seg, FREE); bd->nonmoving_segment.log_block_size = log_block_size; bd->nonmoving_segment.next_free_snap = 0; bd->u.scan = nonmovingSegmentGetBlock(seg, 0); @@ -526,6 +527,7 @@ void nonmovingPushFreeSegment(struct NonmovingSegment *seg) return; } + SET_SEGMENT_STATE(seg, FREE); while (true) { struct NonmovingSegment *old = nonmovingHeap.free; seg->link = old; @@ -694,6 +696,7 @@ void *nonmovingAllocate(Capability *cap, StgWord sz) // make it current new_current->link = NULL; + SET_SEGMENT_STATE(new_current, CURRENT); alloca->current[cap->no] = new_current; } @@ -790,6 +793,7 @@ void nonmovingAddCapabilities(uint32_t new_n_caps) for (unsigned int j = old_n_caps; j < new_n_caps; j++) { allocs[i]->current[j] = nonmovingAllocSegment(capabilities[j]->node); nonmovingInitSegment(allocs[i]->current[j], NONMOVING_ALLOCA0 + i); + SET_SEGMENT_STATE(allocs[i]->current[j], CURRENT); allocs[i]->current[j]->link = NULL; } } @@ -1067,6 +1071,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * break; } // add filled segments to sweep_list + SET_SEGMENT_STATE(seg, FILLED_SWEEPING); seg->link = nonmovingHeap.sweep_list; nonmovingHeap.sweep_list = filled; } diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h index 17c0a3bec0..0886215de8 100644 --- a/rts/sm/NonMoving.h +++ b/rts/sm/NonMoving.h @@ -33,11 +33,31 @@ _Static_assert(NONMOVING_SEGMENT_SIZE % BLOCK_SIZE == 0, // The index of a block within a segment typedef uint16_t nonmoving_block_idx; +#if defined(DEBUG) +#define TRACK_SEGMENT_STATE +#endif + +#if defined(TRACK_SEGMENT_STATE) +// The collector itself doesn't require each segment to know its state (this is +// implied by what segment list it is on) however it can be very useful while +// debugging to know this. +enum NonmovingSegmentState { + FREE, CURRENT, ACTIVE, FILLED, FILLED_SWEEPING +}; + +#define SET_SEGMENT_STATE(seg, st) (seg)->state = (st) +#else +#define SET_SEGMENT_STATE(_seg,_st) +#endif + // A non-moving heap segment struct NonmovingSegment { - struct NonmovingSegment *link; // for linking together segments into lists + 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 +#if defined(TRACK_SEGMENT_STATE) + enum NonmovingSegmentState state; +#endif 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 @@ -148,6 +168,7 @@ INLINE_HEADER void nonmovingPushActiveSegment(struct NonmovingSegment *seg) { struct NonmovingAllocator *alloc = nonmovingHeap.allocators[nonmovingSegmentLogBlockSize(seg) - NONMOVING_ALLOCA0]; + SET_SEGMENT_STATE(seg, ACTIVE); while (true) { struct NonmovingSegment *current_active = (struct NonmovingSegment*)VOLATILE_LOAD(&alloc->active); seg->link = current_active; @@ -162,6 +183,7 @@ INLINE_HEADER void nonmovingPushFilledSegment(struct NonmovingSegment *seg) { struct NonmovingAllocator *alloc = nonmovingHeap.allocators[nonmovingSegmentLogBlockSize(seg) - NONMOVING_ALLOCA0]; + SET_SEGMENT_STATE(seg, FILLED); while (true) { struct NonmovingSegment *current_filled = (struct NonmovingSegment*)VOLATILE_LOAD(&alloc->filled); seg->link = current_filled; |