[Fwd: Unreviewed patch]

Laurynas Biveinis lauras@softhome.net
Fri Oct 27 06:47:00 GMT 2000


DJ Delorie wrote:
> Could you send it to gcc-patches@gcc.gnu.org also?

OK. Yes, it took about one and a half month, but now I have A Real Os
in my sandbox, so I could regenerate files properly and test it better.

This patch moves page-aligned memory allocation to liberty and adopts
GC to use it. Also it allows to use plain malloc() for page-aligned memory
allocation, which enables ggc-page on platforms w/o mmap() or valloc().
This patch fixes one of biggest showstoppers on DJGPP - ggc-simple is too
slow to compile anything useful.

Bootstrapped on i686-pc-linux-gnu, tested, no regressions, no animals were
harmed during creation of this patch.

Laurynas

include/ChangeLog:
2000-06-18 Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
           Laurynas Biveinis <lauras@softhome.net>
        
        * libiberty.h (xvalloc, xvfree, xvalloc_overhead): Declare.

libiberty/ChangeLog:
2000-06-18 Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
           Laurynas Biveinis <lauras@softhome.net>
        
        * xvalloc.c: New file.
        * Makefile.in (CFILES): Added xvalloc.c.
        (REQUIRED_OFILES): Added xvalloc.o.
        (xvalloc.o): List dependencies.
        * configure.in: Auto-detect fcntl.h, sys/mman.h, MMAP_ANYWHERE and
        valloc.
        * configure, config.in: Rebuilt.

gcc/ChangeLog:
2000-06-18 Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
           Laurynas Biveinis <lauras@softhome.net>
        
        * configure.in: No longer check for valloc.  Always use ggc-page.
        * configure, config.in: Rebuilt.
        * Makefile.in (ggc-page.o): Depend on libiberty.h
        * ggc-page.c (alloc_page): Use xvalloc from libiberty.
        (release_pages): Use xvfree.
        (struct globals): New member usable_pagesize.
        (init_ggc): Compute it with xvalloc_overhead from libiberty.
        (OBJECTS_PER_PAGE): Use it.
        (MISALIGNMENT): New macro.
        (clear_marks): Use it.
        (alloc_anon): Deleted.
Index: gcc/gcc/Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.529
diff -u -r1.529 Makefile.in
--- Makefile.in	2000/10/26 07:28:23	1.529
+++ Makefile.in	2000/10/27 12:58:10
@@ -1235,7 +1235,7 @@
 	$(GGC_H) varray.h $(TIMEVAR_H)
 
 ggc-page.o: ggc-page.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h toplev.h \
-	$(GGC_H) varray.h $(TIMEVAR_H)
+	$(GGC_H) varray.h $(TIMEVAR_H) $(srcdir)/../include/libiberty.h
 
 ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_H) $(GGC_H)
 
Index: gcc/gcc/config.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config.in,v
retrieving revision 1.86
diff -u -r1.86 config.in
--- config.in	2000/09/21 05:30:35	1.86
+++ config.in	2000/10/27 12:58:10
@@ -219,9 +219,6 @@
 /* Define if you have the sysconf function.  */
 #undef HAVE_SYSCONF
 
-/* Define if you have the valloc function.  */
-#undef HAVE_VALLOC
-
 /* Define if you have the <argz.h> header file.  */
 #undef HAVE_ARGZ_H
 
Index: gcc/gcc/configure
===================================================================
RCS file: /cvs/gcc/egcs/gcc/configure,v
retrieving revision 1.442
diff -u -r1.442 configure
--- configure	2000/10/26 07:28:23	1.442
+++ configure	2000/10/27 12:58:30
@@ -1545,7 +1545,7 @@
 #include "confdefs.h"
 
 int main() {
-} $ac_kw foo() {
+} int $ac_kw foo() {
 ; return 0; }
 EOF
 if { (eval echo configure:1552: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
@@ -1575,7 +1575,7 @@
 
 
 # Find some useful tools
-for ac_prog in gawk mawk nawk awk
+for ac_prog in mawk gawk nawk awk
 do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
@@ -2552,7 +2552,7 @@
 for ac_func in strtoul bsearch putenv popen bcopy bzero bcmp \
 	index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
 	sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
-	fputs_unlocked getrusage valloc iconv nl_langinfo
+	fputs_unlocked getrusage iconv nl_langinfo
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 echo "configure:2559: checking for $ac_func" >&5
@@ -7255,7 +7255,7 @@
 int main() {
 
 /* Ultrix mips cc rejects this.  */
-typedef int charset[2]; const charset x;
+typedef int charset[2]; const charset x = {0,0};
 /* SunOS 4.1.1 cc rejects this.  */
 char const *const *ccp;
 char **p;
@@ -7396,7 +7396,7 @@
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
-char *p = alloca(2 * sizeof(int));
+void *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
 if { (eval echo configure:7403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
@@ -9468,14 +9468,9 @@
     ;;
 esac
 else
-  if test $ac_cv_func_mmap_anywhere = yes \
-    || test $ac_cv_func_valloc = yes; then
   GGC=ggc-page
-else
-  GGC=ggc-simple
-fi
 fi
-
+
 
 echo "Using $GGC for garbage collection."
 
@@ -9510,7 +9505,7 @@
 
 # Build a new-libstdc++ system (ie libstdc++-v3)
 echo $ac_n "checking for libstdc++ to install""... $ac_c" 1>&6
-echo "configure:9514: checking for libstdc++ to install" >&5
+echo "configure:9509: checking for libstdc++ to install" >&5
 # Check whether --enable-libstdcxx-v3 or --disable-libstdcxx-v3 was given.
 if test "${enable_libstdcxx_v3+set}" = set; then
   enableval="$enable_libstdcxx_v3"
@@ -9537,7 +9532,7 @@
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:9541: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:9536: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
Index: gcc/gcc/configure.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/configure.in,v
retrieving revision 1.438
diff -u -r1.438 configure.in
--- configure.in	2000/10/26 07:28:24	1.438
+++ configure.in	2000/10/27 12:58:43
@@ -506,7 +506,7 @@
 AC_CHECK_FUNCS(strtoul bsearch putenv popen bcopy bzero bcmp \
 	index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
 	sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
-	fputs_unlocked getrusage valloc iconv nl_langinfo)
+	fputs_unlocked getrusage iconv nl_langinfo)
 
 AC_CHECK_TYPE(ssize_t, int)
 
@@ -4864,13 +4864,7 @@
   *)
     AC_MSG_ERROR([$withval is an invalid option to --with-gc])
     ;;
-esac],
-[if test $ac_cv_func_mmap_anywhere = yes \
-    || test $ac_cv_func_valloc = yes; then
-  GGC=ggc-page
-else
-  GGC=ggc-simple
-fi])
+esac], [GGC=ggc-page])
 AC_SUBST(GGC)
 echo "Using $GGC for garbage collection."
 
Index: gcc/gcc/ggc-page.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ggc-page.c,v
retrieving revision 1.30
diff -u -r1.30 ggc-page.c
--- ggc-page.c	2000/08/29 20:57:11	1.30
+++ ggc-page.c	2000/10/27 12:58:47
@@ -29,18 +29,6 @@
 #include "ggc.h"
 #include "timevar.h"
 
-#ifdef HAVE_MMAP_ANYWHERE
-#include <sys/mman.h>
-#endif
-
-#ifndef MAP_FAILED
-#define MAP_FAILED -1
-#endif
-
-#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
 /* Stategy: 
 
    This garbage-collecting allocator allocates objects on one of a set
@@ -215,6 +203,10 @@
   size_t pagesize;
   size_t lg_pagesize;
 
+  /* The system's page size minus any overheads of the page allocation
+     system.  */
+  size_t usable_pagesize;
+
   /* Bytes currently allocated.  */
   size_t allocated;
 
@@ -227,11 +219,6 @@
   /* The current depth in the context stack.  */
   unsigned short context_depth;
 
-  /* A file descriptor open to /dev/zero for reading.  */
-#if defined (HAVE_MMAP_ANYWHERE) && !defined(MAP_ANONYMOUS)
-  int dev_zero_fd;
-#endif
-
   /* A cache of free system pages.  */
   page_entry *free_pages;
 
@@ -247,7 +234,8 @@
 /* The number of objects per allocation page, for objects of size
    2^ORDER.  */
 #define OBJECTS_PER_PAGE(Order) \
-  ((Order) >= G.lg_pagesize ? 1 : G.pagesize / ((size_t)1 << (Order)))
+  ((Order) >= G.lg_pagesize ? 1 \
+   : ((G.usable_pagesize) / ((size_t)1 << (Order))))
 
 /* The size in bytes required to maintain a bitmap for the objects
    on a page-entry.  */
@@ -264,15 +252,14 @@
    test from triggering too often when the heap is small.  */
 #define GGC_MIN_LAST_ALLOCATED (4 * 1024 * 1024)
 
-/* Allocate pages in chunks of this size, to throttle calls to mmap.
-   The first page is used, the rest go onto the free list.  */
-#define GGC_QUIRE_SIZE 16
+/* Test the misalignment of an address.  */
+#define MISALIGNMENT(Address) \
+  (((size_t)(Address)) & (G.pagesize - 1))
 
 
 static int ggc_allocated_p PARAMS ((const void *));
 static page_entry *lookup_page_table_entry PARAMS ((const void *));
 static void set_page_table_entry PARAMS ((void *, page_entry *));
-static char *alloc_anon PARAMS ((char *, size_t));
 static struct page_entry * alloc_page PARAMS ((unsigned));
 static void free_page PARAMS ((struct page_entry *));
 static void release_pages PARAMS ((void));
@@ -403,45 +390,6 @@
   fflush (stdout);
 }
 
-/* Allocate SIZE bytes of anonymous memory, preferably near PREF,
-   (if non-null).  */
-
-static inline char *
-alloc_anon (pref, size)
-     char *pref ATTRIBUTE_UNUSED;
-     size_t size;
-{
-  char *page;
-
-#ifdef HAVE_MMAP_ANYWHERE
-#ifdef MAP_ANONYMOUS
-  page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#else
-  page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-			MAP_PRIVATE, G.dev_zero_fd, 0);
-#endif
-  if (page == (char *) MAP_FAILED)
-    {
-      fputs ("Virtual memory exhausted!\n", stderr);
-      exit(1);
-    }
-#else
-#ifdef HAVE_VALLOC
-  page = (char *) valloc (size);
-  if (!page)
-    {
-      fputs ("Virtual memory exhausted!\n", stderr);
-      exit(1);
-    }
-#endif /* HAVE_VALLOC */
-#endif /* HAVE_MMAP_ANYWHERE */
-
-  /* Remember that we allocated this memory.  */
-  G.bytes_mapped += size;
-
-  return page;
-}
 
 /* Allocate a new page for allocating objects of size 2^ORDER,
    and return an entry for it.  The entry is not added to the
@@ -485,31 +433,14 @@
       else
 	free (p);
     }
-#ifdef HAVE_MMAP_ANYWHERE
-  else if (entry_size == G.pagesize)
+  else
     {
-      /* We want just one page.  Allocate a bunch of them and put the
-	 extras on the freelist.  (Can only do this optimization with
-	 mmap for backing store.)  */
-      struct page_entry *e, *f = G.free_pages;
-      int i;
-
-      page = alloc_anon (NULL, entry_size * GGC_QUIRE_SIZE);
-      /* This loop counts down so that the chain will be in ascending
-	 memory order.  */
-      for (i = GGC_QUIRE_SIZE - 1; i >= 1; i--)
-	{
-	  e = (struct page_entry *) xcalloc (1, sizeof (struct page_entry));
-	  e->bytes = entry_size;
-	  e->page = page + i*entry_size;
-	  e->next = f;
-	  f = e;
-	}
-      G.free_pages = f;
+      /* Actually allocate the memory.  */
+      page = xvalloc (entry_size);
+
+      /* Remember that we actually allocated this memory.  */
+      G.bytes_mapped += entry_size;
     }
-#endif
-  else
-    page = alloc_anon (NULL, entry_size);
 
   if (entry == NULL)
     entry = (struct page_entry *) xcalloc (1, page_entry_size);
@@ -560,46 +491,16 @@
 {
   page_entry *p, *next;
 
-#ifdef HAVE_MMAP_ANYWHERE
-  char *start;
-  size_t len;
-
-  /* Gather up adjacent pages so they are unmapped together.  */
-  p = G.free_pages;
-
-  while (p)
+  for (p = G.free_pages; p ; p = next)
     {
-      start = p->page;
       next = p->next;
-      len = p->bytes;
-      free (p);
-      p = next;
-
-      while (p && p->page == start + len)
-	{
-	  next = p->next;
-	  len += p->bytes;
-	  free (p);
-	  p = next;
-	}
-
-      munmap (start, len);
-      G.bytes_mapped -= len;
-    }
-#else
-#ifdef HAVE_VALLOC
-
-  for (p = G.free_pages; p; p = next)
-    {
-      next = p->next;
-      free (p->page);
+      xvfree (p->page, p->bytes);
       G.bytes_mapped -= p->bytes;
       free (p);
     }
-#endif /* HAVE_VALLOC */
-#endif /* HAVE_MMAP_ANYWHERE */
 
   G.free_pages = NULL;
+
 }
 
 /* This table provides a fast way to determine ceil(log_2(size)) for
@@ -772,6 +673,8 @@
   entry->in_use_p[word] |= mask;
   entry->num_free_objects -= 1;
 
+  G.allocated += (size_t) 1 << entry->order;
+
   if (GGC_DEBUG_LEVEL >= 4)
     fprintf (G.debug_file, "Marking %p\n", p);
 
@@ -798,48 +701,24 @@
   return 1 << pe->order;
 }
 
-/* Initialize the ggc-mmap allocator.  */
+/* Initialize the ggc-page allocator.  */
 
 void
 init_ggc ()
 {
   G.pagesize = getpagesize();
   G.lg_pagesize = exact_log2 (G.pagesize);
+  G.usable_pagesize = G.pagesize - xvalloc_overhead();
 
-#if defined (HAVE_MMAP_ANYWHERE) && !defined(MAP_ANONYMOUS)
-  G.dev_zero_fd = open ("/dev/zero", O_RDONLY);
-  if (G.dev_zero_fd == -1)
-    abort ();
-#endif
 
 #if 0
-  G.debug_file = fopen ("ggc-mmap.debug", "w");
+  G.debug_file = fopen ("ggc-page.debug", "w");
 #else
   G.debug_file = stdout;
 #endif
 
   G.allocated_last_gc = GGC_MIN_LAST_ALLOCATED;
 
-#ifdef HAVE_MMAP_ANYWHERE
-  /* StunOS has an amazing off-by-one error for the first mmap allocation
-     after fiddling with RLIMIT_STACK.  The result, as hard as it is to
-     believe, is an unaligned page allocation, which would cause us to
-     hork badly if we tried to use it.  */
-  {
-    char *p = alloc_anon (NULL, G.pagesize);
-    if ((size_t)p & (G.pagesize - 1))
-      {
-	/* How losing.  Discard this one and try another.  If we still
-	   can't get something useful, give up.  */
-
-	p = alloc_anon (NULL, G.pagesize);
-	if ((size_t)p & (G.pagesize - 1))
-	  abort ();
-      }
-    munmap (p, G.pagesize);
-  }
-#endif
-
   empty_string = ggc_alloc_string ("", 0);
   ggc_add_string_root (&empty_string, 1);
 }
@@ -946,7 +825,7 @@
 	{
 #ifdef ENABLE_CHECKING
 	  /* The data should be page-aligned.  */
-	  if ((size_t) p->page & (G.pagesize - 1))
+	  if (MISALIGNMENT(p->page))
 	    abort ();
 #endif
 
@@ -987,7 +866,6 @@
       page_entry * const last = G.page_tails[order];
 
       size_t num_objects = OBJECTS_PER_PAGE (order);
-      size_t live_objects;
       page_entry *p, *previous;
       int done;
 	
@@ -1003,19 +881,13 @@
 	  /* Loop until all entries have been examined.  */
 	  done = (p == last);
 
-	  /* Add all live objects on this page to the count of
-             allocated memory.  */
-	  live_objects = num_objects - p->num_free_objects;
-
-	  G.allocated += ((size_t) 1 << order) * live_objects;
-
 	  /* Only objects on pages in the topmost context should get
 	     collected.  */
 	  if (p->context_depth < G.context_depth)
 	    ;
 
 	  /* Remove the page if it's empty.  */
-	  else if (live_objects == 0)
+	  else if (p->num_free_objects == num_objects)
 	    {
 	      if (! previous)
 		G.pages[order] = next;
@@ -1134,8 +1006,8 @@
   if (!quiet_flag)
     fprintf (stderr, " {GC %luk -> ", (unsigned long) G.allocated / 1024);
 
-  /* Zero the total allocated bytes.  This will be recalculated in the
-     sweep phase.  */
+  /* Zero the total allocated bytes.  We'll reaccumulate this while
+     marking.  */
   G.allocated = 0;
 
   /* Release the pages we freed the last time we collected, but didn't 
Index: gcc/include/libiberty.h
===================================================================
RCS file: /cvs/gcc/egcs/include/libiberty.h,v
retrieving revision 1.13
diff -u -r1.13 libiberty.h
--- libiberty.h	2000/08/24 20:28:15	1.13
+++ libiberty.h	2000/10/27 12:59:02
@@ -161,6 +161,22 @@
 
 extern PTR xmemdup PARAMS ((const PTR, size_t, size_t)) ATTRIBUTE_MALLOC;
 
+/* Allocate a page-aligned memory block.  */
+
+extern char *xvalloc PARAMS ((size_t)) ATTRIBUTE_MALLOC;
+
+/* Release memory allocated by xvalloc.  */
+
+extern void xvfree PARAMS ((char *, size_t));
+
+/* Initialize xvalloc internal structures.  It's optional, but it's
+   best to call it before any memory allocation takes place.  It can
+   be called multiple times, returning how many bytes should be left
+   at the end of a page for memory-allocation data structures, so as
+   to avoid wasting every other page.  This value should be subtracted
+   from getpagesize() in the argument to xvalloc/xvfree. */
+extern unsigned xvalloc_overhead PARAMS ((void));
+
 /* hex character manipulation routines */
 
 #define _hex_array_size 256
Index: gcc/libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/Makefile.in,v
retrieving revision 1.54
diff -u -r1.54 Makefile.in
--- Makefile.in	2000/08/29 04:35:59	1.54
+++ Makefile.in	2000/10/27 12:59:11
@@ -135,7 +135,7 @@
 	strchr.c strdup.c strerror.c strncmp.c strrchr.c strsignal.c strstr.c \
 	strtod.c strtol.c strtoul.c tmpnam.c vasprintf.c vfork.c vfprintf.c   \
 	vprintf.c vsprintf.c waitpid.c xatexit.c xexit.c xmalloc.c	      \
-	xmemdup.c xstrdup.c xstrerror.c
+	xmemdup.c xstrdup.c xstrerror.c xvalloc.c
 
 # These are always included in the library.
 REQUIRED_OFILES = argv.o choose-temp.o concat.o cplus-dem.o cp-demangle.o \
@@ -143,7 +143,7 @@
 	getruntime.o hashtab.o hex.o floatformat.o md5.o objalloc.o obstack.o \
 	partition.o pexecute.o sort.o spaces.o splay-tree.o strerror.o	  \
 	strsignal.o xatexit.o xexit.o xmalloc.o xmemdup.o xstrdup.o	  \
-	xstrerror.o
+	xstrerror.o xvalloc.o
 
 $(TARGETLIB): $(REQUIRED_OFILES) $(EXTRA_OFILES) $(LIBOBJS) $(ALLOCA)
 	rm -f $(TARGETLIB)
@@ -297,5 +297,6 @@
 xmemdup.o: config.h $(INCDIR)/libiberty.h
 xstrdup.o: config.h $(INCDIR)/libiberty.h
 xstrerror.o: config.h $(INCDIR)/libiberty.h
+xvalloc.o: config.h $(INCDIR)/libiberty.h
 waitpid.o: config.h
 hashtab.o: config.h $(INCDIR)/libiberty.h $(INCDIR)/hashtab.h $(INCDIR)/ansidecl.h
Index: gcc/libiberty/config.in
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/config.in,v
retrieving revision 1.13
diff -u -r1.13 config.in
--- config.in	2000/07/23 19:18:32	1.13
+++ config.in	2000/10/27 12:59:11
@@ -187,6 +187,9 @@
 /* Define if you have the tmpnam function.  */
 #undef HAVE_TMPNAM
 
+/* Define if you have the valloc function.  */
+#undef HAVE_VALLOC
+
 /* Define if you have the vasprintf function.  */
 #undef HAVE_VASPRINTF
 
@@ -243,4 +246,7 @@
 
 /* Define if errno must be declared even when <errno.h> is included. */
 #undef NEED_DECLARATION_ERRNO
+
+/* Define if mmap can get us zeroed pages from /dev/zero. */
+#undef HAVE_MMAP_ANYWHERE
 
Index: gcc/libiberty/configure
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/configure,v
retrieving revision 1.26
diff -u -r1.26 configure
--- configure	2000/09/05 18:43:26	1.26
+++ configure	2000/10/27 12:59:17
@@ -1822,7 +1822,7 @@
   # We haven't set the list of objects yet.  Use the standard autoconf
   # tests.  This will only work if the compiler works.
   echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1821: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1826: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1833,12 +1833,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 1832 "configure"
+#line 1837 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1842: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1864,19 +1864,19 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1863: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1868: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
   for ac_func in $funcs
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1870: checking for $ac_func" >&5
+echo "configure:1875: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1875 "configure"
+#line 1880 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1899,7 +1899,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1898: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1946,19 +1946,19 @@
     # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:1945: checking for working alloca.h" >&5
+echo "configure:1950: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1950 "configure"
+#line 1955 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
-char *p = alloca(2 * sizeof(int));
+void *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:1957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -1979,12 +1979,12 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:1978: checking for alloca" >&5
+echo "configure:1983: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1983 "configure"
+#line 1988 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -2012,7 +2012,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:2011: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -2044,12 +2044,12 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2043: checking whether alloca needs Cray hooks" >&5
+echo "configure:2048: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2048 "configure"
+#line 2053 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -2074,12 +2074,12 @@
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2073: checking for $ac_func" >&5
+echo "configure:2078: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2078 "configure"
+#line 2083 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2102,7 +2102,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2129,7 +2129,7 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2128: checking stack direction for C alloca" >&5
+echo "configure:2133: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2137,7 +2137,7 @@
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2136 "configure"
+#line 2141 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -2156,7 +2156,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:2155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -2181,12 +2181,12 @@
   esac
 
   echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2180: checking for ANSI C header files" >&5
+echo "configure:2185: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2185 "configure"
+#line 2190 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2194,7 +2194,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2193: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2198: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2211,7 +2211,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2210 "configure"
+#line 2215 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2229,7 +2229,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2228 "configure"
+#line 2233 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2250,7 +2250,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2249 "configure"
+#line 2254 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2261,7 +2261,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2285,12 +2285,12 @@
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2284: checking for pid_t" >&5
+echo "configure:2289: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2289 "configure"
+#line 2294 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2319,17 +2319,17 @@
 
 ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2318: checking for vfork.h" >&5
+echo "configure:2323: checking for vfork.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2323 "configure"
+#line 2328 "configure"
 #include "confdefs.h"
 #include <vfork.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2328: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2333: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2354,18 +2354,18 @@
 fi
 
 echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2353: checking for working vfork" >&5
+echo "configure:2358: checking for working vfork" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
   echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:2359: checking for vfork" >&5
+echo "configure:2364: checking for vfork" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2364 "configure"
+#line 2369 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vfork(); below.  */
@@ -2388,7 +2388,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vfork=yes"
 else
@@ -2410,7 +2410,7 @@
 ac_cv_func_vfork_works=$ac_cv_func_vfork
 else
   cat > conftest.$ac_ext <<EOF
-#line 2409 "configure"
+#line 2414 "configure"
 #include "confdefs.h"
 /* Thanks to Paul Eggert for this test.  */
 #include <stdio.h>
@@ -2505,7 +2505,7 @@
   }
 }
 EOF
-if { (eval echo configure:2504: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_vfork_works=yes
 else
@@ -2532,19 +2532,19 @@
   fi
   for v in $vars; do
     echo $ac_n "checking for $v""... $ac_c" 1>&6
-echo "configure:2531: checking for $v" >&5
+echo "configure:2536: checking for $v" >&5
     if eval "test \"`echo '$''{'libiberty_cv_var_$v'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2536 "configure"
+#line 2541 "configure"
 #include "confdefs.h"
 int *p;
 int main() {
 extern int $v; p = &$v;
 ; return 0; }
 EOF
-if { (eval echo configure:2543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "libiberty_cv_var_$v=yes"
 else
@@ -2570,12 +2570,12 @@
   for ac_func in $checkfuncs
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2569: checking for $ac_func" >&5
+echo "configure:2574: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2574 "configure"
+#line 2579 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2598,7 +2598,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2628,17 +2628,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2627: checking for $ac_hdr" >&5
+echo "configure:2632: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2632 "configure"
+#line 2637 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2637: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2642: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2667,12 +2667,12 @@
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2666: checking for $ac_func" >&5
+echo "configure:2671: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2671 "configure"
+#line 2676 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2695,7 +2695,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2720,7 +2720,7 @@
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:2719: checking for working mmap" >&5
+echo "configure:2724: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2728,7 +2728,7 @@
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 2727 "configure"
+#line 2732 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -2755,12 +2755,15 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/mman.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 
 /* This mess was copied from the GNU getpagesize.h.  */
 #ifndef HAVE_GETPAGESIZE
-# ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-# endif
 
 /* Assume that all systems that can run configure have sys/param.h.  */
 # ifndef HAVE_SYS_PARAM_H
@@ -2815,7 +2818,7 @@
 	/*
 	 * First, make a file with some known garbage in it.
 	 */
-	data = malloc(pagesize);
+	data = (char*)malloc(pagesize);
 	if (!data)
 		exit(1);
 	for (i = 0; i < pagesize; ++i)
@@ -2836,7 +2839,7 @@
 	fd = open("conftestmmap", O_RDWR);
 	if (fd < 0)
 		exit(1);
-	data2 = malloc(2 * pagesize);
+	data2 = (char*)malloc(2 * pagesize);
 	if (!data2)
 		exit(1);
 	data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
@@ -2854,7 +2857,7 @@
 	 */
 	for (i = 0; i < pagesize; ++i)
 		*(data2 + i) = *(data2 + i) + 1;
-	data3 = malloc(pagesize);
+	data3 = (char*)malloc(pagesize);
 	if (!data3)
 		exit(1);
 	if (read(fd, data3, pagesize) != pagesize)
@@ -2868,7 +2871,7 @@
 }
 
 EOF
-if { (eval echo configure:2867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -2892,7 +2895,7 @@
 
 
 echo $ac_n "checking for working strncmp""... $ac_c" 1>&6
-echo "configure:2891: checking for working strncmp" >&5
+echo "configure:2899: checking for working strncmp" >&5
 if eval "test \"`echo '$''{'ac_cv_func_strncmp_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2900,7 +2903,7 @@
   ac_cv_func_strncmp_works=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 2899 "configure"
+#line 2907 "configure"
 #include "confdefs.h"
 
 /* Test by Jim Wilson and Kaveh Ghazi.
@@ -2961,7 +2964,7 @@
 }
 
 EOF
-if { (eval echo configure:2960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2968: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_strncmp_works=yes
 else
@@ -2980,6 +2983,262 @@
 if test $ac_cv_func_strncmp_works = no ; then
   LIBOBJS="$LIBOBJS strncmp.o"
 fi
+
+
+
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2995: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3000 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3005: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3034: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3039 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3062: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap from /dev/zero""... $ac_c" 1>&6
+echo "configure:3087: checking for working mmap from /dev/zero" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_anywhere'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_mmap_anywhere=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3095 "configure"
+#include "confdefs.h"
+
+/* Test by Richard Henderson and Alexandre Oliva.
+   Check whether mmap from /dev/zero works. */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h.  */
+# ifndef HAVE_SYS_PARAM_H
+#  define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  ifdef HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192  /* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int main()
+{
+  char *x;
+  int fd, pg;
+
+  fd = open("/dev/zero", O_RDWR);
+  if (fd < 0)
+    exit(1);
+
+  pg = getpagesize();
+  x = (char*)mmap(0, pg, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+  if (x == (char *) -1)
+    exit(2);
+
+  *(int *)x += 1;
+
+  if (munmap(x, pg) < 0)
+    exit(3);
+
+  exit(0);
+}
+EOF
+if { (eval echo configure:3167: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_func_mmap_anywhere=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_func_mmap_anywhere=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_anywhere" 1>&6
+if test $ac_cv_func_mmap_anywhere = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_MMAP_ANYWHERE 1
+EOF
+
+fi
+
+for ac_func in valloc
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3192: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3197 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
 
 
 # Install a library built with a cross compiler in $(tooldir) rather
Index: gcc/libiberty/configure.in
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/configure.in,v
retrieving revision 1.29
diff -u -r1.29 configure.in
--- configure.in	2000/09/05 18:43:26	1.29
+++ configure.in	2000/10/27 12:59:18
@@ -362,6 +362,89 @@
 
 libiberty_AC_FUNC_STRNCMP
 
+AC_DEFUN([AC_FUNC_MMAP_ANYWHERE],
+[AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_FUNCS(getpagesize)
+AC_CACHE_CHECK(for working mmap from /dev/zero, ac_cv_func_mmap_anywhere,
+[AC_TRY_RUN([
+/* Test by Richard Henderson and Alexandre Oliva.
+   Check whether mmap from /dev/zero works. */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h.  */
+# ifndef HAVE_SYS_PARAM_H
+#  define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  ifdef HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192  /* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int main()
+{
+  char *x;
+  int fd, pg;
+
+  fd = open("/dev/zero", O_RDWR);
+  if (fd < 0)
+    exit(1);
+
+  pg = getpagesize();
+  x = (char*)mmap(0, pg, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+  if (x == (char *) -1)
+    exit(2);
+
+  *(int *)x += 1;
+
+  if (munmap(x, pg) < 0)
+    exit(3);
+
+  exit(0);
+}], ac_cv_func_mmap_anywhere=yes, ac_cv_func_mmap_anywhere=no,
+ac_cv_func_mmap_anywhere=no)])
+if test $ac_cv_func_mmap_anywhere = yes; then
+  AC_DEFINE(HAVE_MMAP_ANYWHERE, 1,
+           [Define if mmap can get us zeroed pages from /dev/zero.])
+fi
+])
+
+AC_FUNC_MMAP_ANYWHERE
+AC_CHECK_FUNCS(valloc)
+
 # Install a library built with a cross compiler in $(tooldir) rather
 # than $(libdir).
 if test -z "${with_cross_host}"; then
 
Index: gcc/libiberty/xvalloc.c
===================================================================
--- /dev/null	Sat Oct 21 14:34:50 2000
+++ xvalloc.c	Thu Oct 26 16:48:55 2000
@@ -0,0 +1,352 @@
+/* page-aligned memory allocation routines.
+   Copyright (C) 1999, 2000 Free Software Foundation
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.  If not, write
+to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libiberty.h>
+
+/* If defined to a positive number and malloc-based page allocation is
+   being used, counters are maintained for each successful allocation
+   using the mechanism that tries to convince malloc to return a
+   page-aligned address (aligned) and the fallback mechanism
+   (fallback).  Their values are printed every MALLOC_ACCOUNT
+   allocations. */
+#if 0
+# define MALLOC_ACCOUNT 16
+#endif
+
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED -1
+#endif
+
+#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/* The system's page size.  */
+static size_t pagesize;
+
+#if defined (MAP_ANONYMOUS) || HAVE_MMAP_ANYWHERE
+
+# define offset 0
+# define overhead 0
+
+# ifndef MAP_ANONYMOUS
+static int dev_zero_fd;
+# endif
+
+#else
+
+#if HAVE_VALLOC
+static int use_valloc;
+#else
+# define use_valloc 0
+#endif
+
+static int always_aligned;
+
+/* This is usually 0, but AIX 4.1.5's malloc, for example, always
+   returns addresses p=16n+8.  This variable is supposed to be used as
+   an offset from the value returned by malloc to the beginning of the
+   page. */
+static size_t offset;
+
+/* This is how much space is used up by malloc internal structures.
+   It's typically 8 or 16 bytes. */
+static size_t overhead;
+#endif
+
+/* Test the misalignment of an address.  */
+#define MISALIGNMENT(Address) \
+  (((size_t)(Address)) & (pagesize - 1))
+
+#if ! defined (MAP_ANONYMOUS) && ! HAVE_MMAP_ANYWHERE
+static void
+xvmalloc_set_pointer (page, other)
+     char *page, *other;
+{
+  /* Set the pointer just before the page boundary to the beginning of
+     the block, so that it can be freed afterwards. */
+  if (! always_aligned && offset)
+    ((char**)page)[-1] = other;
+}
+
+static char *
+xvmalloc_get_pointer (page)
+     char *page;
+{
+  if (always_aligned || ! offset)
+    return page;
+  else
+    return ((char**)page)[-1];
+}
+
+/* Return a page-aligned memory block with as many bytes as requested
+   in the page. */
+static char *
+xvmalloc_fallback (size)
+     size_t size;
+{
+  char *page, *other;
+
+  /* We must not get here, since offset is zero. */
+  if (always_aligned)
+    abort ();
+
+  other = xmalloc(size + pagesize + offset - 1);
+  page = (char *)((size_t)(other + pagesize) & ~(pagesize - 1));
+
+  /* Mark its beginning. */
+  xvmalloc_set_pointer (page, other);
+
+  return page;
+}
+#endif /* ! defined (MAP_ANONYMOUS) && ! HAVE_MMAP_ANYWHERE */
+
+/* Return the number of bytes that should be subtracted from the
+   pagesize in order to avoid wasting every other page. */
+unsigned
+xvalloc_overhead ()
+{
+  if (pagesize)
+    return overhead + offset;
+
+  pagesize = getpagesize();
+
+#if ! defined (MAP_ANONYMOUS) && HAVE_MMAP_ANYWHERE
+  dev_zero_fd = open ("/dev/zero", O_RDONLY);
+  if (dev_zero_fd == -1)
+    abort ();
+#endif
+
+#if defined (MAP_ANONYMOUS) || HAVE_MMAP_ANYWHERE
+  /* StunOS has an amazing off-by-one error for the first mmap allocation
+     after fiddling with RLIMIT_STACK.  The result, as hard as it is to
+     believe, is an unaligned page allocation, which would cause us to
+     hork badly if we tried to use it.  */
+  {
+    char *p = xvalloc (pagesize);
+    if (MISALIGNMENT (p))
+      {
+       /* How losing.  Discard this one and try another.  If we still
+          can't get something useful, give up.  */
+
+       p = xvalloc (pagesize);
+       if (MISALIGNMENT (p))
+         abort ();
+      }
+    xvfree (p, pagesize);
+  }
+#else
+# if HAVE_VALLOC
+  {
+    char *to_free = 0, *p = 0, *q = 0;
+
+    /* If valloc imposes some space overhead, try to leave some bytes
+       at the end of the page, so as not to waste every other page. */
+    for (overhead = 0; overhead < pagesize;
+        overhead = overhead ? 2 * overhead : sizeof (char*))
+      {
+       p = valloc (pagesize - overhead);
+       if (! p)
+         {
+           overhead = pagesize;
+           break;
+         }
+       *(char**)p = to_free;
+
+       q = valloc (pagesize - overhead);
+       if (! q)
+         {
+           overhead = pagesize;
+           break;
+         }
+       *(char**)q = p;
+
+       to_free = q;
+       if (q - p <= pagesize)
+         break;
+      }
+
+    /* Set use_valloc so that xvfree() uses the appropriate free
+       mechanism. */
+    use_valloc = 1;
+    while (to_free)
+      {
+       p = to_free;
+       to_free = *(char**)p;
+
+       /* Note: the second argument is unused when the allocation
+          mechanism is xvalloc. */
+       xvfree (p, 0);
+      }
+
+    /* We'll only use valloc if we can arrange to not waste pages. */
+    use_valloc = (overhead < pagesize);
+  }
+# endif
+  /* If we're not using valloc, let's configure with plain malloc. */
+  if (! use_valloc)
+    {
+      char *to_free = 0, *p = 0, *q = 0;
+
+      /* Find out the memory overhead of a page-sized malloc. */
+      p = xmalloc (pagesize);
+      *(char**)p = to_free;
+      q = xmalloc (pagesize);
+      *(char**)q = p;
+      to_free = q;
+      overhead = q - p - pagesize;
+
+      /* If the overhead is a whole page, odds are that malloc()ing a
+        large block will always return a page-aligned address.  So we
+        do just like in the case of valloc. */
+      if (overhead == pagesize)
+       for (overhead = sizeof (char*); overhead < pagesize; overhead *= 2)
+         {
+           p = xmalloc (pagesize - overhead);
+           *(char**)p = to_free;
+
+           q = xmalloc (pagesize - overhead);
+           *(char**)q = p;
+
+           to_free = q;
+           if (q - p <= pagesize)
+             break;
+         }
+
+      while (to_free)
+       {
+         p = to_free;
+         to_free = *(char**)p;
+         free (p);
+       }
+
+       /* TODO: we do not check how to make malloc() return
+          aligned memory.  If you know a reliable way to do it,
+          please go ahead.  */
+       always_aligned = 0;	
+
+       /* Let's be conservative and revert to the original
+          values. */
+       offset = 0;
+       overhead *= 2;
+
+      /* We'll have to store a pointer to the beginning of the
+        malloc()ed block right before the page boundary.  Reserve
+        space for it. */
+      if (offset < sizeof (char*))
+       offset = sizeof (char*);
+      /* Assume offset has at least the same alignment requirements of
+        the malloc overhead.  We may be wasting some bytes here, but
+        it shouldn't hurt too much. */
+      if (offset < overhead)
+       offset = overhead;
+    }
+#endif /* defined (MAP_ANONYMOUS) || HAVE_MMAP_ANYWHERE */
+
+  return overhead + offset;
+}
+
+/* Return a page-aligned block of memory of length size. */
+char*
+xvalloc(size)
+     size_t size;
+{
+  char *page;
+
+#if HAVE_MMAP_ANYWHERE || defined (MAP_ANONYMOUS)
+# ifdef MAP_ANONYMOUS
+  page = (char *) mmap (0, size, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+# else
+  page = (char *) mmap (0, size, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE, dev_zero_fd, 0);
+# endif
+  if (page == (char *) MAP_FAILED)
+    {
+      fputs ("Virtual memory exhausted!\n", stderr);
+      exit(1);
+    }
+#else
+
+# if HAVE_VALLOC
+  if (use_valloc)
+    {
+      page = (char *) valloc (size);
+      if (!page)
+       {
+         fputs ("Virtual memory exhausted!\n", stderr);
+         exit(1);
+       }
+    }
+# endif
+
+  if (! use_valloc)
+      page = xvmalloc_fallback (size);
+
+#endif /* defined (MAP_ANONYMOUS) || HAVE_MMAP_ANYWHERE */
+
+  return page;
+}
+
+/* Releases the memory block that has previously been returned by
+   xvalloc(size). */
+void
+xvfree(page, size)
+     char *page;
+     size_t size;
+{
+#if defined (MAP_ANONYMOUS) || HAVE_MMAP_ANYWHERE
+  munmap (page, size);
+#else
+# if HAVE_VALLOC
+  /* The docs say we shouldn't be using free() for valloc().  However,
+     no configure test that would fail for such use could be
+     implemented; it just worked.  If a failure situation is ever
+     found, a configure test that AC_DEFINEs HAVE_VALLOC to 0 should
+     be added. */
+  if (use_valloc)
+    free (page);
+# endif
+  if (! use_valloc)
+    free (xvmalloc_get_pointer (page));
+#endif
+}


More information about the Gcc-patches mailing list