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

Commit a0fb48d

Browse files
committed
add test for precise GC
1 parent aa3a5d9 commit a0fb48d

File tree

4 files changed

+154
-14
lines changed

4 files changed

+154
-14
lines changed

src/gc/impl/conservative/gc.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3857,6 +3857,7 @@ unittest
38573857

38583858
// improve predictability of coverage of code that is eventually not hit by other tests
38593859
debug (SENTINEL) {} else // cannot extend with SENTINEL
3860+
debug (MARK_PRINTF) {} else // takes forever
38603861
unittest
38613862
{
38623863
import core.memory;
@@ -3909,6 +3910,8 @@ version (D_LP64) unittest
39093910
if (os_physical_mem() > sz)
39103911
{
39113912
import core.memory;
3913+
GC.collect();
3914+
GC.minimize();
39123915
auto stats = GC.stats();
39133916
auto ptr = GC.malloc(sz, BlkAttr.NO_SCAN);
39143917
auto info = GC.query(ptr);

test/gc/Makefile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
include ../common.mak
22

3-
TESTS := sentinel printf memstomp invariant logging
3+
TESTS := sentinel printf memstomp invariant logging precise
44

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

1010
.PHONY: all clean
1111
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
@@ -16,19 +16,22 @@ $(ROOT)/%.done: $(ROOT)/%
1616
@touch $@
1717

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

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

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

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

3030
$(ROOT)/logging: $(SRC)
31-
$(DMD) -debug=LOGGING $(UDFLAGS) -of$@ $(SRC)
31+
$(DMD) -debug=LOGGING $(UDFLAGS) -main -of$@ $(SRC)
32+
33+
$(ROOT)/precise: $(SRC)
34+
$(DMD) $(UDFLAGS) -gx -of$@ $(SRC) precisegc.d
3235

3336
clean:
3437
rm -rf $(ROOT)

test/gc/precisegc.d

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// precise GC related:
2+
// https://issues.dlang.org/show_bug.cgi?id=3463
3+
// https://issues.dlang.org/show_bug.cgi?id=4358
4+
// https://issues.dlang.org/show_bug.cgi?id=9094
5+
// https://issues.dlang.org/show_bug.cgi?id=13801
6+
// https://issues.dlang.org/show_bug.cgi?id=18900
7+
module testgc;
8+
9+
import core.memory;
10+
11+
class C
12+
{
13+
__gshared int dtors;
14+
~this() { dtors++; }
15+
16+
C next;
17+
size_t val;
18+
}
19+
20+
struct S
21+
{
22+
__gshared int dtors;
23+
~this() { dtors++; }
24+
25+
size_t val;
26+
S* next;
27+
}
28+
29+
struct L
30+
{
31+
__gshared int dtors;
32+
~this() { dtors++; }
33+
34+
size_t[1000] data;
35+
S* node;
36+
}
37+
38+
struct Roots
39+
{
40+
C c;
41+
S *s;
42+
L *l;
43+
};
44+
45+
Roots* roots;
46+
size_t iroots;
47+
48+
void init()
49+
{
50+
roots = new Roots;
51+
roots.c = new C;
52+
roots.c.next = new C;
53+
54+
roots.s = new S;
55+
roots.s.next = new S;
56+
57+
roots.l = new L;
58+
roots.l.node = new S;
59+
}
60+
61+
void verifyPointers()
62+
{
63+
// adrOf not reliable: https://issues.dlang.org/show_bug.cgi?id=19522
64+
//assert(GC.addrOf(cast(void*)roots.c.next) == cast(void*)roots.c.next);
65+
//assert(GC.addrOf(roots.s.next) == roots.s.next);
66+
//assert(GC.addrOf(roots.l.node) == roots.l.node);
67+
assert(C.dtors == 0);
68+
assert(S.dtors == 0);
69+
assert(L.dtors == 0);
70+
}
71+
72+
// compiling with -gx should help eliminating false pointers on the stack
73+
Roots makeFalsePointers()
74+
{
75+
roots.c.val = cast(size_t) cast(void*) roots.c.next;
76+
roots.c.next = null;
77+
roots.s.val = cast(size_t) cast(void*) roots.s.next;
78+
roots.s.next = null;
79+
roots.l.data[7] = cast(size_t) cast(void*) roots.l.node;
80+
roots.l.node = null;
81+
82+
return Roots(null, null, null); // try to spill register contents
83+
}
84+
85+
Roots moveRoot()
86+
{
87+
iroots = cast(size_t)roots;
88+
roots = null;
89+
90+
return Roots(null, null, null); // try to spill register contents
91+
}
92+
93+
// compiling with -gx should help eliminating false pointers on the stack
94+
void verifyFalsePointers()
95+
{
96+
// addrOf not reliable: https://issues.dlang.org/show_bug.cgi?id=19522
97+
// assert(GC.addrOf(cast(void*)(roots.c.val)) == null);
98+
// assert(GC.addrOf(cast(void*)(roots.s.val)) == null);
99+
// assert(GC.addrOf(cast(void*)(roots.l.data[7])) == null);
100+
assert(C.dtors == 1);
101+
assert(S.dtors == 2);
102+
assert(L.dtors == 0);
103+
}
104+
105+
extern(C) __gshared string[] rt_options = [ "gcopt=gc:precise", "scanDataSeg=precise" ];
106+
107+
void main()
108+
{
109+
GC.collect(); // cleanup from unittests
110+
111+
init();
112+
GC.collect(); // should collect nothing
113+
verifyPointers();
114+
115+
makeFalsePointers();
116+
GC.collect(); // should collect roots.c.next, roots.s.next and roots.l.node
117+
verifyFalsePointers();
118+
119+
moveRoot();
120+
GC.collect(); // should collect all
121+
122+
version(Windows) // precise DATA scanning only implemented on Windows
123+
{
124+
//assert(GC.addrOf(cast(void*)iroots) == null);
125+
assert(C.dtors == 2);
126+
assert(S.dtors == 3);
127+
assert(L.dtors == 1);
128+
}
129+
}

test/gc/win64.mak

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,36 @@ DRUNTIMELIB=druntime64.lib
66

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

11-
test: sentinel printf memstomp invariant logging
11+
test: sentinel printf memstomp invariant logging precise
1212

1313
sentinel:
14-
$(DMD) -debug=SENTINEL $(UDFLAGS) -of$@.exe $(SRC)
14+
$(DMD) -debug=SENTINEL $(UDFLAGS) -main -of$@.exe $(SRC)
1515
.\$@.exe
1616
del $@.exe $@.obj $@.ilk $@.pdb
1717

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

2323
memstomp:
24-
$(DMD) -debug=MEMSTOMP $(UDFLAGS) -of$@.exe $(SRC)
24+
$(DMD) -debug=MEMSTOMP $(UDFLAGS) -main -of$@.exe $(SRC)
2525
.\$@.exe
2626
del $@.exe $@.obj $@.ilk $@.pdb
2727

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

3333
logging:
34-
$(DMD) -debug=LOGGING $(UDFLAGS) -of$@.exe $(SRC)
34+
$(DMD) -debug=LOGGING $(UDFLAGS) -of$@.exe -main $(SRC)
35+
.\$@.exe
36+
del $@.exe $@.obj $@.ilk $@.pdb
37+
38+
precise:
39+
$(DMD) $(UDFLAGS) -of$@.exe -gx $(SRC) test/gc/precisegc.d
3540
.\$@.exe
3641
del $@.exe $@.obj $@.ilk $@.pdb

0 commit comments

Comments
 (0)