diff options
Diffstat (limited to 'libphobos/testsuite/libphobos.gc/precisegc.d')
-rw-r--r-- | libphobos/testsuite/libphobos.gc/precisegc.d | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/libphobos/testsuite/libphobos.gc/precisegc.d b/libphobos/testsuite/libphobos.gc/precisegc.d new file mode 100644 index 00000000000..9bcaf3f4faa --- /dev/null +++ b/libphobos/testsuite/libphobos.gc/precisegc.d @@ -0,0 +1,126 @@ +// 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; +import core.stdc.stdio; + +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() +{ + 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() +{ + assert(C.dtors <= 1); + if (C.dtors < 1) printf ("False pointers? C.dtors = %d, 1 expected\n", C.dtors); + assert(S.dtors <= 2); + if (S.dtors < 2) printf ("False pointers? S.dtors = %d, 2 expected\n", S.dtors); + 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(C.dtors <= 2); + if (C.dtors < 2) printf ("False DATA pointers? C.dtors = %d, 2 expected\n", C.dtors); + assert(S.dtors <= 3); + if (S.dtors < 3) printf ("False DATA pointers? S.dtors = %d, 2 expected\n", S.dtors); + assert(L.dtors <= 1); + if (L.dtors < 1) printf ("False DATA pointers? L.dtors = %d, 1 expected\n", L.dtors); + } +} |