blob: 0e4eb4494018561efadfb203a57ec8915050c1b5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
module lib;
// test EH
void throwException()
{
throw new Exception(null);
}
Exception collectException(void delegate() dg)
{
try
dg();
catch (Exception e)
return e;
return null;
}
// test GC
__gshared Object root;
void alloc() { root = new Object(); }
void access() { assert(root.toString() !is null); } // vtbl call will fail if finalized
void free() { root = null; }
Object tls_root;
void tls_alloc() { tls_root = new Object(); }
void tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized
void tls_free() { tls_root = null; }
void stack(alias func)()
{
// allocate some extra stack space to not keep references to GC memory on the scanned stack
ubyte[1024] buf = void;
func();
}
void testGC()
{
import core.memory;
stack!alloc();
stack!tls_alloc();
stack!access();
stack!tls_access();
GC.collect();
stack!tls_access();
stack!access();
stack!tls_free();
stack!free();
}
// test Init
import core.atomic : atomicOp;
shared uint shared_static_ctor, shared_static_dtor, static_ctor, static_dtor;
shared static this() { if (atomicOp!"+="(shared_static_ctor, 1) != 1) assert(0); }
shared static ~this() { if (atomicOp!"+="(shared_static_dtor, 1) != 1) assert(0); }
static this() { atomicOp!"+="(static_ctor, 1); }
static ~this() { atomicOp!"+="(static_dtor, 1); }
extern(C) int runTests()
{
try
runTestsImpl();
catch (Throwable)
return 0;
return 1;
}
void runTestsImpl()
{
import core.thread;
bool passed;
try
throwException();
catch (Exception e)
passed = true;
assert(passed);
assert(collectException({throwException();}) !is null);
testGC();
assert(shared_static_ctor == 1);
assert(static_ctor == 1);
static void run()
{
assert(static_ctor == 2);
assert(shared_static_ctor == 1);
testGC();
}
auto thr = new Thread(&run);
thr.start();
thr.join();
assert(static_dtor == 1);
passed = false;
foreach (m; ModuleInfo)
if (m.name == "lib") passed = true;
assert(passed);
}
// Provide a way to initialize D from C programs that are D agnostic.
import core.runtime : rt_init, rt_term;
extern(C) int lib_init()
{
return rt_init();
}
extern(C) int lib_term()
{
return rt_term();
}
shared size_t* _finalizeCounter;
class MyFinalizer
{
~this()
{
import core.atomic;
atomicOp!"+="(*_finalizeCounter, 1);
}
}
class MyFinalizerBig : MyFinalizer
{
ubyte[4096] _big = void;
}
extern(C) void setFinalizeCounter(shared(size_t)* p)
{
_finalizeCounter = p;
}
|