Skip to content

Commit efddd81

Browse files
committed
[GC] Batch free extents when purging.
1 parent 476502d commit efddd81

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

sdlib/d/gc/arena.d

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,9 @@ public:
144144
assert(worklist.length > 0, "Worklist is empty!");
145145
assert(pds[0].arenaIndex == index, "Erroneous arena index!");
146146

147-
auto dallocSlabs = cast(Extent**) alloca(worklist.length * PointerSize);
148-
149147
uint ndalloc = 0;
150-
scope(success) if (ndalloc > 0) {
151-
foreach (i; 0 .. ndalloc) {
152-
// FIXME: batch free to go through the lock once using freeExtentLocked.
153-
filler.freeExtent(emap, dallocSlabs[i]);
154-
}
155-
}
148+
auto dallocSlabs = cast(Extent**) alloca(worklist.length * PointerSize);
149+
scope(success) filler.batchFreeExtents(emap, dallocSlabs[0 .. ndalloc]);
156150

157151
auto ec = pds[0].extentClass;
158152
auto sc = ec.sizeClass;

sdlib/d/gc/page.d

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,33 @@ public:
242242
}
243243

244244
void freeExtent(ref CachedExtentMap emap, Extent* e) shared {
245-
emap.clear(e);
246-
freePages(e);
245+
assert(e.arenaIndex == arena.index, "Invalid arena!");
246+
batchFreeExtents(emap, (&e)[0 .. 1]);
247+
}
248+
249+
void batchFreeExtents(ref CachedExtentMap emap, Extent*[] extents) shared {
250+
// FIXME: in contract.
251+
foreach (e; extents) {
252+
assert(e.arenaIndex == arena.index, "Invalid arena!");
253+
}
254+
255+
// Avoid locking if there is nothing to do.
256+
if (extents.length == 0) {
257+
return;
258+
}
259+
260+
// Clear the emap.
261+
foreach (e; extents) {
262+
emap.clear(e);
263+
}
264+
265+
// Free the pages.
266+
mutex.lock();
267+
scope(exit) mutex.unlock();
268+
269+
foreach (e; extents) {
270+
(cast(PageFiller*) &this).freePagesImpl(e);
271+
}
247272
}
248273

249274
void freePages(Extent* e) shared {
@@ -342,6 +367,16 @@ private:
342367
return e.at(ptr, npages, block);
343368
}
344369

370+
void freePagesImpl(Extent* e) {
371+
assert(mutex.isHeld(), "Mutex not held!");
372+
assert(isAligned(e.address, PageSize), "Invalid extent address!");
373+
374+
uint n = e.blockIndex;
375+
uint pages = modUp(e.npages, PagesInBlock);
376+
377+
freePagesImpl(e, n, pages);
378+
}
379+
345380
void freePagesImpl(Extent* e, uint n, uint pages) {
346381
assert(mutex.isHeld(), "Mutex not held!");
347382
assert(pages > 0 && pages <= PagesInBlock, "Invalid number of pages!");
@@ -1030,11 +1065,7 @@ private:
10301065
assert(isAligned(e.address, PageSize), "Invalid extent address!");
10311066

10321067
emap.clear(e);
1033-
1034-
uint n = e.blockIndex;
1035-
uint pages = modUp(e.npages, PagesInBlock);
1036-
1037-
(cast(PageFiller*) &this).freePagesImpl(e, n, pages);
1068+
freePagesImpl(e);
10381069
}
10391070
}
10401071

0 commit comments

Comments
 (0)