Skip to content

Commit

Permalink
Mark and scan huge allocation during collection process.
Browse files Browse the repository at this point in the history
  • Loading branch information
deadalnix committed Sep 28, 2015
1 parent 755dd9c commit c8a39f6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
60 changes: 50 additions & 10 deletions libsdrt/src/d/gc/arena.d
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct Arena {
// Extent describing huge allocs.
import d.gc.extent;
ExtentTree hugeTree;
LookupExtentTree hugeLookupTree;
ExtentTree hugeLookupTree;

// Set of chunks for GC lookup.
ChunkSet chunkSet;
Expand Down Expand Up @@ -109,7 +109,12 @@ struct Arena {
assert(c.header.arena is &this);
oldBinID = c.pages[c.getRunID(ptr)].binID;
} else {
oldBinID = getBinID(findHugeExtent(ptr).size);
auto e = extractHugeExtent(ptr);
assert(e !is null);

// We need to keep it alive for now.
hugeTree.insert(e);
oldBinID = getBinID(e.size);
}

if (newBinID == oldBinID) {
Expand Down Expand Up @@ -435,7 +440,7 @@ private:
return ret;
}

Extent* findHugeExtent(void* ptr) {
Extent* extractHugeExtent(void* ptr) {
// XXX: in contracts
import d.gc.spec;
assert(((cast(size_t) ptr) & AlignMask) == 0);
Expand All @@ -445,8 +450,20 @@ private:

// XXX: extract
auto e = hugeTree.find(&test);
assert(e !is null);
assert(e.arena is &this);
if (e !is null) {
hugeTree.remove(e);
} else {
e = hugeLookupTree.find(&test);
if (e !is null) {
hugeLookupTree.remove(e);
}
}

// FIXME: out contract.
if (e !is null) {
assert(e.addr is ptr);
assert(e.arena is &this);
}

return e;
}
Expand All @@ -458,12 +475,12 @@ private:
}

// XXX: extract
auto e = findHugeExtent(ptr);
auto e = extractHugeExtent(ptr);
assert(e !is null);

import d.gc.mman;
pages_unmap(e.addr, e.size);

hugeTree.remove(e);
free(e);
}

Expand Down Expand Up @@ -526,6 +543,12 @@ private:
}

void collect() {
// Get ready to detect huge allocations.
hugeLookupTree = hugeTree;

// FIXME: This bypass visibility.
hugeTree.root = null;

// TODO: The set need a range interface or some other way to iterrate.
auto chunks = chunkSet.cloneChunks();

Expand All @@ -537,6 +560,8 @@ private:
c.prepare();
}

// FIXME: mark datastructures as live.

// Scan the roots !
__sdgc_push_registers(scanStack);
foreach(range; roots) {
Expand Down Expand Up @@ -582,13 +607,28 @@ private:

import d.gc.spec;
auto c = findChunk(ptr);
if (c is null) {
if (c !is null && chunkSet.test(c)) {
newPtr = c.mark(ptr) || newPtr;
continue;
}

if (chunkSet.test(c)) {
newPtr = c.mark(ptr) || newPtr;
// XXX: extract.
Extent ecmp;
ecmp.addr = cast(void*) ptr;
auto e = hugeLookupTree.find(&ecmp);
if (e is null) {
continue;
}

hugeLookupTree.remove(e);
hugeTree.insert(e);

auto hugeRange = makeRange(e.addr[0 .. e.size]);

// FIXME: Ideally, a worklist is preferable as
// 1/ We could recurse a lot this way.
// 2/ We want to keep working on the same chunk for locality.
scan(hugeRange);
}

return newPtr;
Expand Down
15 changes: 10 additions & 5 deletions libsdrt/src/d/gc/extent.d
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
module d.gc.extent;

import d.gc.rbtree;
alias ExtentTree = RBTree!(Extent, addrExtentCmp);
alias LookupExtentTree = RBTree!(Extent, addrExtentCmp, "lookupNode");
alias ExtentTree = RBTree!(Extent, addrRangeExtentCmp);

struct Extent {
import d.gc.arena;
Expand All @@ -11,9 +10,6 @@ struct Extent {
import d.gc.rbtree;
ExtentTree.Node node;

// Used for GC lookup of huge allocs.
LookupExtentTree.Node lookupNode;

void* addr;
size_t size;
}
Expand All @@ -25,3 +21,12 @@ ptrdiff_t addrExtentCmp(Extent* lhs, Extent* rhs) {
// We need to compare that way to avoid integer overflow.
return (l > r) - (l < r);
}

ptrdiff_t addrRangeExtentCmp(Extent* lhs, Extent* rhs) {
auto l = cast(size_t) lhs.addr;
auto rstart = cast(size_t) rhs.addr;
auto rend = rstart + rhs.size;

// We need to compare that way to avoid integer overflow.
return (l >= rend) - (l < rstart);
}
2 changes: 1 addition & 1 deletion tests/test0176.d
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,6 @@ void main() {

r1 = _tl_gc_realloc(r0, 35 * 1024 * 1024);
assert(r1 is r0);

_tl_gc_collect();
}

0 comments on commit c8a39f6

Please sign in to comment.