Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
add test for precise GC
Browse files Browse the repository at this point in the history
  • Loading branch information
rainers committed Jan 3, 2019
1 parent aa3a5d9 commit a0fb48d
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/gc/impl/conservative/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -3857,6 +3857,7 @@ unittest

// improve predictability of coverage of code that is eventually not hit by other tests
debug (SENTINEL) {} else // cannot extend with SENTINEL
debug (MARK_PRINTF) {} else // takes forever
unittest
{
import core.memory;
Expand Down Expand Up @@ -3909,6 +3910,8 @@ version (D_LP64) unittest
if (os_physical_mem() > sz)
{
import core.memory;
GC.collect();
GC.minimize();
auto stats = GC.stats();
auto ptr = GC.malloc(sz, BlkAttr.NO_SCAN);
auto info = GC.query(ptr);
Expand Down
17 changes: 10 additions & 7 deletions test/gc/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
include ../common.mak

TESTS := sentinel printf memstomp invariant logging
TESTS := sentinel printf memstomp invariant logging precise

SRC_GC = ../../src/gc/impl/conservative/gc.d
SRC = $(SRC_GC) ../../src/rt/lifetime.d
# ../../src/object.d causes duplicate symbols
UDFLAGS = $(DFLAGS) -unittest -main
UDFLAGS = $(DFLAGS) -unittest

.PHONY: all clean
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
Expand All @@ -16,19 +16,22 @@ $(ROOT)/%.done: $(ROOT)/%
@touch $@

$(ROOT)/sentinel: $(SRC)
$(DMD) -debug=SENTINEL $(UDFLAGS) -of$@ $(SRC)
$(DMD) -debug=SENTINEL $(UDFLAGS) -main -of$@ $(SRC)

$(ROOT)/printf: $(SRC)
$(DMD) -debug=PRINTF -debug=PRINTF_TO_FILE -debug=COLLECT_PRINTF $(UDFLAGS) -of$@ $(SRC_GC)
$(DMD) -debug=PRINTF -debug=PRINTF_TO_FILE -debug=COLLECT_PRINTF $(UDFLAGS) -main -of$@ $(SRC_GC)

$(ROOT)/memstomp: $(SRC)
$(DMD) -debug=MEMSTOMP $(UDFLAGS) -of$@ $(SRC)
$(DMD) -debug=MEMSTOMP $(UDFLAGS) -main -of$@ $(SRC)

$(ROOT)/invariant: $(SRC)
$(DMD) -debug -debug=INVARIANT -debug=PTRCHECK -debug=PTRCHECK2 $(UDFLAGS) -of$@ $(SRC)
$(DMD) -debug -debug=INVARIANT -debug=PTRCHECK -debug=PTRCHECK2 $(UDFLAGS) -main -of$@ $(SRC)

$(ROOT)/logging: $(SRC)
$(DMD) -debug=LOGGING $(UDFLAGS) -of$@ $(SRC)
$(DMD) -debug=LOGGING $(UDFLAGS) -main -of$@ $(SRC)

$(ROOT)/precise: $(SRC)
$(DMD) $(UDFLAGS) -gx -of$@ $(SRC) precisegc.d

clean:
rm -rf $(ROOT)
129 changes: 129 additions & 0 deletions test/gc/precisegc.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// precise GC related:
// https://issues.dlang.org/show_bug.cgi?id=3463
// https://issues.dlang.org/show_bug.cgi?id=4358
// https://issues.dlang.org/show_bug.cgi?id=9094
// https://issues.dlang.org/show_bug.cgi?id=13801
// https://issues.dlang.org/show_bug.cgi?id=18900
module testgc;

import core.memory;

class C
{
__gshared int dtors;
~this() { dtors++; }

C next;
size_t val;
}

struct S
{
__gshared int dtors;
~this() { dtors++; }

size_t val;
S* next;
}

struct L
{
__gshared int dtors;
~this() { dtors++; }

size_t[1000] data;
S* node;
}

struct Roots
{
C c;
S *s;
L *l;
};

Roots* roots;
size_t iroots;

void init()
{
roots = new Roots;
roots.c = new C;
roots.c.next = new C;

roots.s = new S;
roots.s.next = new S;

roots.l = new L;
roots.l.node = new S;
}

void verifyPointers()
{
// adrOf not reliable: https://issues.dlang.org/show_bug.cgi?id=19522
//assert(GC.addrOf(cast(void*)roots.c.next) == cast(void*)roots.c.next);
//assert(GC.addrOf(roots.s.next) == roots.s.next);
//assert(GC.addrOf(roots.l.node) == roots.l.node);
assert(C.dtors == 0);
assert(S.dtors == 0);
assert(L.dtors == 0);
}

// compiling with -gx should help eliminating false pointers on the stack
Roots makeFalsePointers()
{
roots.c.val = cast(size_t) cast(void*) roots.c.next;
roots.c.next = null;
roots.s.val = cast(size_t) cast(void*) roots.s.next;
roots.s.next = null;
roots.l.data[7] = cast(size_t) cast(void*) roots.l.node;
roots.l.node = null;

return Roots(null, null, null); // try to spill register contents
}

Roots moveRoot()
{
iroots = cast(size_t)roots;
roots = null;

return Roots(null, null, null); // try to spill register contents
}

// compiling with -gx should help eliminating false pointers on the stack
void verifyFalsePointers()
{
// addrOf not reliable: https://issues.dlang.org/show_bug.cgi?id=19522
// assert(GC.addrOf(cast(void*)(roots.c.val)) == null);
// assert(GC.addrOf(cast(void*)(roots.s.val)) == null);
// assert(GC.addrOf(cast(void*)(roots.l.data[7])) == null);
assert(C.dtors == 1);
assert(S.dtors == 2);
assert(L.dtors == 0);
}

extern(C) __gshared string[] rt_options = [ "gcopt=gc:precise", "scanDataSeg=precise" ];

void main()
{
GC.collect(); // cleanup from unittests

init();
GC.collect(); // should collect nothing
verifyPointers();

makeFalsePointers();
GC.collect(); // should collect roots.c.next, roots.s.next and roots.l.node
verifyFalsePointers();

moveRoot();
GC.collect(); // should collect all

version(Windows) // precise DATA scanning only implemented on Windows
{
//assert(GC.addrOf(cast(void*)iroots) == null);
assert(C.dtors == 2);
assert(S.dtors == 3);
assert(L.dtors == 1);
}
}
19 changes: 12 additions & 7 deletions test/gc/win64.mak
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@ DRUNTIMELIB=druntime64.lib

SRC_GC = src/gc/impl/conservative/gc.d
SRC = $(SRC_GC) src/rt/lifetime.d src/object.d
UDFLAGS = -m$(MODEL) -g -unittest -conf= -Isrc -defaultlib=$(DRUNTIMELIB) -main
UDFLAGS = -m$(MODEL) -g -unittest -conf= -Isrc -defaultlib=$(DRUNTIMELIB)

test: sentinel printf memstomp invariant logging
test: sentinel printf memstomp invariant logging precise

sentinel:
$(DMD) -debug=SENTINEL $(UDFLAGS) -of$@.exe $(SRC)
$(DMD) -debug=SENTINEL $(UDFLAGS) -main -of$@.exe $(SRC)
.\$@.exe
del $@.exe $@.obj $@.ilk $@.pdb

printf:
$(DMD) -debug=PRINTF -debug=PRINTF_TO_FILE -debug=COLLECT_PRINTF $(UDFLAGS) -of$@.exe $(SRC_GC)
$(DMD) -debug=PRINTF -debug=PRINTF_TO_FILE -debug=COLLECT_PRINTF $(UDFLAGS) -main -of$@.exe $(SRC_GC)
.\$@.exe
del $@.exe $@.obj $@.ilk $@.pdb gcx.log

memstomp:
$(DMD) -debug=MEMSTOMP $(UDFLAGS) -of$@.exe $(SRC)
$(DMD) -debug=MEMSTOMP $(UDFLAGS) -main -of$@.exe $(SRC)
.\$@.exe
del $@.exe $@.obj $@.ilk $@.pdb

invariant:
$(DMD) -debug -debug=INVARIANT -debug=PTRCHECK -debug=PTRCHECK2 $(UDFLAGS) -of$@.exe $(SRC)
$(DMD) -debug -debug=INVARIANT -debug=PTRCHECK -debug=PTRCHECK2 $(UDFLAGS) -main -of$@.exe $(SRC)
.\$@.exe
del $@.exe $@.obj $@.ilk $@.pdb

logging:
$(DMD) -debug=LOGGING $(UDFLAGS) -of$@.exe $(SRC)
$(DMD) -debug=LOGGING $(UDFLAGS) -of$@.exe -main $(SRC)
.\$@.exe
del $@.exe $@.obj $@.ilk $@.pdb

precise:
$(DMD) $(UDFLAGS) -of$@.exe -gx $(SRC) test/gc/precisegc.d
.\$@.exe
del $@.exe $@.obj $@.ilk $@.pdb

0 comments on commit a0fb48d

Please sign in to comment.