changeset 7608:060ba558f95d

* lib/xalloc.h (xnmalloc, xnrealloc, x2nrealloc): Now static inline functions that are identical with the old xnmalloc_inline, xnrealloc_inline, x2nrealloc_inline of lib/xmalloc.c. This is so that we can avoid some unnecessary integer multiplications and divisions in the common case where the element size is known at compile time. (XNMALLOC) [HAVE_INLINE]: Remove special case, which is no longer needed. (xnboundedmalloc): Remove. (XMALLOC, XNMALLOC, XZALLOC, XCALLOC): Use lower-case letters for arguments, for consistency with rest of this header. (xcharalloc): Rewrite using XNMALLOC. * lib/xmalloc.c (xnmalloc_inline, xnmalloc, xnrealloc_inline): (xnrealloc, x2nrealloc_inline, x2nrealloc): Remove. The *_inline versions have been moved to lib/xalloc.h and renamed to be the non-*_inline versions. (xmalloc, xrealloc): Implement without reference to the xnmalloc and xnrealloc functions, since those functions are now inline and now call us. (x2realloc): Invoke x2realloc, not x2realloc_inline, to accommodate renaming described above.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 06 Nov 2006 21:24:35 +0000
parents 0358f264cb92
children 387691bf7ac7
files ChangeLog lib/xalloc.h lib/xmalloc.c
diffstat 3 files changed, 149 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
 2006-11-06  Paul Eggert  <eggert@cs.ucla.edu>
 
+	* lib/xalloc.h (xnmalloc, xnrealloc, x2nrealloc): Now static
+	inline functions that are identical with the old xnmalloc_inline,
+	xnrealloc_inline, x2nrealloc_inline of lib/xmalloc.c.  This is so
+	that we can avoid some unnecessary integer multiplications and
+	divisions in the common case where the element size is known at
+	compile time.
+	(XNMALLOC) [HAVE_INLINE]: Remove special case, which is no longer
+	needed.
+	(xnboundedmalloc): Remove.
+	(XMALLOC, XNMALLOC, XZALLOC, XCALLOC): Use lower-case letters for
+	arguments, for consistency with rest of this header.
+	(xcharalloc): Rewrite using XNMALLOC.
+	* lib/xmalloc.c (xnmalloc_inline, xnmalloc, xnrealloc_inline):
+	(xnrealloc, x2nrealloc_inline, x2nrealloc): Remove.  The *_inline
+	versions have been moved to lib/xalloc.h and renamed to be the
+	non-*_inline versions.
+	(xmalloc, xrealloc): Implement without reference to the xnmalloc
+	and xnrealloc functions, since those functions are now inline and
+	now call us.
+	(x2realloc): Invoke x2realloc, not x2realloc_inline, to accommodate
+	renaming described above.
+
 	New module canonicalize-lgpl, proposed by Charles Wilson in
 	<http://lists.gnu.org/archive/html/bug-gnulib/2006-11/msg00020.html>
 	with a few small changes afterwards.
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -1,7 +1,7 @@
 /* xalloc.h -- malloc with out-of-memory checking
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -46,13 +46,10 @@
 extern void xalloc_die (void) ATTRIBUTE_NORETURN;
 
 void *xmalloc (size_t s);
-void *xnmalloc (size_t n, size_t s);
 void *xzalloc (size_t s);
 void *xcalloc (size_t n, size_t s);
 void *xrealloc (void *p, size_t s);
-void *xnrealloc (void *p, size_t n, size_t s);
 void *x2realloc (void *p, size_t *pn);
-void *x2nrealloc (void *p, size_t *pn, size_t s);
 void *xmemdup (void const *p, size_t s);
 char *xstrdup (char const *str);
 
@@ -71,57 +68,142 @@
 # define xalloc_oversized(n, s) \
     ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
 
+/* Allocate an array of N objects, each with S bytes of memory,
+   dynamically, with error checking.  S must be nonzero.  */
+
+static inline void *
+xnmalloc (size_t n, size_t s)
+{
+  if (xalloc_oversized (n, s))
+    xalloc_die ();
+  return xmalloc (n * s);
+}
+
+/* Change the size of an allocated block of memory P to an array of N
+   objects each of S bytes, with error checking.  S must be nonzero.  */
+
+static inline void *
+xnrealloc (void *p, size_t n, size_t s)
+{
+  if (xalloc_oversized (n, s))
+    xalloc_die ();
+  return xrealloc (p, n * s);
+}
+
+/* If P is null, allocate a block of at least *PN such objects;
+   otherwise, reallocate P so that it contains more than *PN objects
+   each of S bytes.  *PN must be nonzero unless P is null, and S must
+   be nonzero.  Set *PN to the new number of objects, and return the
+   pointer to the new block.  *PN is never set to zero, and the
+   returned pointer is never null.
+
+   Repeated reallocations are guaranteed to make progress, either by
+   allocating an initial block with a nonzero size, or by allocating a
+   larger block.
+
+   In the following implementation, nonzero sizes are doubled so that
+   repeated reallocations have O(N log N) overall cost rather than
+   O(N**2) cost, but the specification for this function does not
+   guarantee that sizes are doubled.
+
+   Here is an example of use:
+
+     int *p = NULL;
+     size_t used = 0;
+     size_t allocated = 0;
+
+     void
+     append_int (int value)
+       {
+	 if (used == allocated)
+	   p = x2nrealloc (p, &allocated, sizeof *p);
+	 p[used++] = value;
+       }
+
+   This causes x2nrealloc to allocate a block of some nonzero size the
+   first time it is called.
+
+   To have finer-grained control over the initial size, set *PN to a
+   nonzero value before calling this function with P == NULL.  For
+   example:
+
+     int *p = NULL;
+     size_t used = 0;
+     size_t allocated = 0;
+     size_t allocated1 = 1000;
+
+     void
+     append_int (int value)
+       {
+	 if (used == allocated)
+	   {
+	     p = x2nrealloc (p, &allocated1, sizeof *p);
+	     allocated = allocated1;
+	   }
+	 p[used++] = value;
+       }
+
+   */
+
+static inline void *
+x2nrealloc (void *p, size_t *pn, size_t s)
+{
+  size_t n = *pn;
+
+  if (! p)
+    {
+      if (! n)
+	{
+	  /* The approximate size to use for initial small allocation
+	     requests, when the invoking code specifies an old size of
+	     zero.  64 bytes is the largest "small" request for the
+	     GNU C library malloc.  */
+	  enum { DEFAULT_MXFAST = 64 };
+
+	  n = DEFAULT_MXFAST / s;
+	  n += !n;
+	}
+    }
+  else
+    {
+      if (((size_t) -1) / 2 / s < n)
+	xalloc_die ();
+      n *= 2;
+    }
+
+  *pn = n;
+  return xrealloc (p, n * s);
+}
+
 /* In the following macros, T must be an elementary or structure/union or
    typedef'ed type, or a pointer to such a type.  To apply one of the
    following macros to a function pointer or array type, you need to typedef
    it first and use the typedef name.  */
 
 /* Allocate an object of type T dynamically, with error checking.  */
-/* extern T *XMALLOC (typename T); */
-#define XMALLOC(T) \
-  ((T *) xmalloc (sizeof (T)))
+/* extern t *XMALLOC (typename t); */
+#define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
 
-/* Allocate memory for NMEMB elements of type T, with error checking.  */
-/* extern T *XNMALLOC (size_t nmemb, typename T); */
-#if HAVE_INLINE
-/* xnmalloc performs a division and multiplication by sizeof (T).  Arrange to
-   perform the division at compile-time and the multiplication with a factor
-   known at compile-time.  */
-# define XNMALLOC(N,T) \
-   ((T *) (sizeof (T) == 1 \
-	   ? xmalloc (N) \
-	   : xnboundedmalloc(N, (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / sizeof (T), sizeof (T))))
-static inline void *
-xnboundedmalloc (size_t n, size_t bound, size_t s)
-{
-  if (n > bound)
-    xalloc_die ();
-  return xmalloc (n * s);
-}
-#else
-# define XNMALLOC(N,T) \
-   ((T *) (sizeof (T) == 1 ? xmalloc (N) : xnmalloc (N, sizeof (T))))
-#endif
+/* Allocate memory for N elements of type T, with error checking.  */
+/* extern t *XNMALLOC (size_t n, typename t); */
+#define XNMALLOC(n, t) ((t *) xnmalloc (n, sizeof (t)))
 
 /* Allocate an object of type T dynamically, with error checking,
    and zero it.  */
-/* extern T *XZALLOC (typename T); */
-#define XZALLOC(T) \
-  ((T *) xzalloc (sizeof (T)))
+/* extern t *XZALLOC (typename t); */
+#define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
 
-/* Allocate memory for NMEMB elements of type T, with error checking,
+/* Allocate memory for N elements of type T, with error checking,
    and zero it.  */
-/* extern T *XCALLOC (size_t nmemb, typename T); */
-#define XCALLOC(N,T) \
-  ((T *) xcalloc (N, sizeof (T)))
+/* extern t *XCALLOC (size_t n, typename t); */
+#define XCALLOC(n, t) ((t *) xcalloc (n, sizeof (t)))
 
 /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
-   except it returns char *.
-   xcharalloc (N) is equivalent to XNMALLOC (N, char).  */
+   except it returns char *.  */
 static inline char *
 xcharalloc (size_t n)
 {
-  return (char *) xmalloc (n);
+  return XNMALLOC (n, char);
 }
 
 # ifdef __cplusplus
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -38,148 +38,27 @@
 enum { HAVE_GNU_CALLOC = 0 };
 #endif
 
-/* Allocate an array of N objects, each with S bytes of memory,
-   dynamically, with error checking.  S must be nonzero.  */
-
-static inline void *
-xnmalloc_inline (size_t n, size_t s)
-{
-  void *p;
-  if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
-    xalloc_die ();
-  return p;
-}
-
-void *
-xnmalloc (size_t n, size_t s)
-{
-  return xnmalloc_inline (n, s);
-}
-
 /* Allocate N bytes of memory dynamically, with error checking.  */
 
 void *
 xmalloc (size_t n)
 {
-  return xnmalloc_inline (n, 1);
-}
-
-/* Change the size of an allocated block of memory P to an array of N
-   objects each of S bytes, with error checking.  S must be nonzero.  */
-
-static inline void *
-xnrealloc_inline (void *p, size_t n, size_t s)
-{
-  if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
+  void *p = malloc (n);
+  if (!p && n != 0)
     xalloc_die ();
   return p;
 }
 
-void *
-xnrealloc (void *p, size_t n, size_t s)
-{
-  return xnrealloc_inline (p, n, s);
-}
-
 /* Change the size of an allocated block of memory P to N bytes,
    with error checking.  */
 
 void *
 xrealloc (void *p, size_t n)
 {
-  return xnrealloc_inline (p, n, 1);
-}
-
-
-/* If P is null, allocate a block of at least *PN such objects;
-   otherwise, reallocate P so that it contains more than *PN objects
-   each of S bytes.  *PN must be nonzero unless P is null, and S must
-   be nonzero.  Set *PN to the new number of objects, and return the
-   pointer to the new block.  *PN is never set to zero, and the
-   returned pointer is never null.
-
-   Repeated reallocations are guaranteed to make progress, either by
-   allocating an initial block with a nonzero size, or by allocating a
-   larger block.
-
-   In the following implementation, nonzero sizes are doubled so that
-   repeated reallocations have O(N log N) overall cost rather than
-   O(N**2) cost, but the specification for this function does not
-   guarantee that sizes are doubled.
-
-   Here is an example of use:
-
-     int *p = NULL;
-     size_t used = 0;
-     size_t allocated = 0;
-
-     void
-     append_int (int value)
-       {
-	 if (used == allocated)
-	   p = x2nrealloc (p, &allocated, sizeof *p);
-	 p[used++] = value;
-       }
-
-   This causes x2nrealloc to allocate a block of some nonzero size the
-   first time it is called.
-
-   To have finer-grained control over the initial size, set *PN to a
-   nonzero value before calling this function with P == NULL.  For
-   example:
-
-     int *p = NULL;
-     size_t used = 0;
-     size_t allocated = 0;
-     size_t allocated1 = 1000;
-
-     void
-     append_int (int value)
-       {
-	 if (used == allocated)
-	   {
-	     p = x2nrealloc (p, &allocated1, sizeof *p);
-	     allocated = allocated1;
-	   }
-	 p[used++] = value;
-       }
-
-   */
-
-static inline void *
-x2nrealloc_inline (void *p, size_t *pn, size_t s)
-{
-  size_t n = *pn;
-
-  if (! p)
-    {
-      if (! n)
-	{
-	  /* The approximate size to use for initial small allocation
-	     requests, when the invoking code specifies an old size of
-	     zero.  64 bytes is the largest "small" request for the
-	     GNU C library malloc.  */
-	  enum { DEFAULT_MXFAST = 64 };
-
-	  n = DEFAULT_MXFAST / s;
-	  n += !n;
-	}
-    }
-  else
-    {
-      if (SIZE_MAX / 2 / s < n)
-	xalloc_die ();
-      n *= 2;
-    }
-
-  *pn = n;
-  return xrealloc (p, n * s);
-}
-
-void *
-x2nrealloc (void *p, size_t *pn, size_t s)
-{
-  return x2nrealloc_inline (p, pn, s);
+  p = realloc (p, n);
+  if (!p && n != 0)
+    xalloc_die ();
+  return p;
 }
 
 /* If P is null, allocate a block of at least *PN bytes; otherwise,
@@ -191,7 +70,7 @@
 void *
 x2realloc (void *p, size_t *pn)
 {
-  return x2nrealloc_inline (p, pn, 1);
+  return x2nrealloc (p, pn, 1);
 }
 
 /* Allocate S bytes of zeroed memory dynamically, with error checking.