This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

cpplib: some performance improvements


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) \

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]