diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-08 06:41:28 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-08 06:41:28 +0000 |
commit | 605921ec4952418fb7207475f356c1ac2d8eb081 (patch) | |
tree | 88ecf2cfe1c6969a132fe87f02608ce70f8f7757 /gcc/ggc-common.c | |
parent | d33902461b8428c70087bebd5746ad8c406a8890 (diff) | |
download | gcc-605921ec4952418fb7207475f356c1ac2d8eb081.tar.gz |
PR pch/9830
* ggc-common.c (HAVE_MMAP_FILE): Include sys/types.h
if HAVE_MINCORE is defined.
(MAP_FAILED): Define if not defined.
(gt_pch_save): Test against MAP_FAILED.
(gt_pch_restore): If HAVE_MINCORE, use MAP_FIXED to force
the mapping address to the preferred base after checking it
is possible to do so. Test against MAP_FAILED.
* configure.in: Test for the presence of mincore in libc.
* config.in: Regenerate.
* configure: Regenerate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67614 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r-- | gcc/ggc-common.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 8e5be8ca299..4d1889c41d0 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -36,6 +36,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifdef HAVE_MMAP_FILE # include <sys/mman.h> +# ifdef HAVE_MINCORE +/* This is on Solaris. */ +# include <sys/types.h> +# endif +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) #endif #ifdef ENABLE_VALGRIND_CHECKING @@ -449,7 +457,7 @@ gt_pch_save (FILE *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); @@ -567,10 +575,41 @@ gt_pch_restore (FILE *f) addr = mmap (mmi.preferred_base, mmi.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fileno (f), mmi.offset); -#else - addr = (void *)-1; -#endif - if (addr == (void *)-1) + +#if HAVE_MINCORE + if (addr != mmi.preferred_base) + { + size_t page_size = getpagesize(); + char one_byte; + + 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, by looping over all pages + that would be affected by the fixed mapping. */ + errno = 0; + + for (i = 0; i < mmi.size; i+= page_size) + if (mincore ((char *)mmi.preferred_base + i, page_size, (void *)&one_byte) == -1 + && errno == ENOMEM) + continue; /* The page is not mapped. */ + else + break; + + if (i >= mmi.size) + addr = mmap (mmi.preferred_base, mmi.size, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, + fileno (f), mmi.offset); + } +#endif /* HAVE_MINCORE */ + +#else /* HAVE_MMAP_FILE */ + addr = MAP_FAILED; +#endif /* HAVE_MMAP_FILE */ + if (addr == MAP_FAILED) { addr = xmalloc (mmi.size); if (fseek (f, mmi.offset, SEEK_SET) != 0 |