diff options
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r-- | gcc/ggc-common.c | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index ecd6624487c..57392388936 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -31,6 +31,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "params.h" #include "hosthooks.h" +#include <unistd.h> /* Required for getpagesize(). */ + #ifdef HAVE_SYS_RESOURCE_H # include <sys/resource.h> #endif @@ -417,6 +419,16 @@ struct mmap_info void *preferred_base; }; +/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS. Return the + alignment required for allocating virtual memory. Usually this is the + same as pagesize. */ + +size_t +default_gt_pch_alloc_granularity (void) +{ + return getpagesize(); +} + /* Write out the state of the compiler to F. */ void @@ -429,7 +441,7 @@ gt_pch_save (FILE *f) char *this_object = NULL; size_t this_object_size = 0; struct mmap_info mmi; - size_t page_size = getpagesize(); + const size_t mmap_offset_alignment = host_hooks.gt_pch_alloc_granularity(); gt_pch_save_stringpool (); @@ -458,7 +470,7 @@ gt_pch_save (FILE *f) and on the rest it's a lot of work to do better. (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and HOST_HOOKS_GT_PCH_USE_ADDRESS.) */ - mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size); + mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (state.f)); #if HAVE_MMAP_FILE if (mmi.preferred_base == NULL) @@ -492,14 +504,15 @@ gt_pch_save (FILE *f) ggc_pch_prepare_write (state.d, state.f); - /* Pad the PCH file so that the mmapped area starts on a page boundary. */ + /* Pad the PCH file so that the mmapped area starts on an allocation + granularity (usually page) boundary. */ { long o; o = ftell (state.f) + sizeof (mmi); if (o == -1) fatal_error ("can't get position in PCH file: %m"); - mmi.offset = page_size - o % page_size; - if (mmi.offset == page_size) + mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment; + if (mmi.offset == mmap_offset_alignment) mmi.offset = 0; mmi.offset += o; } @@ -548,6 +561,7 @@ gt_pch_restore (FILE *f) struct mmap_info mmi; void *addr; bool needs_read; + int result; /* Delete any deletable objects. This makes ggc_pch_read much faster, as it can be sure that no GCable objects remain other @@ -580,28 +594,16 @@ gt_pch_restore (FILE *f) if (fread (&mmi, sizeof (mmi), 1, f) != 1) fatal_error ("can't read PCH file: %m"); - if (host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size)) - { -#if HAVE_MMAP_FILE - void *mmap_result; - - mmap_result = mmap (mmi.preferred_base, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, - fileno (f), mmi.offset); + /* Set the default value of addr. */ + addr = mmi.preferred_base; + result = host_hooks.gt_pch_use_address (addr, mmi.size, fileno(f), + mmi.offset); - /* The file might not be mmap-able. */ - needs_read = mmap_result == (void *) MAP_FAILED; - - /* Sanity check for broken MAP_FIXED. */ - if (! needs_read && mmap_result != mmi.preferred_base) - abort (); -#else - needs_read = true; -#endif - addr = mmi.preferred_base; - } - else + if (result == 0) { + /* Default hook for gt_pch_use_address returns 0. + This if case is used by all targets, and mingw32 + if a failure occurs in gt_pch_use_address. */ #if HAVE_MMAP_FILE addr = mmap (mmi.preferred_base, mmi.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, @@ -613,9 +615,6 @@ gt_pch_restore (FILE *f) size_t page_size = getpagesize(); char one_byte; - if (addr != (void *) 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 @@ -632,25 +631,40 @@ gt_pch_restore (FILE *f) break; if (i >= mmi.size) - addr = mmap (mmi.preferred_base, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, - fileno (f), mmi.offset); + { + if (addr != (void *) MAP_FAILED) + munmap (addr, mmi.size); + + addr = mmap (mmi.preferred_base, mmi.size, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, + fileno (f), mmi.offset); + } } #endif /* HAVE_MINCORE */ needs_read = addr == (void *) MAP_FAILED; #else /* HAVE_MMAP_FILE */ + + /* Mingw32 targets do all the work in gt_pch_use_address. + Should that fail we fallback to using xmalloc to setup + addr and attempt to read the file via needs_read. */ needs_read = true; #endif /* HAVE_MMAP_FILE */ + /* In all probability this will fail, since + addr != mmi.preferred_base. This is a last ditch attempt. */ if (needs_read) addr = xmalloc (mmi.size); } + /* PCH files cannot be relocated. */ + if (result == -1 || addr != mmi.preferred_base) + fatal_error ("had to relocate PCH"); + if (needs_read) { if (fseek (f, mmi.offset, SEEK_SET) != 0 - || fread (&mmi, mmi.size, 1, f) != 1) + || fread (addr, mmi.size, 1, f) != 1) fatal_error ("can't read PCH file: %m"); } else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0) @@ -658,29 +672,6 @@ gt_pch_restore (FILE *f) ggc_pch_read (f, addr); - if (addr != mmi.preferred_base) - { - for (rt = gt_ggc_rtab; *rt; rt++) - for (rti = *rt; rti->base != NULL; rti++) - for (i = 0; i < rti->nelt; i++) - { - char **ptr = (char **)((char *)rti->base + rti->stride * i); - if (*ptr != NULL) - *ptr += (size_t)addr - (size_t)mmi.preferred_base; - } - - for (rt = gt_pch_cache_rtab; *rt; rt++) - for (rti = *rt; rti->base != NULL; rti++) - for (i = 0; i < rti->nelt; i++) - { - char **ptr = (char **)((char *)rti->base + rti->stride * i); - if (*ptr != NULL) - *ptr += (size_t)addr - (size_t)mmi.preferred_base; - } - - sorry ("had to relocate PCH"); - } - gt_pch_restore_stringpool (); } |