This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Reducing the size of C++ executables - eliminating malloc
- From: jschopp <jschopp at austin dot ibm dot com>
- To: Michael Eager <eager at eagercon dot com>
- Cc: GCC <gcc at gcc dot gnu dot org>, Newlib <newlib at sourceware dot org>
- Date: Mon, 13 Nov 2006 00:11:03 -0600
- Subject: Re: Reducing the size of C++ executables - eliminating malloc
- References: <455612EC.3060502@eagercon.com>
> 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).
We've seen this on cell spu as well. And with only 256K total memory it was a really big
deal for us. Our minimal program dropped from 10566 bytes to 2822 bytes (text + data +
bss) with the attached completely unacceptable for merging patch. We were thinking that
our platform has no need for more than 32 atexit handlers, and the proper solution is to
make the code removed in the attached patch simply #ifdefed away for platforms like ours
that are happy with 32 atexit handlers and are short on space. This seems to be the
approach in the patch you linked to.
-Joel
Index: newlib-1.14.0/newlib/libc/stdlib/__atexit.c
===================================================================
--- newlib-1.14.0.orig/newlib/libc/stdlib/__atexit.c
+++ newlib-1.14.0/newlib/libc/stdlib/__atexit.c
@@ -9,6 +9,7 @@
#include "atexit.h"
+
/*
* Register a function to be performed at exit or on shared library unload.
*/
@@ -24,6 +25,10 @@ _DEFUN (__register_exitproc,
struct _on_exit_args * args;
register struct _atexit *p;
+#ifdef _REENT_SMALL
+ static struct _on_exit_args myargs;
+#endif
+
#ifndef __SINGLE_THREAD__
__LOCK_INIT(static, lock);
@@ -35,21 +40,10 @@ _DEFUN (__register_exitproc,
_GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
if (p->_ind >= _ATEXIT_SIZE)
{
- p = (struct _atexit *) malloc (sizeof *p);
- if (p == NULL)
- {
#ifndef __SINGLE_THREAD__
__lock_release(lock);
#endif
return -1;
- }
- p->_ind = 0;
- p->_next = _GLOBAL_REENT->_atexit;
- _GLOBAL_REENT->_atexit = p;
-#ifndef _REENT_SMALL
- p->_on_exit_args._fntypes = 0;
- p->_on_exit_args._is_cxa = 0;
-#endif
}
if (type != __et_atexit)
@@ -58,7 +52,8 @@ _DEFUN (__register_exitproc,
args = p->_on_exit_args_ptr;
if (args == NULL)
{
- args = malloc (sizeof * p->_on_exit_args_ptr);
+/* args = malloc (sizeof * p->_on_exit_args_ptr); */
+ args = myargs;
if (args == NULL)
{
#ifndef __SINGLE_THREAD__
Index: newlib-1.14.0/newlib/libc/stdlib/__call_atexit.c
===================================================================
--- newlib-1.14.0.orig/newlib/libc/stdlib/__call_atexit.c
+++ newlib-1.14.0/newlib/libc/stdlib/__call_atexit.c
@@ -68,10 +68,10 @@ _DEFUN (__call_exitprocs, (code, d),
/* Remove empty block from the list. */
*lastp = p->_next;
#ifdef _REENT_SMALL
- if (args)
- free (args);
+/* if (args) */
+/* free (args); */
#endif
- free (p);
+/* free (p); */
p = *lastp;
}
else