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