bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Use mapped file name for symbols


From: Akim Demaille
Subject: Re: [PATCH] Use mapped file name for symbols
Date: Thu, 25 Feb 2021 08:44:45 +0100

Joshua,

> Le 25 févr. 2021 à 06:54, Akim Demaille <akim@lrde.epita.fr> a écrit :
> 
> Thanks for the fix!  However, this is doing a lot of malloc/free for a 
> handful of file names.  I'll rather see if there's a means to have a cache 
> for this.

I don't have time to finish this now, but this message is to make sure we 
aren't both working on it.  Here's what I have currently.  It appears to work.

commit 6c47c14f0c245a70ed5a32048b50b678b7f8bb8a
Author: Akim Demaille <akim.demaille@gmail.com>
Date:   Thu Feb 25 08:31:50 2021 +0100

    WIP: cache the mapped file names
    
    * #: .
    * #: .
    * #: .
    * #: .
    * #: .
    * #: .
    * #: .
    * #: .

diff --git a/bootstrap.conf b/bootstrap.conf
index 51777601b..6f1a3fc61 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -27,6 +27,7 @@ gnulib_modules='
   getopt-gnu
   gettext-h git-version-gen gitlog-to-changelog
   gpl-3.0 intprops inttypes isnan javacomp-script
+  hash-map
   javaexec-script
   ldexpl
   libtextstyle-optional
@@ -58,7 +59,7 @@ gnulib_modules='
   xconcat-filename
   xhash
   xlist
-  xmemdup0
+  xmap xmemdup0
   xstrndup
 
   fprintf-posix printf-posix snprintf-posix sprintf-posix
diff --git a/lib/.gitignore b/lib/.gitignore
index 5d7f60e5b..00843d68f 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -162,10 +162,14 @@
 /gl_anytreehash_list2.h
 /gl_array_list.c
 /gl_array_list.h
+/gl_hash_map.c
+/gl_hash_map.h
 /gl_linked_list.c
 /gl_linked_list.h
 /gl_list.c
 /gl_list.h
+/gl_map.c
+/gl_map.h
 /gl_oset.c
 /gl_oset.h
 /gl_rbtree_ordered.h
@@ -175,6 +179,8 @@
 /gl_rbtreehash_list.h
 /gl_xlist.c
 /gl_xlist.h
+/gl_xmap.c
+/gl_xmap.h
 /gnulib.mk
 /hard-locale.c
 /hard-locale.h
diff --git a/lib/malloc/.gitignore b/lib/malloc/.gitignore
new file mode 100644
index 000000000..6f3f8a3ba
--- /dev/null
+++ b/lib/malloc/.gitignore
@@ -0,0 +1,5 @@
+/scratch_buffer.h
+/scratch_buffer_dupfree.c
+/scratch_buffer_grow.c
+/scratch_buffer_grow_preserve.c
+/scratch_buffer_set_array_size.c
diff --git a/src/files.c b/src/files.c
index c0d5d1ca7..7ffec3254 100644
--- a/src/files.c
+++ b/src/files.c
@@ -26,6 +26,8 @@
 #include <error.h>
 #include <get-errno.h>
 #include <gl_array_list.h>
+#include <gl_hash_map.h>
+#include <gl_xmap.h>
 #include <gl_xlist.h>
 #include <quote.h>
 #include <quotearg.h>
@@ -58,7 +60,6 @@ char *spec_graph_file = NULL;    /* for -g. */
 char *spec_html_file = NULL;     /* for --html. */
 char *spec_xml_file = NULL;      /* for -x. */
 char *spec_header_file = NULL;   /* for --header. */
-char *spec_mapped_header_file = NULL;
 char *parser_file_name;
 
 /* All computed output file names.  */
@@ -95,7 +96,6 @@ uniqstr grammar_file = NULL;
 char *all_but_ext;
 static char *all_but_tab_ext;
 char *dir_prefix;
-char *mapped_dir_prefix;
 
 /* C source file extension (the parser source).  */
 static char *src_extension = NULL;
@@ -109,6 +109,10 @@ struct prefix_map
 };
 
 static gl_list_t prefix_maps = NULL;
+
+/* Map file names to prefix-mapped file names. */
+static gl_map_t mapped_files = NULL;
+
 
 /*-----------------------------------------------------------------.
 | Return a newly allocated string composed of the concatenation of |
@@ -172,11 +176,10 @@ xfdopen (int fd, char const *mode)
   return res;
 }
 
-/*  Given an input file path, returns a dynamically allocated string that
-    contains the path with the file prefix mapping rules applied, or NULL if
-    the input was NULL. */
-char *
-map_file_name (char const *filename)
+/* The mapped name of FILENAME, allocated, if there are prefix maps.
+   Otherwise NULL.  */
+static char *
+map_file_name_alloc (char const *filename)
 {
   if (!filename)
     return NULL;
@@ -209,6 +212,49 @@ map_file_name (char const *filename)
   return s;
 }
 
+static bool
+string_equals (const void *x1, const void *x2)
+{
+  const char *s1 = x1;
+  const char *s2 = x2;
+  return STREQ (s1, s2);
+}
+
+/* A hash function for NUL-terminated char* strings using
+   the method described by Bruno Haible.
+   See https://www.haible.de/bruno/hashfunc.html.  */
+static size_t
+string_hash (const void *x)
+{
+#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
+
+  const char *s = x;
+  size_t h = 0;
+
+  for (; *s; s++)
+    h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
+
+  return h;
+}
+
+const char *
+map_file_name (char const *filename)
+{
+  if (!prefix_maps)
+    return filename;
+  if (!mapped_files)
+    mapped_files
+      = gl_map_nx_create_empty (GL_HASH_MAP,
+                                string_equals, string_hash, NULL, NULL);
+  const void *res = gl_map_get (mapped_files, filename);
+  if (!res)
+    {
+      res = map_file_name_alloc (filename);
+      gl_map_put (mapped_files, filename, map_file_name_alloc (filename));
+    }
+  return res;
+}
+
 static void
 prefix_map_free (struct prefix_map *p)
 {
@@ -446,9 +492,6 @@ compute_output_file_names (void)
       output_file_name_check (&spec_verbose_file, false);
     }
 
-  spec_mapped_header_file = map_file_name (spec_header_file);
-  mapped_dir_prefix = map_file_name (dir_prefix);
-
   free (all_but_tab_ext);
   free (src_extension);
   free (header_extension);
@@ -536,10 +579,8 @@ output_file_names_free (void)
   free (spec_html_file);
   free (spec_xml_file);
   free (spec_header_file);
-  free (spec_mapped_header_file);
   free (parser_file_name);
   free (dir_prefix);
-  free (mapped_dir_prefix);
   for (int i = 0; i < generated_files_size; i++)
     free (generated_files[i].name);
   free (generated_files);
@@ -547,4 +588,6 @@ output_file_names_free (void)
 
   if (prefix_maps)
     gl_list_free (prefix_maps);
+  if (mapped_files)
+    gl_map_free (mapped_files);
 }
diff --git a/src/files.h b/src/files.h
index e84497115..385847739 100644
--- a/src/files.h
+++ b/src/files.h
@@ -53,15 +53,9 @@ extern char *spec_xml_file;
 /* File name specified with --header.  */
 extern char *spec_header_file;
 
-/* File name specified with --header, adjusted for mapped prefixes. */
-extern char *spec_mapped_header_file;
-
 /* Directory prefix of output file names.  */
 extern char *dir_prefix;
 
-/* Directory prefix of output file name, adjusted for mapped prefixes. */
-extern char *mapped_dir_prefix;
-
 /* The file name as given on the command line.
    Not named "input_file" because Flex uses this name for an argument,
    and therefore GCC warns about a name clash. */
@@ -94,7 +88,13 @@ FILE *xfopen (const char *name, char const *mode);
 void xfclose (FILE *ptr);
 FILE *xfdopen (int fd, char const *mode);
 
-char *map_file_name (char const *filename);
+/* Given an input file path, return a string that contains the path
+   with the file prefix mapping rules applied, or NULL if the input
+   was NULL.  Do not free the return value.  */
+const char *map_file_name (char const *filename);
+
+/* Add a new file prefix mapping. If a file path starts with
+   oldprefix, it will be replaced with newprefix.  */
 void add_prefix_map (char const *oldprefix, char const *newprefix);
 
 #endif /* !FILES_H_ */
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
index 3e7657ca1..0654a3f10 100644
--- a/src/muscle-tab.c
+++ b/src/muscle-tab.c
@@ -204,10 +204,8 @@ static void
 muscle_syncline_grow (char const *key, location loc)
 {
   obstack_printf (&muscle_obstack, "]b4_syncline(%d, ", loc.start.line);
-  char *f = map_file_name (loc.start.file);
   obstack_quote (&muscle_obstack,
-                 quotearg_style (c_quoting_style, f));
-  free (f);
+                 quotearg_style (c_quoting_style, map_file_name 
(loc.start.file)));
   obstack_sgrow (&muscle_obstack, ")dnl\n[");
   char const *extension = obstack_finish0 (&muscle_obstack);
   muscle_grow (key, extension, "", "");
diff --git a/src/output.c b/src/output.c
index 34dbc6714..4b1bb0d8e 100644
--- a/src/output.c
+++ b/src/output.c
@@ -531,9 +531,7 @@ user_actions_output (FILE *out)
           {
             fprintf (out, "b4_syncline(%d, ",
                      rules[r].action_loc.start.line);
-            char *f = map_file_name (rules[r].action_loc.start.file);
-            string_output (out, f);
-            free(f);
+            string_output (out, map_file_name 
(rules[r].action_loc.start.file));
             fprintf (out, ")dnl\n");
           }
         fprintf (out, "[%*s%s]],\n[[",
@@ -631,10 +629,8 @@ prepare_symbol_definitions (void)
 
           if (p->code)
             {
-              char *f = map_file_name (p->location.start.file);
               SET_KEY2 (pname, "file");
-              MUSCLE_INSERT_C_STRING (key, f);
-              free (f);
+              MUSCLE_INSERT_C_STRING (key, map_file_name 
(p->location.start.file));
 
               SET_KEY2 (pname, "line");
               MUSCLE_INSERT_INT (key, p->location.start.line);
@@ -852,6 +848,9 @@ prepare (void)
 
   MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
 
+  const char *spec_mapped_header_file = map_file_name (spec_header_file);
+  const char *mapped_dir_prefix = map_file_name (dir_prefix);
+
 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
   DEFINE (dir_prefix);
   DEFINE (mapped_dir_prefix);
diff --git a/src/scan-skel.l b/src/scan-skel.l
index 1ec125af5..20049cfb3 100644
--- a/src/scan-skel.l
+++ b/src/scan-skel.l
@@ -269,7 +269,5 @@ fail_for_invalid_at (char const *at)
 static void
 output_mapped_file (char const *name)
 {
-  char *f = map_file_name (name);
-  fputs (quotearg_style (c_quoting_style, f), yyout);
-  free (f);
+  fputs (quotearg_style (c_quoting_style, map_file_name (name)), yyout);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]