This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Declare memory allocation functions "throw()"


This patch adds an empty exception specification (i.e., throw ()) to
declarations of memory allocation functions in <stdlib.h>.

The objective is that C++ compilers (including G++) generate better
code if they can tell that one of the functions they are calling is
not going to throw an exception.  Of course, most C library functions
do not throw exceptions, but there are some counter-examples:

1. qsort may throw exceptions, since it calls back into a
   user-provided sort function, which may itself throw an exception

2. when using POSIX threads, some functions are "cancellation points".
   Under GLIBC, these functions throw exceptions to indicate
   cancellation.  I'm not sure what Newlib does in this case.

So, we don't just blindly want to annotate all functions with
"throw()"; I think we should gradually go through and add the
specifications where we are convinced it's safe.

I started with the memory allocation functions because I was looking
at "operator delete" on ARM; this calls "free", and because the
compiler thought that "free" might throw an exception, this meant that
"operator delete" had EH unwind information.  That, in turn, pulled in
EH support routines and made my application bigger.

If this patch (or some variant of it) is approved, then we can
gradually add more exception specifications through the headers, just
as GLIBC has done.  This is particularly important for Newlib, since
it's often used on small-memory systems where eliminating the EH
code-size overhead is important.

OK to apply?

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2007-05-04  Mark Mitchell  <mark@codesourcery.com>

	* libc/include/stdlib.h (calloc): Declare with EXFUN_NOTHROW.
	(free): Likewise.
	(malloc): Likewise.
	(realloc): Likewise.
	(_malloc_r): Likewise.
	(_callor_r): Likewise.
	(_free_r): Likewise.
	(_realloc_r): Likewise.
	* libc/include/_ansi.h: Move C++ defines to top of file.
	(_NOTHROW): New macro.
	(_EXFUN_NOTHROW): Likewise.

Index: newlib/libc/include/stdlib.h
===================================================================
--- newlib/libc/include/stdlib.h	(revision 167623)
+++ newlib/libc/include/stdlib.h	(working copy)
@@ -74,17 +74,17 @@ _PTR	_EXFUN(bsearch,(const _PTR __key,
 		       size_t __nmemb,
 		       size_t __size,
 		       int _EXPARM(_compar,(const _PTR, const _PTR))));
-_PTR	_EXFUN(calloc,(size_t __nmemb, size_t __size));
+_PTR	_EXFUN_NOTHROW(calloc,(size_t __nmemb, size_t __size));
 div_t	_EXFUN(div,(int __numer, int __denom));
 _VOID	_EXFUN(exit,(int __status) _ATTRIBUTE ((noreturn)));
-_VOID	_EXFUN(free,(_PTR));
+_VOID	_EXFUN_NOTHROW(free,(_PTR));
 char *  _EXFUN(getenv,(const char *__string));
 char *	_EXFUN(_getenv_r,(struct _reent *, const char *__string));
 char *	_EXFUN(_findenv,(_CONST char *, int *));
 char *	_EXFUN(_findenv_r,(struct _reent *, _CONST char *, int *));
 long	_EXFUN(labs,(long));
 ldiv_t	_EXFUN(ldiv,(long __numer, long __denom));
-_PTR	_EXFUN(malloc,(size_t __size));
+_PTR	_EXFUN_NOTHROW(malloc,(size_t __size));
 int	_EXFUN(mblen,(const char *, size_t));
 int	_EXFUN(_mblen_r,(struct _reent *, const char *, size_t, _mbstate_t *));
 int	_EXFUN(mbtowc,(wchar_t *, const char *, size_t));
@@ -103,7 +103,7 @@ char *  _EXFUN(mktemp,(char *));
 #endif
 _VOID	_EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR)));
 int	_EXFUN(rand,(_VOID));
-_PTR	_EXFUN(realloc,(_PTR __r, size_t __size));
+_PTR	_EXFUN_NOTHROW(realloc,(_PTR __r, size_t __size));
 _VOID	_EXFUN(srand,(unsigned __seed));
 double	_EXFUN(strtod,(const char *__n, char **__end_PTR));
 double	_EXFUN(_strtod_r,(struct _reent *,const char *__n, char **__end_PTR));
@@ -182,10 +182,10 @@ void	_EXFUN(_unsetenv_r,(struct _reent *
 
 char *	_EXFUN(_dtoa_r,(struct _reent *, double, int, int, int *, int*, char**));
 #ifndef __CYGWIN__
-_PTR	_EXFUN(_malloc_r,(struct _reent *, size_t));
-_PTR	_EXFUN(_calloc_r,(struct _reent *, size_t, size_t));
-_VOID	_EXFUN(_free_r,(struct _reent *, _PTR));
-_PTR	_EXFUN(_realloc_r,(struct _reent *, _PTR, size_t));
+_PTR	_EXFUN_NOTHROW(_malloc_r,(struct _reent *, size_t));
+_PTR	_EXFUN_NOTHROW(_calloc_r,(struct _reent *, size_t, size_t));
+_VOID	_EXFUN_NOTHROW(_free_r,(struct _reent *, _PTR));
+_PTR	_EXFUN_NOTHROW(_realloc_r,(struct _reent *, _PTR, size_t));
 _VOID	_EXFUN(_mstats_r,(struct _reent *, char *));
 #endif
 int	_EXFUN(_system_r,(struct _reent *, const char *));
Index: newlib/libc/include/_ansi.h
===================================================================
--- newlib/libc/include/_ansi.h	(revision 167623)
+++ newlib/libc/include/_ansi.h	(working copy)
@@ -23,6 +23,25 @@
 #define _HAVE_STDC
 #endif
 
+/*  ISO C++.  */
+
+#ifdef __cplusplus
+#if !(defined(_BEGIN_STD_C) && defined(_END_STD_C))
+#ifdef _HAVE_STD_CXX
+#define _BEGIN_STD_C namespace std { extern "C" {
+#define _END_STD_C  } }
+#else
+#define _BEGIN_STD_C extern "C" {
+#define _END_STD_C  }
+#endif
+#define _NOTHROW throw()
+#endif
+#else
+#define _BEGIN_STD_C
+#define _END_STD_C
+#define _NOTHROW
+#endif
+
 #ifdef _HAVE_STDC
 #define	_PTR		void *
 #define	_AND		,
@@ -33,9 +52,11 @@
 #define	_DOTS		, ...
 #define _VOID void
 #ifdef __CYGWIN__
+#define	_EXFUN_NOTHROW(name, proto)	__cdecl name proto _NOTHROW
 #define	_EXFUN(name, proto)		__cdecl name proto
 #define	_EXPARM(name, proto)		(* __cdecl name) proto
 #else
+#define	_EXFUN_NOTHROW(name, proto)	name proto _NOTHROW
 #define	_EXFUN(name, proto)		name proto
 #define _EXPARM(name, proto)		(* name) proto
 #endif
@@ -75,21 +96,4 @@
 #define _ATTRIBUTE(attrs)
 #endif
 
-/*  ISO C++.  */
-
-#ifdef __cplusplus
-#if !(defined(_BEGIN_STD_C) && defined(_END_STD_C))
-#ifdef _HAVE_STD_CXX
-#define _BEGIN_STD_C namespace std { extern "C" {
-#define _END_STD_C  } }
-#else
-#define _BEGIN_STD_C extern "C" {
-#define _END_STD_C  }
-#endif
-#endif
-#else
-#define _BEGIN_STD_C
-#define _END_STD_C
-#endif
-
 #endif /* _ANSIDECL_H_ */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]