This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
RE: [RFC] Reduce code bloat caused by demangler (was: Don't access fpos_t.__state on uClibc w/o wchar support)
- From: Pétur Runólfsson <peturr02 at ru dot is>
- To: "Carlo Wood" <carlo at alinoe dot com>,<libstdc++ at gcc dot gnu dot org>
- Date: Mon, 29 Sep 2003 15:28:42 -0000
- Subject: RE: [RFC] Reduce code bloat caused by demangler (was: Don't access fpos_t.__state on uClibc w/o wchar support)
Carlo Wood wrote:
> On Mon, Sep 29, 2003 at 09:03:37AM -0000, Pétur Runólfsson wrote:
> > Bernardo Innocenti wrote:
> > > Actually, there are bigger outstanding problems in 3.4: the new
> > > demangler gets linked in as soon as the program uses exceptions,
> > > bringing 200KB worth of code with it.
>
> I don't understand this remark entirely.
OK, as far as I understand, the situation is this:
demangle.o uses string, so it brings in string-inst.o and
allocator-inst.o.
string uses __throw_length_error, which is defined in functexcept.cc,
so functexcept.o gets included.
__throw_ios_failure is also defined in functexcept.cc and uses
ios_base::failure::failure(), which is defined in ios.cc, so we
get ios.o.
ios.cc includes ios_base::sync_with_stdio, which uses istream, ostream
and basic_filebuf, so we get fstream-inst.o, istream-inst.o and
ostream-inst.o.
ios.cc also includes ios_base::getloc(), which uses,
locale(const locale&), which is defined in locale.cc
istream and ostream inherit from ios, which is defined in io-inst.cc.
io-inst.cc has #include <iostream>, which causes an object of type
ios_base::Init to be created. This is why the iostreams library gets
initialized, even in programs that make no use of it. locale::classic()
currently depends on the presence of this object.
locale.cc includes locale::classic() and locale(const char*), which
bring in localename.o.
localename.cc uses all the facets, so we get locale-inst.o,
ctype_members.o, codecvt_members.o, messages_members.o etc.
So, everytime string is used in a statically linked program, the
executable includes almost the whole of libstdc++, even though almost
none of it is actually needed.
My patch breaks the chain between functexcept.o and ios.o, by moving
ios_base::failure into a separate source file. In the future, it makes
sense to move ios_base::Init and ios_base::sync_with_stdio into
another source file, so <sstream> can be used without bringing in
basic_filebuf.
> Now I suppose that you don't mean *shared* code, linked in from
> libstdc++ (the Undefined symbols in demangle.o).
That is exactly what I mean.
> I surely also
> hope that the size of the decode_* routines aren't that "huge"
> because of dragged in code bloat because of *inlined* code from
> <string> or <vector>.
That isn't bloat, because that code is used by the program.
Since <iostream> is not used by the program, the only thing it
achieves is to increase the size of the executable; hence it's
'bloat'.
Note that really has nothing to do with the demangler per se,
any use of <string> will currently drag iostreams along with it.
The faq
http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#2_5
suggests that the linker flag --gc-sections can be used to
combat this bloat. It doesn't help much on my system; I suspect
that the ios_base::Init object in io-inst.o causes the linker
to think that the iostreams bits are being used.
That faq also suggests that splitting up source files should be
avoided for maintenance reasons. IMHO maintenance reasons
argue *for* splitting up ios.cc; failure, Init and sync_with_stdio
have nothing to do with the rest of ios_base, so they shouldn't
be put in the same source file.
Regards,
Petur