Skip to content

Commit

Permalink
[GC] Inline worklist management when marking dense objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
deadalnix committed Oct 21, 2024
1 parent b43c60c commit 0869ec1
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions sdlib/d/gc/scanner.d
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,29 @@ public:
auto pd = lastDenseSlabPageDescriptor;
auto slotSize = lastDenseBin.slotSize;

if (!markDense(base, index, pd)) {
if (!markDense(pd, index)) {
continue;
}

if (pd.containsPointers) {
auto item = WorkItem(base + index * slotSize, slotSize);
addToWorkList(item);
if (!pd.containsPointers) {
continue;
}

auto i = WorkItem(base + index * slotSize, slotSize);
if (likely(cursor < WorkListCapacity)) {
worklist[cursor++] = i;
continue;
}

/**
* We want to make sure that no matter what, this worker processes
* the WorkItem it is provided directly. Everything else in the
* worklist can be sent to other threads.
*/
scanner.addToWorkList(worklist[0 .. WorkListCapacity]);

cursor = 1;
worklist[0] = i;
continue;
}

Expand Down Expand Up @@ -353,7 +367,7 @@ public:
}

private:
bool markDense(const void* base, uint index, PageDescriptor pd) {
static bool markDense(PageDescriptor pd, uint index) {
auto e = pd.extent;

/**
Expand Down Expand Up @@ -382,19 +396,6 @@ private:
return true;
}

void addToWorkList(WorkItem item) {
if (likely(cursor < WorkListCapacity)) {
worklist[cursor++] = item;
return;
}

// Flush the current worklist and add the item.
scanner.addToWorkList(worklist[0 .. WorkListCapacity]);

cursor = 1;
worklist[0] = item;
}

void markSparse(PageDescriptor pd, const void* ptr, ubyte cycle) {
import d.gc.slab;
auto se = SlabEntry(pd, ptr);
Expand Down Expand Up @@ -499,6 +500,7 @@ public:

this(const void* ptr, size_t length) {
assert(isAligned(ptr, PointerSize), "Invalid ptr!");
assert(length >= PointerSize, "WorkItem cannot be empty!");

auto storedLength = length / PointerSize - 1;
assert(storedLength < (1 << FreeBits), "Invalid length!");
Expand All @@ -509,6 +511,7 @@ public:

this(const(void*)[] range) {
assert(range.length > 0, "WorkItem cannot be empty!");
assert(range.length <= (1 << FreeBits), "Invalid length!");

payload = cast(size_t) range.ptr;
payload |= (range.length - 1) << LengthShift;
Expand Down

0 comments on commit 0869ec1

Please sign in to comment.