diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-opts.c | 1 | ||||
-rw-r--r-- | libcpp/ChangeLog | 17 | ||||
-rw-r--r-- | libcpp/files.c | 68 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 1 | ||||
-rw-r--r-- | libcpp/internal.h | 3 |
6 files changed, 87 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1aec1408048..5af2db9c88c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-12-06 Tom Tromey <tromey@redhat.com> + + PR c/29172: + * c-opts.c (c_common_parse_file): Call cpp_clear_file_cache. + 2007-12-06 Richard Sandiford <rsandifo@nildram.co.uk> * config/mips/mips.c (mips_function_ok_for_sibcall): Check diff --git a/gcc/c-opts.c b/gcc/c-opts.c index 16710b6a825..a5c2270c025 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -1281,6 +1281,7 @@ c_common_parse_file (int set_yydebug) if (++i >= num_in_fnames) break; cpp_undef_all (parse_in); + cpp_clear_file_cache (parse_in); this_input_filename = cpp_read_main_file (parse_in, in_fnames[i]); /* If an input file is missing, abandon further compilation. diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index b64bfa9d372..1cc5d7f57f1 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,20 @@ +2007-12-06 Tom Tromey <tromey@redhat.com> + + PR c/29172: + * internal.h (struct cpp_reader) <file_hash_entries>: Changed + type. + <file_hash_entries_allocated, file_hash_entries_used>: Removed. + * files.c (FILE_HASH_POOL_SIZE): New macro. + (struct file_hash_entry_pool): New. + (destroy_all_cpp_files): New function. + (allocate_file_hash_entries): Allocate a file_hash_entry_pool. + (new_file_hash_entry): Update. + (free_file_hash_entries): New function. + (_cpp_cleanup_files): Call free_file_hash_entries and + destroy_all_cpp_files. + (cpp_clear_file_cache): New function. + * include/cpplib.h (cpp_clear_file_cache): Declare. + 2007-12-03 Tom Tromey <tromey@redhat.com> PR preprocessor/34288: diff --git a/libcpp/files.c b/libcpp/files.c index ad7dad03afa..467bb145ab9 100644 --- a/libcpp/files.c +++ b/libcpp/files.c @@ -150,6 +150,21 @@ struct file_hash_entry } u; }; +/* Number of entries to put in a file_hash_entry pool. */ +#define FILE_HASH_POOL_SIZE 127 + +/* A file hash entry pool. We allocate file_hash_entry object from + one of these. */ +struct file_hash_entry_pool +{ + /* Number of entries used from this pool. */ + unsigned int file_hash_entries_used; + /* Next pool in the chain; used when freeing. */ + struct file_hash_entry_pool *next; + /* The memory pool. */ + struct file_hash_entry pool[FILE_HASH_POOL_SIZE]; +}; + static bool open_file (_cpp_file *file); static bool pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch); @@ -964,6 +979,19 @@ destroy_cpp_file (_cpp_file *file) free (file); } +/* Release all the files allocated by this reader. */ +static void +destroy_all_cpp_files (cpp_reader *pfile) +{ + _cpp_file *iter = pfile->all_files; + while (iter) + { + _cpp_file *next = iter->next_file; + destroy_cpp_file (iter); + iter = next; + } +} + /* A hash of directory names. The directory names are the path names of files which contain a #include "", the included file name is appended to this directories. @@ -1009,20 +1037,35 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) static void allocate_file_hash_entries (cpp_reader *pfile) { - pfile->file_hash_entries_used = 0; - pfile->file_hash_entries_allocated = 127; - pfile->file_hash_entries = XNEWVEC (struct file_hash_entry, - pfile->file_hash_entries_allocated); + struct file_hash_entry_pool *pool = XNEW (struct file_hash_entry_pool); + pool->file_hash_entries_used = 0; + pool->next = pfile->file_hash_entries; + pfile->file_hash_entries = pool; } /* Return a new file hash entry. */ static struct file_hash_entry * new_file_hash_entry (cpp_reader *pfile) { - if (pfile->file_hash_entries_used == pfile->file_hash_entries_allocated) + unsigned int idx; + if (pfile->file_hash_entries->file_hash_entries_used == FILE_HASH_POOL_SIZE) allocate_file_hash_entries (pfile); - return &pfile->file_hash_entries[pfile->file_hash_entries_used++]; + idx = pfile->file_hash_entries->file_hash_entries_used++; + return &pfile->file_hash_entries->pool[idx]; +} + +/* Free the file hash entry pools. */ +static void +free_file_hash_entries (cpp_reader *pfile) +{ + struct file_hash_entry_pool *iter = pfile->file_hash_entries; + while (iter) + { + struct file_hash_entry_pool *next = iter->next; + free (iter); + iter = next; + } } /* Returns TRUE if a file FNAME has ever been successfully opened. @@ -1125,6 +1168,19 @@ _cpp_cleanup_files (cpp_reader *pfile) htab_delete (pfile->dir_hash); htab_delete (pfile->nonexistent_file_hash); obstack_free (&pfile->nonexistent_file_ob, 0); + free_file_hash_entries (pfile); + destroy_all_cpp_files (pfile); +} + +/* Make the parser forget about files it has seen. This can be useful + for resetting the parser to start another run. */ +void +cpp_clear_file_cache (cpp_reader *pfile) +{ + _cpp_cleanup_files (pfile); + pfile->file_hash_entries = NULL; + pfile->all_files = NULL; + _cpp_init_files (pfile); } /* Enter a file name in the hash for the sake of cpp_included. */ diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 01e982fbceb..e205be7cd6c 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -862,6 +862,7 @@ extern cpp_dir *cpp_get_dir (struct _cpp_file *); extern cpp_buffer *cpp_get_buffer (cpp_reader *); extern struct _cpp_file *cpp_get_file (cpp_buffer *); extern cpp_buffer *cpp_get_prev (cpp_buffer *); +extern void cpp_clear_file_cache (cpp_reader *); /* In cpppch.c */ struct save_macro_data; diff --git a/libcpp/internal.h b/libcpp/internal.h index 830f07bf3a8..6110e5cdb08 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -360,8 +360,7 @@ struct cpp_reader /* File and directory hash table. */ struct htab *file_hash; struct htab *dir_hash; - struct file_hash_entry *file_hash_entries; - unsigned int file_hash_entries_allocated, file_hash_entries_used; + struct file_hash_entry_pool *file_hash_entries; /* Negative path lookup hash table. */ struct htab *nonexistent_file_hash; |