This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[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

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