Reducing the size of C++ executables - eliminating malloc
Michael Eager
eager@eagercon.com
Sun Nov 12 22:37:00 GMT 2006
Mark Mitchell wrote:
> Michael Eager wrote:
>> GCC 4.1.1 for PowerPC generates a 162K executable for a
>> minimal program "int main() { return 0; }". GCC 3.4.1
>> generated a 7.2K executable. Mark Mitchell mentioned the
>> same problem for ARM and proposed a patch to remove the
>> reference to malloc in atexit
>> (http://sourceware.org/ml/newlib/2006/msg00181.html).
>>
>> There are references to malloc in eh_alloc.c and
>> unwind-dw2-fde.c. It looks like these are being
>> included even when there are no exception handlers.
>>
>> Any suggestions on how to eliminate the references
>> to these routines?
>
> These aren't full implementation sketches, but, yes, we can do better.
> Here are some ideas:
>
> 1. For the DWARF unwind stuff, have the linker work out how much space
> is required and pre-allocate it. The space required is a statically
> knowable property of the executable, modulo dynamic linking, and on the
> cases where we care most (bare-metal) we don't have to worry about
> dynamic linking. (If you can afford a dynamic linker, you can probably
> afford malloc, and it's in a shared library.)
>
> 2. For the EH stuff, the maximum size of an exception is also statically
> knowable, again assuming no dynamic linking. The maximum exception
> nesting depth (i.e., the number of simultaneously active exceptions) is
> not, though. So, here, what I think you want is a small, statically
> allocated stack, at least as big as the biggest exception, out of which
> you allocate exception objects. Happily, we already have this, in the
> form of "emergency_buffer" -- although it uses a compile-time estimate
> of the biggest object, rather than having the linker fill it in, as
> would be ideal. But, in the no-malloc case, just fall back to the
> emergency mode.
>
> You could also declare malloc "weak" in that file, and just not call it
> if the value is zero. That way, if malloc is around, you can use it --
> but if it's not, you use the emergency buffer. Put the emergency_buffer
> in a separate file (rather than in eh_alloc.cc), so that users can
> provide their own implementation to control the size, overriding the one
> in the library.
Preallocating space is a good thing, particularly if the size
can be computed at compile time. It's a little bit more awkward
if it has to be calculated at link time.
On the other hand, why should either DWARF unwind or the eh_*
files be included if C++ exception handling is not used?
The minimal executable has a reference to __gxx_personality_v0.
This is defined in eh_personality.o, which has a reference to
__cxa_allocate_exception in eh_alloc.o. So this seems to be the
thread which pulls in all the other pieces.
Generating __gxx_personality_v0 is suppressed with the -fno-exceptions
flag, but it would seem better if this symbol were only generated
when catch/throw was used. This happens in cxx_init_decl_processing(),
which is called before it's known whether or not EH is really needed.
Any suggestions on how to move this test later?
--
Michael Eager eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306 650-325-8077
More information about the Newlib
mailing list