blob: 9bcaf3f4faad0de69227aabcb664d1d9b8f8214e [file] [log] [blame]
// 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);
}
}