This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib: some performance improvements
- To: gcc-patches at gcc dot gnu dot org
- Subject: cpplib: some performance improvements
- From: Zack Weinberg <zack at wolery dot cumb dot org>
- Date: Tue, 4 Jul 2000 22:29:58 -0700
cpplib currently burns ~20% of execution time inside malloc, because
it allocates thousands of tiny objects. This patch switches three of
the five most frequent callers of malloc to obstack allocation. The
other two require more work; unfortunately they're the largest two.
By itself this should be good for a 5-10% speedup depending on how
crummy your malloc is. I get a couple of minutes shaved off make
bootstrap and make check.
There's also a couple minor namespace tweaks.
Bootstrapped i386-linux.
zw
* cpphash.c: Include obstack.h.
(del_HASHNODE, make_HASHNODE): Removed.
(cpp_lookup): Allocate hash nodes here; do it on an obstack.
(_cpp_init_macro_hash): Rename _cpp_init_macros; create
obstack for hash nodes.
(_cpp_cleanup_macros): New.
* cpplex.c: Don't include sys/mman.h.
(cpp_push_buffer, cpp_pop_buffer): Moved to cpplib.c.
* cpplib.c: Include sys/mman.h and obstack.h.
(cpp_push_buffer): Moved from cpplex.c; allocate buffers on an
obstack.
(cpp_pop_buffer): Moved from cpplex.c; free buffers from an obstack.
(_cpp_unwind_if_stack): Now static, unwind_if_stack. Don't
bother freeing if stack entries (they will be freed with their buffer).
(do_endif): Free if stack entries from the buffer obstack.
(push_conditional): Allocate if stack entries from the buffer obstack.
(find_answer): Rename to _cpp_find_answer.
(do_assert, do_unassert): Update.
* cpphash.h: Update prototypes.
(xobnew): New convenience macro.
* cpplib.h (struct cpp_reader): Add hash_ob and buffer_ob fields.
Update comments.
(struct cpp_hashnode): Remove disabled field.
* cppinit.c: Don't include hashtab.h or splay-tree.h.
(report_missing_guard): Moved to cppfiles.c.
(cpp_reader_init): Call cpp_init_stacks, cpp_init_macros,
cpp_init_includes.
(cpp_cleanup): Call cpp_cleanup_stacks, cpp_cleanup_macros,
cpp_cleanup_includes. Don't destroy hashtab or
all_include_files here.
(cpp_finish): Use _cpp_report_missing_guards.
* cppfiles.c (report_missing_guard): Moved from cppinit.c.
(_cpp_init_include_table): Rename _cpp_init_includes.
(_cpp_cleanup_includes, _cpp_report_missing_guards): New.
* cppexp.c (parse_assertion): Update for new name of
find_answer.
* Makefile.in (cpplib.o, cpphash.o, cppinit.o): Update deps.
===================================================================
Index: cppexp.c
--- cppexp.c 2000/07/04 01:58:19 1.61
+++ cppexp.c 2000/07/05 05:07:23
@@ -404,7 +404,7 @@ parse_assertion (pfile)
/* If we get here, the syntax is valid. */
op.op = INT;
op.value = (hp->type == T_ASSERTION &&
- (answer == 0 || *find_answer (hp, &answer->list) != 0));
+ (answer == 0 || *_cpp_find_answer (hp, &answer->list) != 0));
if (answer)
FREE_ANSWER (answer);
===================================================================
Index: cppfiles.c
--- cppfiles.c 2000/07/04 01:58:19 1.71
+++ cppfiles.c 2000/07/05 05:07:24
@@ -60,7 +60,8 @@ static ssize_t read_with_read PARAMS ((c
static ssize_t read_file PARAMS ((cpp_buffer *, int, ssize_t));
static void destroy_include_file_node PARAMS ((splay_tree_value));
-static int close_cached_fd PARAMS ((splay_tree_node, void *));
+static int close_cached_fd PARAMS ((splay_tree_node, void *));
+static int report_missing_guard PARAMS ((splay_tree_node, void *));
#if 0
static void hack_vms_include_specification PARAMS ((char *));
@@ -103,7 +104,7 @@ close_cached_fd (n, dummy)
}
void
-_cpp_init_include_table (pfile)
+_cpp_init_includes (pfile)
cpp_reader *pfile;
{
pfile->all_include_files
@@ -112,6 +113,13 @@ _cpp_init_include_table (pfile)
destroy_include_file_node);
}
+void
+_cpp_cleanup_includes (pfile)
+ cpp_reader *pfile;
+{
+ splay_tree_delete (pfile->all_include_files);
+}
+
/* Given a filename, look it up and possibly open it. If the file
does not exist, return NULL. If the file does exist but doesn't
need to be reread, return an include_file entry with fd == -1.
@@ -356,6 +364,38 @@ cpp_make_system_header (pfile, pbuf, fla
cpp_ice (pfile, "cpp_make_system_header called on non-file buffer");
else
pbuf->inc->sysp = flag;
+}
+
+/* Report on all files that might benefit from a multiple include guard.
+ Triggered by -H. */
+void
+_cpp_report_missing_guards (pfile)
+ cpp_reader *pfile;
+{
+ int banner = 0;
+ splay_tree_foreach (pfile->all_include_files, report_missing_guard,
+ (PTR) &banner);
+}
+
+static int
+report_missing_guard (n, b)
+ splay_tree_node n;
+ void *b;
+{
+ struct include_file *f = (struct include_file *) n->value;
+ int *bannerp = (int *)b;
+
+ if (f && f->cmacro == 0 && f->include_count == 1)
+ {
+ if (*bannerp == 0)
+ {
+ fputs (_("Multiple include guards may be useful for:\n"), stderr);
+ *bannerp = 1;
+ }
+ fputs (f->name, stderr);
+ putc ('\n', stderr);
+ }
+ return 0;
}
#define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
===================================================================
Index: cpphash.c
--- cpphash.c 2000/07/04 01:58:19 1.94
+++ cpphash.c 2000/07/05 05:07:24
@@ -26,10 +26,12 @@ Foundation, 59 Temple Place - Suite 330,
#include "config.h"
#include "system.h"
#include "cpplib.h"
-#include "hashtab.h"
#include "cpphash.h"
+#include "hashtab.h"
+#include "obstack.h"
-#undef abort
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
/* This is the second argument to eq_HASHNODE. */
struct hashdummy
@@ -43,9 +45,6 @@ struct hashdummy
static unsigned int hash_HASHNODE PARAMS ((const void *));
static int eq_HASHNODE PARAMS ((const void *, const void *));
-static void del_HASHNODE PARAMS ((void *));
-static cpp_hashnode *make_HASHNODE PARAMS ((const U_CHAR *, size_t,
- enum node_type, unsigned int));
static int dump_hash_helper PARAMS ((void **, void *));
static void dump_funlike_macro PARAMS ((cpp_reader *, cpp_hashnode *));
@@ -105,41 +104,6 @@ eq_HASHNODE (x, y)
&& !ustrncmp (a->name, b->name, a->length));
}
-/* Destroy a cpp_hashnode. */
-static void
-del_HASHNODE (x)
- void *x;
-{
- cpp_hashnode *h = (cpp_hashnode *)x;
-
- _cpp_free_definition (h);
- free (h);
-}
-
-/* Allocate and initialize a cpp_hashnode structure.
- Caller must fill in the value field. */
-
-static cpp_hashnode *
-make_HASHNODE (name, len, type, hash)
- const U_CHAR *name;
- size_t len;
- enum node_type type;
- unsigned int hash;
-{
- cpp_hashnode *hp = (cpp_hashnode *) xmalloc (sizeof (cpp_hashnode) + len);
- U_CHAR *p = (U_CHAR *)hp + offsetof (cpp_hashnode, name);
-
- hp->type = type;
- hp->length = len;
- hp->hash = hash;
- hp->disabled = 0;
-
- memcpy (p, name, len);
- p[len] = 0;
-
- return hp;
-}
-
/* Find the hash node for name "name", of length LEN. */
cpp_hashnode *
@@ -151,6 +115,7 @@ cpp_lookup (pfile, name, len)
struct hashdummy dummy;
cpp_hashnode *new, **slot;
unsigned int hash;
+ U_CHAR *p;
dummy.name = name;
dummy.length = len;
@@ -161,20 +126,42 @@ cpp_lookup (pfile, name, len)
if (*slot)
return *slot;
- new = make_HASHNODE (name, len, T_VOID, hash);
+ /* Create a new hash node. */
+ p = obstack_alloc (pfile->hash_ob, sizeof (cpp_hashnode) + len);
+ new = (cpp_hashnode *)p;
+ p += offsetof (cpp_hashnode, name);
+
+ new->type = T_VOID;
+ new->length = len;
+ new->hash = hash;
+ new->fe_value = 0;
new->value.expansion = NULL;
+ memcpy (p, name, len);
+ p[len] = 0;
+
*slot = new;
return new;
}
-/* Init the hash table. In here so it can see the hash and eq functions. */
+/* Set up and tear down internal structures for macro expansion. */
void
-_cpp_init_macro_hash (pfile)
+_cpp_init_macros (pfile)
cpp_reader *pfile;
{
pfile->hashtab = htab_create (HASHSIZE, hash_HASHNODE,
- eq_HASHNODE, del_HASHNODE);
+ eq_HASHNODE, (htab_del) _cpp_free_definition);
+ pfile->hash_ob = xnew (struct obstack);
+ obstack_init (pfile->hash_ob);
+}
+
+void
+_cpp_cleanup_macros (pfile)
+ cpp_reader *pfile;
+{
+ htab_delete (pfile->hashtab);
+ obstack_free (pfile->hash_ob, 0);
+ free (pfile->hash_ob);
}
/* Free the definition of macro H. */
===================================================================
Index: cpphash.h
--- cpphash.h 2000/07/04 01:58:19 1.57
+++ cpphash.h 2000/07/05 05:07:24
@@ -188,7 +188,8 @@ extern unsigned int _cpp_calc_hash PARAM
extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
extern void _cpp_dump_definition PARAMS ((cpp_reader *, cpp_hashnode *));
-extern void _cpp_init_macro_hash PARAMS ((cpp_reader *));
+extern void _cpp_init_macros PARAMS ((cpp_reader *));
+extern void _cpp_cleanup_macros PARAMS ((cpp_reader *));
extern void _cpp_dump_macro_hash PARAMS ((cpp_reader *));
/* In cppfiles.c */
@@ -199,7 +200,9 @@ extern void _cpp_execute_include PARAMS
int));
extern int _cpp_compare_file_date PARAMS ((cpp_reader *, const U_CHAR *,
unsigned int, int));
-extern void _cpp_init_include_table PARAMS ((cpp_reader *));
+extern void _cpp_report_missing_guards PARAMS ((cpp_reader *));
+extern void _cpp_init_includes PARAMS ((cpp_reader *));
+extern void _cpp_cleanup_includes PARAMS ((cpp_reader *));
extern const char *_cpp_fake_include PARAMS ((cpp_reader *, const char *));
/* In cppexp.c */
@@ -241,15 +244,17 @@ extern const struct directive *_cpp_chec
PARAMS ((cpp_reader *, const cpp_token *, int));
extern const struct directive *_cpp_check_linemarker
PARAMS ((cpp_reader *, const cpp_token *, int));
-extern void _cpp_unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *));
-extern cpp_hashnode * _cpp_parse_assertion PARAMS ((cpp_reader *,
+extern cpp_hashnode *_cpp_parse_assertion PARAMS ((cpp_reader *,
struct answer **));
-extern struct answer** find_answer PARAMS ((cpp_hashnode *,
+extern struct answer **_cpp_find_answer PARAMS ((cpp_hashnode *,
const cpp_toklist *));
+extern void _cpp_init_stacks PARAMS ((cpp_reader *));
+extern void _cpp_cleanup_stacks PARAMS ((cpp_reader *));
/* Utility routines and macros. */
#define xnew(T) (T *) xmalloc (sizeof(T))
#define xnewvec(T, N) (T *) xmalloc (sizeof(T) * (N))
+#define xobnew(O, T) (T *) obstack_alloc (O, sizeof(T))
/* These are inline functions instead of macros so we can get type
checking. */
===================================================================
Index: cppinit.c
--- cppinit.c 2000/07/04 01:58:20 1.86
+++ cppinit.c 2000/07/05 05:07:24
@@ -21,8 +21,6 @@ Foundation, 59 Temple Place - Suite 330,
#include "config.h"
#include "system.h"
-#include "hashtab.h"
-#include "splay-tree.h"
#include "cpplib.h"
#include "cpphash.h"
#include "output.h"
@@ -225,7 +223,6 @@ static int opt_comp PARAMS ((const voi
#endif
static int parse_option PARAMS ((const char *));
static int handle_option PARAMS ((cpp_reader *, int, char **));
-static int report_missing_guard PARAMS ((splay_tree_node, void *));
/* Fourth argument to append_include_chain: chain to use */
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
@@ -533,8 +530,9 @@ cpp_reader_init (pfile)
CPP_OPTION (pfile, pending) =
(struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
- _cpp_init_macro_hash (pfile);
- _cpp_init_include_table (pfile);
+ _cpp_init_stacks (pfile);
+ _cpp_init_macros (pfile);
+ _cpp_init_includes (pfile);
}
/* Initialize a cpp_printer structure. As a side effect, open the
@@ -580,8 +578,9 @@ cpp_cleanup (pfile)
if (pfile->deps)
deps_free (pfile->deps);
- htab_delete (pfile->hashtab);
- splay_tree_delete (pfile->all_include_files);
+ _cpp_cleanup_stacks (pfile);
+ _cpp_cleanup_macros (pfile);
+ _cpp_cleanup_includes (pfile);
_cpp_free_temp_tokens (pfile);
}
@@ -1009,27 +1008,6 @@ cpp_start_read (pfile, print, fname)
return 1;
}
-static int
-report_missing_guard (n, b)
- splay_tree_node n;
- void *b;
-{
- struct include_file *f = (struct include_file *) n->value;
- int *bannerp = (int *)b;
-
- if (f && f->cmacro == 0 && f->include_count == 1)
- {
- if (*bannerp == 0)
- {
- fputs (_("Multiple include guards may be useful for:\n"), stderr);
- *bannerp = 1;
- }
- fputs (f->name, stderr);
- putc ('\n', stderr);
- }
- return 0;
-}
-
/* This is called at the end of preprocessing. It pops the
last buffer and writes dependency output. It should also
clear macro definitions, such that you could call cpp_start_read
@@ -1085,11 +1063,7 @@ cpp_finish (pfile, print)
/* Report on headers that could use multiple include guards. */
if (CPP_OPTION (pfile, print_include_names))
- {
- int banner = 0;
- splay_tree_foreach (pfile->all_include_files, report_missing_guard,
- (void *) &banner);
- }
+ _cpp_report_missing_guards (pfile);
}
static void
===================================================================
Index: cpplex.c
--- cpplex.c 2000/07/04 22:26:16 1.60
+++ cpplex.c 2000/07/05 05:07:25
@@ -56,10 +56,6 @@ o Correct pastability test for CPP_NAME
#include "cpphash.h"
#include "symcat.h"
-#ifdef HAVE_MMAP_FILE
-# include <sys/mman.h>
-#endif
-
#define auto_expand_name_space(list) \
_cpp_expand_name_space ((list), 1 + (list)->name_cap / 2)
static void safe_fwrite PARAMS ((cpp_reader *, const U_CHAR *,
@@ -225,78 +221,6 @@ _cpp_grow_token_buffer (pfile, n)
pfile->token_buffer = (U_CHAR *)
xrealloc(pfile->token_buffer, pfile->token_buffer_size);
CPP_SET_WRITTEN (pfile, old_written);
-}
-
-/* Allocate a new cpp_buffer for PFILE, and push it on the input buffer stack.
- If BUFFER != NULL, then use the LENGTH characters in BUFFER
- as the new input buffer.
- Return the new buffer, or NULL on failure. */
-
-cpp_buffer *
-cpp_push_buffer (pfile, buffer, length)
- cpp_reader *pfile;
- const U_CHAR *buffer;
- long length;
-{
- cpp_buffer *buf = CPP_BUFFER (pfile);
- cpp_buffer *new;
- if (++pfile->buffer_stack_depth == CPP_STACK_MAX)
- {
- cpp_fatal (pfile, "macro or #include recursion too deep");
- return NULL;
- }
-
- new = (cpp_buffer *) xcalloc (1, sizeof (cpp_buffer));
-
- new->buf = new->cur = buffer;
- new->rlimit = buffer + length;
- new->prev = buf;
- new->line_base = NULL;
-
- CPP_BUFFER (pfile) = new;
- return new;
-}
-
-cpp_buffer *
-cpp_pop_buffer (pfile)
- cpp_reader *pfile;
-{
- cpp_buffer *buf = CPP_BUFFER (pfile);
-
- if (buf->inc)
- {
- _cpp_unwind_if_stack (pfile, buf);
- if (buf->buf)
- {
-#ifdef HAVE_MMAP_FILE
- if (buf->mapped)
- munmap ((caddr_t) buf->buf, buf->rlimit - buf->buf);
- else
-#endif
- free ((PTR) buf->buf);
- }
- if (pfile->system_include_depth)
- pfile->system_include_depth--;
- if (pfile->include_depth)
- pfile->include_depth--;
- if (pfile->potential_control_macro)
- {
- if (buf->inc->cmacro != NEVER_REREAD)
- buf->inc->cmacro = pfile->potential_control_macro;
- pfile->potential_control_macro = 0;
- }
- pfile->input_stack_listing_current = 0;
- /* If the file will not be included again, then close it. */
- if (DO_NOT_REREAD (buf->inc))
- {
- close (buf->inc->fd);
- buf->inc->fd = -1;
- }
- }
- CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
- free (buf);
- pfile->buffer_stack_depth--;
- return CPP_BUFFER (pfile);
}
/* Deal with the annoying semantics of fwrite. */
===================================================================
Index: cpplib.c
--- cpplib.c 2000/07/04 01:58:20 1.180
+++ cpplib.c 2000/07/05 05:07:25
@@ -25,8 +25,13 @@ Foundation, 59 Temple Place - Suite 330,
#include "cpplib.h"
#include "cpphash.h"
#include "intl.h"
+#include "obstack.h"
#include "symcat.h"
+#ifdef HAVE_MMAP_FILE
+# include <sys/mman.h>
+#endif
+
/* Stack of conditionals currently in progress
(including both successful and failing conditionals). */
@@ -43,21 +48,24 @@ struct if_stack
/* Forward declarations. */
static void validate_else PARAMS ((cpp_reader *, const U_CHAR *));
-static int parse_include PARAMS ((cpp_reader *, const U_CHAR *, int,
+static int parse_include PARAMS ((cpp_reader *, const U_CHAR *, int,
const U_CHAR **, unsigned int *,
int *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
const cpp_hashnode *));
static void pass_thru_directive PARAMS ((cpp_reader *));
-static int read_line_number PARAMS ((cpp_reader *, int *));
-static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
+static int read_line_number PARAMS ((cpp_reader *, int *));
+static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
unsigned long *));
-static const cpp_hashnode *parse_ifdef PARAMS ((cpp_reader *, const U_CHAR *));
-static const cpp_hashnode *detect_if_not_defined
- PARAMS ((cpp_reader *));
-static cpp_hashnode *get_define_node PARAMS ((cpp_reader *));
-static void dump_macro_name PARAMS ((cpp_reader *, cpp_hashnode *));
+static const cpp_hashnode *
+ parse_ifdef PARAMS ((cpp_reader *, const U_CHAR *));
+static const cpp_hashnode *
+ detect_if_not_defined PARAMS ((cpp_reader *));
+static cpp_hashnode *
+ get_define_node PARAMS ((cpp_reader *));
+static void dump_macro_name PARAMS ((cpp_reader *, cpp_hashnode *));
+static void unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *));
/* Utility. */
#define str_match(sym, len, str) \
@@ -1150,7 +1158,7 @@ do_endif (pfile)
CPP_BUFFER (pfile)->if_stack = ifs->next;
pfile->skipping = ifs->was_skipping;
pfile->potential_control_macro = ifs->cmacro;
- free (ifs);
+ obstack_free (pfile->buffer_ob, ifs);
}
return 0;
}
@@ -1169,7 +1177,7 @@ push_conditional (pfile, skip, type, cma
{
struct if_stack *ifs;
- ifs = (struct if_stack *) xmalloc (sizeof (struct if_stack));
+ ifs = xobnew (pfile->buffer_ob, struct if_stack);
ifs->lineno = _cpp_get_line (pfile, &ifs->colno);
ifs->next = CPP_BUFFER (pfile)->if_stack;
ifs->cmacro = cmacro;
@@ -1197,8 +1205,8 @@ validate_else (pfile, directive)
/* Called when we reach the end of a file. Walk back up the
conditional stack till we reach its level at entry to this file,
issuing error messages. Then force skipping off. */
-void
-_cpp_unwind_if_stack (pfile, pbuf)
+static void
+unwind_if_stack (pfile, pbuf)
cpp_reader *pfile;
cpp_buffer *pbuf;
{
@@ -1209,7 +1217,7 @@ _cpp_unwind_if_stack (pfile, pbuf)
cpp_error_with_line (pfile, ifs->lineno, ifs->colno, "unterminated #%s",
dtable[ifs->type].name);
nifs = ifs->next;
- free (ifs);
+ /* No need to free - they'll all go away with the buffer. */
}
pfile->skipping = 0;
}
@@ -1330,7 +1338,7 @@ _cpp_parse_assertion (pfile, answerp)
/* Returns a pointer to the pointer to the answer in the answer chain,
or a pointer to NULL if the answer is not in the chain. */
struct answer **
-find_answer (node, candidate)
+_cpp_find_answer (node, candidate)
cpp_hashnode *node;
const cpp_toklist *candidate;
{
@@ -1362,7 +1370,7 @@ do_assert (pfile)
if (node->type == T_ASSERTION)
{
- if (*find_answer (node, &new_answer->list))
+ if (*_cpp_find_answer (node, &new_answer->list))
goto err;
new_answer->next = node->value.answers;
}
@@ -1393,7 +1401,7 @@ do_unassert (pfile)
{
if (answer)
{
- struct answer **p = find_answer (node, &answer->list);
+ struct answer **p = _cpp_find_answer (node, &answer->list);
temp = *p;
if (temp)
@@ -1502,4 +1510,94 @@ cpp_defined (pfile, id, len)
return 0;
}
return (hp->type != T_VOID);
+}
+
+/* Allocate a new cpp_buffer for PFILE, and push it on the input buffer stack.
+ If BUFFER != NULL, then use the LENGTH characters in BUFFER
+ as the new input buffer.
+ Return the new buffer, or NULL on failure. */
+
+cpp_buffer *
+cpp_push_buffer (pfile, buffer, length)
+ cpp_reader *pfile;
+ const U_CHAR *buffer;
+ long length;
+{
+ cpp_buffer *buf = CPP_BUFFER (pfile);
+ cpp_buffer *new;
+ if (++pfile->buffer_stack_depth == CPP_STACK_MAX)
+ {
+ cpp_fatal (pfile, "#include recursion too deep");
+ return NULL;
+ }
+
+ new = xobnew (pfile->buffer_ob, cpp_buffer);
+ memset (new, 0, sizeof (cpp_buffer));
+
+ new->buf = new->cur = buffer;
+ new->rlimit = buffer + length;
+ new->prev = buf;
+
+ CPP_BUFFER (pfile) = new;
+ return new;
+}
+
+cpp_buffer *
+cpp_pop_buffer (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buf = CPP_BUFFER (pfile);
+
+ unwind_if_stack (pfile, buf);
+#ifdef HAVE_MMAP_FILE
+ if (buf->mapped)
+ munmap ((caddr_t) buf->buf, buf->rlimit - buf->buf);
+ else
+#endif
+ if (buf->inc)
+ free ((PTR) buf->buf);
+
+ if (buf->inc)
+ {
+ if (pfile->system_include_depth)
+ pfile->system_include_depth--;
+ if (pfile->include_depth)
+ pfile->include_depth--;
+ if (pfile->potential_control_macro)
+ {
+ if (buf->inc->cmacro != NEVER_REREAD)
+ buf->inc->cmacro = pfile->potential_control_macro;
+ pfile->potential_control_macro = 0;
+ }
+ pfile->input_stack_listing_current = 0;
+ /* If the file will not be included again, then close it. */
+ if (DO_NOT_REREAD (buf->inc))
+ {
+ close (buf->inc->fd);
+ buf->inc->fd = -1;
+ }
+ }
+
+ CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
+ obstack_free (pfile->buffer_ob, buf);
+ pfile->buffer_stack_depth--;
+ return CPP_BUFFER (pfile);
+}
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+void
+_cpp_init_stacks (pfile)
+ cpp_reader *pfile;
+{
+ pfile->buffer_ob = xnew (struct obstack);
+ obstack_init (pfile->buffer_ob);
+}
+
+void
+_cpp_cleanup_stacks (pfile)
+ cpp_reader *pfile;
+{
+ obstack_free (pfile->buffer_ob, 0);
+ free (pfile->buffer_ob);
}
===================================================================
Index: cpplib.h
--- cpplib.h 2000/07/04 01:58:20 1.103
+++ cpplib.h 2000/07/05 05:07:25
@@ -476,7 +476,7 @@ struct cpp_reader
/* Hash table of macros and assertions. See cpphash.c */
struct htab *hashtab;
- /* Hash table of other included files. See cppfiles.c */
+ /* Tree of other included files. See cppfiles.c */
struct splay_tree_s *all_include_files;
/* Chain of `actual directory' file_name_list entries,
@@ -527,6 +527,14 @@ struct cpp_reader
/* Buffer of -M output. */
struct deps *deps;
+ /* Obstack holding all macro hash nodes. This never shrinks.
+ See cpphash.c */
+ struct obstack *hash_ob;
+
+ /* Obstack holding buffer and conditional structures. This is a
+ real stack. See cpplib.c */
+ struct obstack *buffer_ob;
+
/* User visible options. */
struct cpp_options opts;
@@ -625,7 +633,6 @@ struct cpp_hashnode
unsigned int hash; /* cached hash value */
unsigned short length; /* length of name */
ENUM_BITFIELD(node_type) type : 8; /* node type */
- char disabled; /* macro turned off for rescan? */
union
{
===================================================================
Index: Makefile.in
--- Makefile.in 2000/07/02 05:22:58 1.473
+++ Makefile.in 2000/07/05 05:27:51
@@ -1801,11 +1798,11 @@ cppulp.o: cppulp.c $(CONFIG_H) syste
cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS)
cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS)
-cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS)
-cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H)
+cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
+cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H) $(HASHTAB_H)
cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
-cppinit.o: cppinit.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H) $(SPLAY_TREE_H) \
+cppinit.o: cppinit.c $(CONFIG_H) $(LIBCPP_DEPS) \
mkdeps.h prefix.h output.h Makefile version.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(PREPROCESSOR_DEFINES) \