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