mirror of
https://github.com/dlang/dmd.git
synced 2025-04-28 06:00:13 +03:00
126 lines
2.7 KiB
D
126 lines
2.7 KiB
D
// 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);
|
|
}
|
|
}
|