Binary Size: function-sections, data-sections, etc.

Artur Skawina art.08.09 at gmail.com
Wed Dec 21 11:04:06 PST 2011


On 12/21/11 17:42, Kagamin wrote:
>> Could you elaborate?
> 
> As I remember, these features rely heavily on linker support, namely on how it merges sections. Each pointer to static ctor (and unittest) is placed in a section, then these sections are merged by linker and you get an array of pointers to all static ctors and unittests. The startup code reads the pointers in sequence and executes them. If some section is removed, the corresponding static ctor won't be run.
> 
>> Real code, that i was testing with previously, contained static module ctors which
>> worked, and i just tried a simple two module test w/ multiple shared_[cd]tors +
>> static_[cd]tors + unittests -- all of them are called as expected.
> 
> If so then ok.

I suspected that was what you were worried about and did that test [1],
which gives the expected output. But looking now at the list of linker
gc'ed sections, i notice ld does claim to have removed eg
".text._D11gcfuncdata218_sharedStaticCtor3FZv", which is one of the ctors.
The reason things still work is because the code is also inlined in 
"_D11gcfuncdata215__modsharedctorFZv" together with the other ctor. 
Aha, the compiler (gdc) actually inlined all the [cd]tors when run at -O3,
and the "real" constructor was then garbage collected by the linker. Phew.
Compiling with -O2 makes modsharedctor call all the ctors instead, and they
are then not gc'ed. 

Why the compiler emits the unused outofline ctors is another question.
Maybe i should start marking them as private?...

Turned out not to be a good idea, as the compiler silently accepts
"shared private static this() {...}" and does not emit the dead code anymore.
But.. this constructor is run together with the un-shared ones, ie possibly
_after_ them... (this is not section-gc specific, happens w/o it too)

artur

[1]

import std.stdio;

/* gcfuncdata2.d is a copy of this module, w/o main() */
import gcfuncdata2;

auto p(S...)(S args) { return stdout.writeln(__FILE__~": ", args); }

void main(string[] args){ p("main"); }

static this() { p("ctor1"); }
static this() { p("ctor2"); }
shared static this() { p("shared ctor1"); }
shared static this() { p("shared ctor2"); }

static ~this() { p("dtor1"); }
static ~this() { p("dtor2"); }
shared static ~this() { p("shared dtor1"); }
shared static ~this() { p("shared dtor2"); }

unittest { p("unittest1"); }
unittest { p("unittest2"); }



More information about the Digitalmars-d mailing list