Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 59aaf67

Browse files
committed
ModuleGroup
- bundle rt.minfo functionality in a new struct ModuleGroup so it can be accessed/reused for shared library handling
1 parent c813532 commit 59aaf67

File tree

1 file changed

+91
-56
lines changed

1 file changed

+91
-56
lines changed

src/rt/minfo.d

Lines changed: 91 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,56 @@ enum
3535
MInew = 0x80000000 // it's the "new" layout
3636
}
3737

38-
// Windows: this gets initialized by minit.asm
39-
// Posix: this gets initialized in rt_moduleCtor()
40-
extern (C) __gshared ModuleInfo*[] _moduleinfo_array;
41-
extern(C) void _minit();
42-
43-
struct SortedCtors
38+
struct ModuleGroup
4439
{
45-
void alloc(size_t n)
40+
this(ModuleInfo*[] modules)
41+
{
42+
_modules = modules;
43+
}
44+
45+
@property inout(ModuleInfo*)[] modules() inout
46+
{
47+
return _modules;
48+
}
49+
50+
void sortCtors()
4651
{
4752
// don't bother to initialize, as they are getting overwritten anyhow
53+
immutable n = _modules.length;
4854
_ctors = (cast(ModuleInfo**).malloc(n * size_t.sizeof))[0 .. n];
4955
_tlsctors = (cast(ModuleInfo**).malloc(n * size_t.sizeof))[0 .. n];
56+
.sortCtors(this);
57+
}
58+
59+
void runCtors()
60+
{
61+
// run independent ctors
62+
runModuleFuncs!(m => m.ictor)(_modules);
63+
// sorted module ctors
64+
runModuleFuncs!(m => m.ctor)(_ctors);
65+
// flag all modules as initialized
66+
foreach (m; _modules)
67+
m.flags = m.flags | MIctordone;
68+
}
69+
70+
void runTlsCtors()
71+
{
72+
runModuleFuncs!(m => m.tlsctor)(_tlsctors);
73+
}
74+
75+
void runTlsDtors()
76+
{
77+
runModuleFuncsRev!(m => m.tlsdtor)(_tlsctors);
78+
}
79+
80+
void runDtors()
81+
{
82+
runModuleFuncsRev!(m => m.dtor)(_ctors);
83+
// clean all initialized flags
84+
foreach (m; _modules)
85+
m.flags = m.flags & ~MIctordone;
86+
87+
free();
5088
}
5189

5290
void free()
@@ -55,13 +93,24 @@ struct SortedCtors
5593
_ctors = null;
5694
.free(_tlsctors.ptr);
5795
_tlsctors = null;
96+
_modules = null;
5897
}
5998

60-
ModuleInfo*[] _ctors;
99+
private:
100+
ModuleInfo*[] _modules;
101+
ModuleInfo*[] _ctors;
61102
ModuleInfo*[] _tlsctors;
62103
}
63104

64-
__gshared SortedCtors _sortedCtors;
105+
version (Windows)
106+
{
107+
// Windows: this gets initialized by minit.asm
108+
// Posix: this gets initialized in _moduleCtor()
109+
extern(C) __gshared ModuleInfo*[] _moduleinfo_array;
110+
extern(C) void _minit();
111+
}
112+
113+
__gshared ModuleGroup _moduleGroup;
65114

66115
/********************************************
67116
* Iterate over all module infos.
@@ -71,7 +120,7 @@ int moduleinfos_apply(scope int delegate(ref ModuleInfo*) dg)
71120
{
72121
int ret = 0;
73122

74-
foreach (m; _moduleinfo_array)
123+
foreach (m; _moduleGroup._modules)
75124
{
76125
// TODO: Should null ModuleInfo be allowed?
77126
if (m !is null)
@@ -90,40 +139,27 @@ int moduleinfos_apply(scope int delegate(ref ModuleInfo*) dg)
90139

91140
extern (C) void rt_moduleCtor()
92141
{
93-
_moduleinfo_array = getModuleInfos();
94-
_sortedCtors = sortCtors(_moduleinfo_array);
95-
96-
// run independent ctors
97-
runModuleFuncs!((a) { return a.ictor; })(_moduleinfo_array);
98-
// sorted module ctors
99-
runModuleFuncs!((a) { return a.ctor; })(_sortedCtors._ctors);
100-
// flag all modules as initialized
101-
foreach (m; _moduleinfo_array)
102-
m.flags = m.flags | MIctordone;
142+
_moduleGroup = ModuleGroup(getModuleInfos());
143+
_moduleGroup.sortCtors();
144+
_moduleGroup.runCtors();
103145
}
104146

105147
extern (C) void rt_moduleTlsCtor()
106148
{
107-
runModuleFuncs!((a) { return a.tlsctor; })(_sortedCtors._tlsctors);
149+
_moduleGroup.runTlsCtors();
108150
}
109151

110152
extern (C) void rt_moduleTlsDtor()
111153
{
112-
runModuleFuncsRev!((a) { return a.tlsdtor; })(_sortedCtors._tlsctors);
154+
_moduleGroup.runTlsDtors();
113155
}
114156

115157
extern (C) void rt_moduleDtor()
116158
{
117-
runModuleFuncsRev!((a) { return a.dtor; })(_sortedCtors._ctors);
118-
119-
// clean all initialized flags
120-
foreach (m; _moduleinfo_array)
121-
m.flags = m.flags & ~MIctordone;
122-
123-
_sortedCtors.free();
159+
_moduleGroup.runDtors();
124160
version (Posix)
125-
.free(_moduleinfo_array.ptr);
126-
_moduleinfo_array = null;
161+
.free(_moduleGroup._modules.ptr);
162+
_moduleGroup.free();
127163
}
128164

129165
/********************************************
@@ -224,29 +260,35 @@ void runModuleFuncsRev(alias getfp)(ModuleInfo*[] modules)
224260
* constructors.
225261
*/
226262

227-
SortedCtors sortCtors(ModuleInfo*[] modules)
263+
void sortCtors(ref ModuleGroup mgroup)
264+
in
265+
{
266+
assert(mgroup._modules.length == mgroup._ctors.length);
267+
assert(mgroup._modules.length == mgroup._tlsctors.length);
268+
}
269+
body
228270
{
229271
enum AllocaLimit = 100 * 1024; // 100KB
230272

231-
immutable size = modules.length * StackRec.sizeof;
273+
immutable len = mgroup._modules.length;
274+
immutable size = len * StackRec.sizeof;
232275

233-
if (!size)
276+
if (!len)
234277
{
235-
return SortedCtors.init;
278+
return;
236279
}
237280
else if (size <= AllocaLimit)
238281
{
239282
auto p = cast(ubyte*).alloca(size);
240283
p[0 .. size] = 0;
241-
return sortCtorsImpl(modules, (cast(StackRec*)p)[0 .. modules.length]);
284+
sortCtorsImpl(mgroup, (cast(StackRec*)p)[0 .. len]);
242285
}
243286
else
244287
{
245288
auto p = cast(ubyte*).malloc(size);
246289
p[0 .. size] = 0;
247-
auto result = sortCtorsImpl(modules, (cast(StackRec*)p)[0 .. modules.length]);
290+
sortCtorsImpl(mgroup, (cast(StackRec*)p)[0 .. len]);
248291
.free(p);
249-
return result;
250292
}
251293
}
252294

@@ -297,21 +339,18 @@ void onCycleError(StackRec[] stack)
297339
throw new Exception("Aborting!");
298340
}
299341

300-
private SortedCtors sortCtorsImpl(ModuleInfo*[] modules, StackRec[] stack)
342+
private void sortCtorsImpl(ref ModuleGroup mgroup, StackRec[] stack)
301343
{
302-
SortedCtors result;
303-
result.alloc(modules.length);
304-
305344
size_t stackidx;
306345
bool tlsPass;
307346

308347
Lagain:
309348

310349
const mask = tlsPass ? (MItlsctor | MItlsdtor) : (MIctor | MIdtor);
311-
auto ctors = tlsPass ? result._tlsctors : result._ctors;
350+
auto ctors = tlsPass ? mgroup._tlsctors : mgroup._ctors;
312351
size_t cidx;
313352

314-
ModuleInfo*[] mods = modules;
353+
ModuleInfo*[] mods = mgroup._modules;
315354
size_t idx;
316355
while (true)
317356
{
@@ -375,7 +414,7 @@ private SortedCtors sortCtorsImpl(ModuleInfo*[] modules, StackRec[] stack)
375414
/* Internal runtime error, dependency on an uninitialized
376415
* module outside of the current module group.
377416
*/
378-
(stackidx < modules.length) || assert(0);
417+
(stackidx < mgroup._modules.length) || assert(0);
379418

380419
// recurse
381420
stack[stackidx++] = StackRec(mods, idx);
@@ -400,22 +439,18 @@ private SortedCtors sortCtorsImpl(ModuleInfo*[] modules, StackRec[] stack)
400439
break;
401440
}
402441
// store final number
403-
tlsPass ? result._tlsctors : result._ctors = ctors[0 .. cidx];
442+
tlsPass ? mgroup._tlsctors : mgroup._ctors = ctors[0 .. cidx];
404443

405444
// clean flags
406-
for (size_t i = 0; i < modules.length; ++i)
407-
{ auto m = modules[i];
445+
foreach(m; mgroup._modules)
408446
m.flags = m.flags & ~(MIctorstart | MIctordone);
409-
}
410447

411448
// rerun for TLS constructors
412449
if (!tlsPass)
413450
{
414451
tlsPass = true;
415452
goto Lagain;
416453
}
417-
418-
return result;
419454
}
420455

421456
version (unittest)
@@ -470,12 +505,12 @@ unittest
470505

471506
void checkExp(ModuleInfo*[] dtors=null, ModuleInfo*[] tlsdtors=null)
472507
{
473-
auto ptrs = [&m0, &m1, &m2];
474-
auto sorted = sortCtors(ptrs);
475-
foreach (m; ptrs)
508+
auto mgroup = ModuleGroup([&m0, &m1, &m2]);
509+
mgroup.sortCtors();
510+
foreach (m; mgroup._modules)
476511
assert(!(m.flags & (MIctorstart | MIctordone)));
477-
assert(sorted._ctors == dtors);
478-
assert(sorted._tlsctors == tlsdtors);
512+
assert(mgroup._ctors == dtors);
513+
assert(mgroup._tlsctors == tlsdtors);
479514
}
480515

481516
// no ctors

0 commit comments

Comments
 (0)