This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFT] PCH support on Solaris
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 7 Apr 2003 16:37:40 +0200
- Subject: [RFT] PCH support on Solaris
Hi,
This patch implements the 3-stage heuristics that was proposed in the message
http://gcc.gnu.org/ml/gcc-patches/2003-04/msg00261.html
in order to enable PCH support on Solaris.
It would be nice if people who have access to Solaris boxes could test it:
- apply the patch,
- re-build the compilers with 'make quickstrap' in the objdir/gcc directory,
- run the PCH testsuite with
make -k check RUNTESTFLAGS="dg.exp"
in the objdir directory.
Thanks in advance.
--
Eric Botcazou
2003-04-07 Eric Botcazou <ebotcazou at libertysurf dot fr>
Paolo Bonzini <bonzini at gnu dot org>
Michael Teske <mteske at csksoftware dot com>
Geoff Keating <geoffk at geoffk dot org>
Enable PCH support on Solaris
* ggc-common.c (HAVE_MMAP_FILE): Define USING_MAP_FIXED
if HAVE_MMAP_ANON or HAVE_MMAP_DEV_ZERO is defined.
(toplevel) Define MAP_FAILED and MAP_NORESERVE if needed.
(gt_pch_save): Use MAP_FAILED.
(gt_pch_restore): Shift the base address passed to mmap if the address
returned on the first call is not the preferred address. If USING_MAP_FIXED
is defined, force the base address by passing MAP_FIXED to mmap if the
address returned on the second call is not the preferred address.
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.67
diff -u -p -r1.67 ggc-common.c
--- ggc-common.c 3 Apr 2003 21:00:55 -0000 1.67
+++ ggc-common.c 7 Apr 2003 12:15:54 -0000
@@ -36,6 +36,27 @@ Software Foundation, 59 Temple Place - S
#ifdef HAVE_MMAP_FILE
# include <sys/mman.h>
+
+# ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MAP_FIXED
+# endif
+
+# ifdef HAVE_MMAP_DEV_ZERO
+# define USING_MAP_FIXED
+# endif
+
+#endif
+
+#ifndef MAP_FAILED
+# define MAP_FAILED ((void *)-1)
+#endif
+
+#ifndef MAP_NORESERVE
+# define MAP_NORESERVE 0
#endif
#ifdef ENABLE_VALGRIND_CHECKING
@@ -477,7 +498,7 @@ gt_pch_save (f)
mmi.preferred_base = mmap (NULL, mmi.size,
PROT_READ | PROT_WRITE, MAP_PRIVATE,
fileno (state.f), 0);
- if (mmi.preferred_base == (void *)-1)
+ if (mmi.preferred_base == MAP_FAILED)
mmi.preferred_base = NULL;
else
munmap (mmi.preferred_base, mmi.size);
@@ -560,6 +581,9 @@ gt_pch_restore (f)
size_t i;
struct mmap_info mmi;
void *addr;
+#ifdef HAVE_MMAP_DEV_ZERO
+ int dev_zero_fd;
+#endif
/* Delete any deletable objects. This makes ggc_pch_read much
faster, as it can be sure that no GCable objects remain other
@@ -596,10 +620,71 @@ gt_pch_restore (f)
addr = mmap (mmi.preferred_base, mmi.size,
PROT_READ | PROT_WRITE, MAP_PRIVATE,
fileno (f), mmi.offset);
+
+ if (addr != mmi.preferred_base)
+ {
+ if (addr != MAP_FAILED)
+ munmap (addr, mmi.size);
+
+ /* On some OSes (specifically Solaris), the whole file
+ may be mapped even though we passed a non-zero offset.
+ So work around that by shifting the base address (this
+ trick is sufficient to let all the PCH testcases pass
+ on the sparc-sun-solaris2.9 box I have access to). */
+
+ addr = mmap ((char *)mmi.preferred_base - mmi.offset, mmi.size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ fileno (f), mmi.offset);
+ }
+
+#ifdef USING_MAP_FIXED
+ if (addr != mmi.preferred_base)
+ {
+ if (addr != MAP_FAILED)
+ munmap (addr, mmi.size);
+
+ /* We really want to be mapped at mmi.preferred_base
+ so we're going to resort to MAP_FIXED. But before,
+ make sure that we can do so without destroying a
+ previously mapped area. */
+
+#ifdef HAVE_MMAP_ANON
+ addr = mmap (mmi.preferred_base, mmi.size,
+ PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
+ -1, 0);
+#endif /* HAVE_MMAP_ANON */
+
+#ifdef HAVE_MMAP_DEV_ZERO
+ dev_zero_fd = open ("/dev/zero", O_RDONLY);
+ if (dev_zero_fd == -1)
+ addr = MAP_FAILED;
+ else
+ {
+ addr = mmap (mmi.preferred_base, mmi.size,
+ PROT_NONE,
+ MAP_PRIVATE | MAP_NORESERVE,
+ dev_zero_fd, 0);
+ if (addr != MAP_FAILED)
+ munmap (addr, mmi.size);
+ close (dev_zero_fd);
+ }
+#endif /* HAVE_MMAP_DEV_ZERO */
+
+ if (addr == mmi.preferred_base)
+ addr = mmap (mmi.preferred_base, mmi.size,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED,
+ fileno (f), mmi.offset);
+ else
+ addr = MAP_FAILED;
+ }
+#endif /* USING_MAP_FIXED */
+
#else
- addr = (void *)-1;
-#endif
- if (addr == (void *)-1)
+ addr = MAP_FAILED;
+#endif /* HAVE_MMAP_FILE */
+ if (addr == MAP_FAILED)
{
addr = xmalloc (mmi.size);
if (fseek (f, mmi.offset, SEEK_SET) != 0