diff options
-rw-r--r-- | gcc/ChangeLog | 34 | ||||
-rw-r--r-- | gcc/Makefile.in | 6 | ||||
-rw-r--r-- | gcc/c-common.c | 4 | ||||
-rw-r--r-- | gcc/c-common.h | 5 | ||||
-rw-r--r-- | gcc/c-lex.c | 7 | ||||
-rw-r--r-- | gcc/c-pch.c | 18 | ||||
-rw-r--r-- | gcc/config/rs6000/host-darwin.c | 50 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/doc/hostconfig.texi | 33 | ||||
-rw-r--r-- | gcc/ggc-common.c | 125 | ||||
-rw-r--r-- | gcc/hooks.c | 15 | ||||
-rw-r--r-- | gcc/hooks.h | 2 | ||||
-rw-r--r-- | gcc/hosthooks-def.h | 6 | ||||
-rw-r--r-- | gcc/hosthooks.h | 3 |
15 files changed, 253 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d6887fad18a..b4327db660b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +2003-07-29 Geoffrey Keating <geoffk@apple.com> + + * c-common.c (allow_pch): Remove. + * c-common.h (allow_pch): Remove. + (c_common_no_more_pch): Declare. + * c-lex.c (c_lex): Call c_common_no_more_pch when appropriate. + * c-pch.c: Include hosthooks.h. + (c_common_valid_pch): Don't check allow_pch. + (c_common_read_pch): Clear valid_pch to prevent reading PCH files. + (c_common_no_more_pch): New. + * ggc-common.c: Include hosthooks.h. + (gt_pch_save): Call gt_pch_get_address. + (gt_pch_restore): Call gt_pch_use_address. + * hooks.c (hook_voidp_size_t_null): New. + (hook_bool_voidp_size_t_false): New. + * hooks.h (hook_voidp_size_t_null): New. + (hook_bool_voidp_size_t_false): New. + * hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): New. + (HOST_HOOKS_GT_PCH_USE_ADDRESS): New. + (HOST_HOOKS_INITIALIZER): Add HOST_HOOKS_GT_PCH_GET_ADDRESS, + HOST_HOOKS_GT_PCH_USE_ADDRESS. + * hosthooks.h (struct host_hooks): Add gt_pch_get_address, + gt_pch_use_address. + * doc/hostconfig.texi (Host Common): Document + HOST_HOOKS_GT_PCH_GET_ADDRESS, HOST_HOOKS_GT_PCH_USE_ADDRESS. + * Makefile.in (c-pch.o): Depend on hosthooks.h. + (ggc-common.o): Likewise. + + * config/rs6000/host-darwin.c (HOST_HOOKS_GT_PCH_GET_ADDRESS): Define. + (HOST_HOOKS_GT_PCH_USE_ADDRESS): Define. + (pch_address_space): New. + (darwin_rs6000_gt_pch_get_address): New. + (darwin_rs6000_gt_pch_use_address): New. + 2003-07-29 Neil Booth <neil@daikokuya.co.uk> * Makefile.in (LIBCPP_DEPS): Add HASHTAB_H. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 3754567a8bb..aaf42fcd816 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1351,8 +1351,8 @@ c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(C_TREE_H) tree-dump.h c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \ - $(C_COMMON_H) output.h toplev.h c-pragma.h $(GGC_H) debug.h langhooks.h \ - flags.h + $(C_COMMON_H) output.h toplev.h c-pragma.h $(GGC_H) debug.h \ + langhooks.h flags.h hosthooks.h # Language-independent files. @@ -1433,7 +1433,7 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h ssa.h cselib.h insn-addr.h ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \ - $(HASHTAB_H) toplev.h $(PARAMS_H) + $(HASHTAB_H) toplev.h $(PARAMS_H) hosthooks.h ggc-simple.o: ggc-simple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ flags.h $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) diff --git a/gcc/c-common.c b/gcc/c-common.c index 8dea43bb028..95494a966c9 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -187,10 +187,6 @@ tree c_global_trees[CTI_MAX]; langhook should take care of initialization of this array. */ bool statement_code_p[MAX_TREE_CODES]; - -/* Nonzero if we can read a PCH file now. */ - -int allow_pch = 1; /* Switches common to the C front ends. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index 5d4c3d42d5a..8e54b49e300 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -363,10 +363,6 @@ struct c_lang_decl GTY(()) { heuristics regarding optimization. */ #define DECL_ESTIMATED_INSNS(NODE) \ (FUNCTION_DECL_CHECK (NODE)->decl.u1.i) - -/* Nonzero if we can read a PCH file now. */ - -extern int allow_pch; /* Switches common to the C front ends. */ @@ -1314,6 +1310,7 @@ extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd); extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd, const char *orig); extern void c_common_write_pch (void); +extern void c_common_no_more_pch (void); extern void builtin_define_with_value (const char *, const char *, int); extern void c_stddef_cpp_builtins (void); extern void fe_file_change (const struct line_map *); diff --git a/gcc/c-lex.c b/gcc/c-lex.c index b6720da2b5b..28f2e8d5c27 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -320,6 +320,7 @@ c_lex (tree *value) { const cpp_token *tok; location_t atloc; + static bool no_more_pch; retry: tok = get_nonpadding_token (); @@ -421,6 +422,12 @@ c_lex (tree *value) break; } + if (! no_more_pch) + { + no_more_pch = true; + c_common_no_more_pch (); + } + return tok->type; } diff --git a/gcc/c-pch.c b/gcc/c-pch.c index 2cd9b9d1a2d..23ab0f8454a 100644 --- a/gcc/c-pch.c +++ b/gcc/c-pch.c @@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */ #include "c-pragma.h" #include "ggc.h" #include "langhooks.h" +#include "hosthooks.h" struct c_pch_validity { @@ -164,9 +165,6 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd) const char *pch_ident; struct c_pch_validity v; - if (! allow_pch) - return 2; - /* Perform a quick test of whether this is a valid precompiled header for the current language. */ @@ -244,7 +242,7 @@ c_common_read_pch (cpp_reader *pfile, const char *name, return; } - allow_pch = 0; + cpp_get_callbacks (parse_in)->valid_pch = NULL; if (fread (&h, sizeof (h), 1, f) != 1) { @@ -274,3 +272,15 @@ c_common_read_pch (cpp_reader *pfile, const char *name, fclose (f); } + +/* Indicate that no more PCH files should be read. */ + +void +c_common_no_more_pch (void) +{ + if (cpp_get_callbacks (parse_in)->valid_pch) + { + cpp_get_callbacks (parse_in)->valid_pch = NULL; + host_hooks.gt_pch_use_address (NULL, 0); + } +} diff --git a/gcc/config/rs6000/host-darwin.c b/gcc/config/rs6000/host-darwin.c index 7ef7c9aefdc..7e8055690e4 100644 --- a/gcc/config/rs6000/host-darwin.c +++ b/gcc/config/rs6000/host-darwin.c @@ -23,6 +23,7 @@ #include "coretypes.h" #include <signal.h> #include <sys/ucontext.h> +#include <sys/mman.h> #include "hosthooks.h" #include "hosthooks-def.h" #include "toplev.h" @@ -135,5 +136,54 @@ darwin_rs6000_extra_signals (void) if (sigaction (SIGSEGV, &sact, 0) < 0) fatal_error ("While setting up signal handler: %m"); } + +static void * darwin_rs6000_gt_pch_get_address (size_t); +static bool darwin_rs6000_gt_pch_use_address (void *, size_t); + +#undef HOST_HOOKS_GT_PCH_GET_ADDRESS +#define HOST_HOOKS_GT_PCH_GET_ADDRESS darwin_rs6000_gt_pch_get_address +#undef HOST_HOOKS_GT_PCH_USE_ADDRESS +#define HOST_HOOKS_GT_PCH_USE_ADDRESS darwin_rs6000_gt_pch_use_address + + +/* Yes, this is really supposed to work. */ +static char pch_address_space[1024*1024*1024] __attribute__((aligned (4096))); + +/* Return the address of the PCH address space, if the PCH will fit in it. */ + +static void * +darwin_rs6000_gt_pch_get_address (size_t sz) +{ + if (sz <= sizeof (pch_address_space)) + return pch_address_space; + else + return NULL; +} + +/* Check ADDR and SZ for validity, and deallocate (using munmap) that part of + pch_address_space beyond SZ. */ + +static bool +darwin_rs6000_gt_pch_use_address (void *addr, size_t sz) +{ + const size_t pagesize = getpagesize(); + bool result; + + if ((size_t)pch_address_space % pagesize != 0 + || sizeof (pch_address_space) % pagesize != 0) + abort (); + + result = (addr == pch_address_space && sz <= sizeof (pch_address_space)); + if (! result) + sz = 0; + + /* Round the size to a whole page size. Normally this is a no-op. */ + sz = (sz + pagesize - 1) / pagesize * pagesize; + + if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0) + fatal_error ("couldn't unmap pch_address_space: %m\n"); + + return result; +} const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dbebfa8dd2a..309c3f4f6cf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2003-07-29 Geoffrey Keating <geoffk@apple.com> + + * parser.c (cp_lexer_new_main): Use c_common_no_more_pch instead + of setting valid_pch by hand. + 2003-07-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> * decl.c (finish_enum): Initialize underlying_type. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3aa684b3d2c..64d260d5b27 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -302,7 +302,7 @@ cp_lexer_new_main (void) which is a GC collection point. So we have to grab the first token before allocating any memory. */ cp_lexer_get_preprocessor_token (NULL, &first_token); - cpp_get_callbacks (parse_in)->valid_pch = NULL; + c_common_no_more_pch (); /* Allocate the memory. */ lexer = ggc_alloc_cleared (sizeof (cp_lexer)); diff --git a/gcc/doc/hostconfig.texi b/gcc/doc/hostconfig.texi index 626a893c167..5c38313efd2 100644 --- a/gcc/doc/hostconfig.texi +++ b/gcc/doc/hostconfig.texi @@ -42,6 +42,39 @@ This host hook is used to set up handling for extra signals. The most common thing to do in this hook is to detect stack overflow. @end deftypefn +@deftypefn {Host Hook} void * HOST_HOOKS_GT_PCH_GET_ADDRESS (size_t @var{size}) +This host hook returns the address of some space in which a PCH may be +loaded with @samp{HOST_HOOKS_PCH_LOAD_PCH}. The space will need to +have @var{size} bytes. If insufficient space is available, +@samp{NULL} may be returned; the PCH machinery will try to find a +suitable address using a heuristic. + +The memory does not have to be available now. In fact, usually +@samp{HOST_HOOKS_PCH_LOAD_PCH} will already have been called. The memory +need only be available in future invocations of GCC. +@end deftypefn + +@deftypefn {Host Hook} bool HOST_HOOKS_GT_PCH_USE_ADDRESS (size_t @var{size}, void * @var{address}) +This host hook is called when a PCH file is about to be loaded. If +@var{address} is the address that would have been returned by +@samp{HOST_HOOKS_PCH_MEMORY_ADDRESS}, and @var{size} is smaller than +the maximum than @samp{HOST_HOOKS_PCH_MEMORY_ADDRESS} would have +accepted, return true, otherwise return false. + +In addition, free any address space reserved that isn't needed to hold +@var{size} bytes (whether or not true is returned). The PCH machinery will +use @samp{mmap} with @samp{MAP_FIXED} to load the PCH if @samp{HAVE_MMAP_FILE}, +or will use @samp{fread} otherwise. + +If no PCH will be loaded, this hook may be called with @var{size} +zero, in which case all reserved address space should be freed. + +Do not try to handle values of @var{address} that could not have been +returned by this executable; just return false. Such values usually +indicate an out-of-date PCH file (built by some other GCC executable), +and such a PCH file won't work. +@end deftypefn + @node Filesystem @section Host Filesystem @cindex configuration file diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 3163c15f83b..284811878de 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -29,6 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ggc.h" #include "toplev.h" #include "params.h" +#include "hosthooks.h" #ifdef HAVE_SYS_RESOURCE_H # include <sys/resource.h> @@ -450,19 +451,24 @@ gt_pch_save (FILE *f) mmi.size = ggc_pch_total_size (state.d); - /* Try to arrange things so that no relocation is necessary, - but don't try very hard. On most platforms, this will always work, - and on the rest it's a lot of work to do better. */ + /* Try to arrange things so that no relocation is necessary, but + don't try very hard. On most platforms, this will always work, + 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); + #if HAVE_MMAP_FILE - mmi.preferred_base = mmap (NULL, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE, - fileno (state.f), 0); - if (mmi.preferred_base == (void *) MAP_FAILED) - mmi.preferred_base = NULL; - else - munmap (mmi.preferred_base, mmi.size); -#else /* HAVE_MMAP_FILE */ - mmi.preferred_base = NULL; + if (mmi.preferred_base == NULL) + { + mmi.preferred_base = mmap (NULL, mmi.size, + PROT_READ | PROT_WRITE, MAP_PRIVATE, + fileno (state.f), 0); + if (mmi.preferred_base == (void *) MAP_FAILED) + mmi.preferred_base = NULL; + else + munmap (mmi.preferred_base, mmi.size); + } #endif /* HAVE_MMAP_FILE */ ggc_pch_this_base (state.d, mmi.preferred_base); @@ -539,6 +545,7 @@ gt_pch_restore (FILE *f) size_t i; struct mmap_info mmi; void *addr; + bool needs_read; /* Delete any deletable objects. This makes ggc_pch_read much faster, as it can be sure that no GCable objects remain other @@ -571,47 +578,75 @@ 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 - addr = mmap (mmi.preferred_base, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE, - fileno (f), mmi.offset); + void *mmap_result; -#if HAVE_MINCORE - if (addr != mmi.preferred_base) - { - 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 - 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); + mmap_result = mmap (mmi.preferred_base, mmi.size, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, + fileno (f), mmi.offset); + + /* The file might not be mmap-able. */ + needs_read = mmap_result == 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 HAVE_MMAP_FILE + addr = mmap (mmi.preferred_base, mmi.size, + PROT_READ | PROT_WRITE, MAP_PRIVATE, + fileno (f), mmi.offset); + +#if HAVE_MINCORE + if (addr != mmi.preferred_base) + { + 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 + 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 */ + + needs_read = addr == (void *) MAP_FAILED; #else /* HAVE_MMAP_FILE */ - addr = MAP_FAILED; + needs_read = true; #endif /* HAVE_MMAP_FILE */ - if (addr == (void *) MAP_FAILED) + if (needs_read) + addr = xmalloc (mmi.size); + } + + if (needs_read) { - addr = xmalloc (mmi.size); if (fseek (f, mmi.offset, SEEK_SET) != 0 || fread (&mmi, mmi.size, 1, f) != 1) fatal_error ("can't read PCH file: %m"); diff --git a/gcc/hooks.c b/gcc/hooks.c index c022eb38853..966945d9066 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -192,3 +192,18 @@ hook_rtx_rtx_null (rtx x ATTRIBUTE_UNUSED) { return 0; } + +/* Generic hook that takes a size_t and returns NULL. */ +void * +hook_voidp_size_t_null (size_t a ATTRIBUTE_UNUSED) +{ + return NULL; +} + +/* Generic hook that takes a size_t and a pointer and returns false. */ +bool +hook_bool_voidp_size_t_false (void * a ATTRIBUTE_UNUSED, + size_t b ATTRIBUTE_UNUSED) +{ + return false; +} diff --git a/gcc/hooks.h b/gcc/hooks.h index 6fa0bbec3c3..a3465f122d0 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -55,5 +55,7 @@ bool hook_bool_tree_tree_false (tree, tree); rtx hook_rtx_rtx_identity (rtx); rtx hook_rtx_rtx_null (rtx); +void * hook_voidp_size_t_null (size_t); +bool hook_bool_voidp_size_t_false (void *, size_t); #endif diff --git a/gcc/hosthooks-def.h b/gcc/hosthooks-def.h index 8a2b6b803cb..b1a41e72988 100644 --- a/gcc/hosthooks-def.h +++ b/gcc/hosthooks-def.h @@ -24,10 +24,14 @@ Boston, MA 02111-1307, USA. */ #include "hooks.h" #define HOST_HOOKS_EXTRA_SIGNALS hook_void_void +#define HOST_HOOKS_GT_PCH_GET_ADDRESS hook_voidp_size_t_null +#define HOST_HOOKS_GT_PCH_USE_ADDRESS hook_bool_voidp_size_t_false /* The structure is defined in hosthooks.h. */ #define HOST_HOOKS_INITIALIZER { \ - HOST_HOOKS_EXTRA_SIGNALS \ + HOST_HOOKS_EXTRA_SIGNALS, \ + HOST_HOOKS_GT_PCH_GET_ADDRESS, \ + HOST_HOOKS_GT_PCH_USE_ADDRESS \ } #endif /* GCC_HOST_HOOKS_DEF_H */ diff --git a/gcc/hosthooks.h b/gcc/hosthooks.h index cf6382b9419..bbc28f69d4d 100644 --- a/gcc/hosthooks.h +++ b/gcc/hosthooks.h @@ -25,6 +25,9 @@ struct host_hooks { void (*extra_signals) (void); + void * (*gt_pch_get_address) (size_t); + bool (*gt_pch_use_address) (void *, size_t); + /* Whenever you add entries here, make sure you adjust hosthooks-def.h. */ }; |