summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog34
-rw-r--r--gcc/Makefile.in6
-rw-r--r--gcc/c-common.c4
-rw-r--r--gcc/c-common.h5
-rw-r--r--gcc/c-lex.c7
-rw-r--r--gcc/c-pch.c18
-rw-r--r--gcc/config/rs6000/host-darwin.c50
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/doc/hostconfig.texi33
-rw-r--r--gcc/ggc-common.c125
-rw-r--r--gcc/hooks.c15
-rw-r--r--gcc/hooks.h2
-rw-r--r--gcc/hosthooks-def.h6
-rw-r--r--gcc/hosthooks.h3
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. */
};