This repository has been archived by the owner on Oct 12, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
154 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// 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; | ||
|
||
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() | ||
{ | ||
// adrOf not reliable: https://issues.dlang.org/show_bug.cgi?id=19522 | ||
//assert(GC.addrOf(cast(void*)roots.c.next) == cast(void*)roots.c.next); | ||
//assert(GC.addrOf(roots.s.next) == roots.s.next); | ||
//assert(GC.addrOf(roots.l.node) == roots.l.node); | ||
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() | ||
{ | ||
// addrOf not reliable: https://issues.dlang.org/show_bug.cgi?id=19522 | ||
// assert(GC.addrOf(cast(void*)(roots.c.val)) == null); | ||
// assert(GC.addrOf(cast(void*)(roots.s.val)) == null); | ||
// assert(GC.addrOf(cast(void*)(roots.l.data[7])) == null); | ||
assert(C.dtors == 1); | ||
assert(S.dtors == 2); | ||
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(GC.addrOf(cast(void*)iroots) == null); | ||
assert(C.dtors == 2); | ||
assert(S.dtors == 3); | ||
assert(L.dtors == 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters