This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] struct target_desc should be a singleton


An earlier version of the XML register work did a complicated
structural comparison on struct target_desc objects (parsed
descriptions) to figure out if they were "the same".  I realized
quickly that this was unworkable, and it complicated the memory
management enormously, so the current version only does a pointer
equality check.  This happens when selecting a new gdbarch - we
won't reuse a gdbarch that has a different target description.

That means it's good to have a single XML document always compile
to a single struct target_desc, no matter how many times you parse
it.  Then, when you reconnect to the same target a second time, you
get the same struct target_desc, and can reuse the same gdbarch.

This patch implements that.  Tested on arm-none-linux-gnueabi and
x86_64-pc-linux-gnu, and I watched memory usage with valgrind to
be sure I wasn't creating stray gdbarches.  Due to the location
of the change this patch conflicts textually with the XInclude
patch; I will commit it after that one.

-- 
Daniel Jacobowitz
CodeSourcery

2007-01-29  Daniel Jacobowitz  <dan@codesourcery.com>

	* xml-tdesc.c (struct tdesc_xml_cache, tdesc_xml_cache_s)
	(xml_cache): New.
	(tdesc_parse_xml): Cache expanded descriptions.

---
 gdb/xml-tdesc.c |   38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

Index: src/gdb/xml-tdesc.c
===================================================================
--- src.orig/gdb/xml-tdesc.c	2007-01-13 12:19:29.000000000 -0500
+++ src/gdb/xml-tdesc.c	2007-01-13 12:42:10.000000000 -0500
@@ -55,6 +55,24 @@ tdesc_parse_xml (const char *document, x
 
 #else /* HAVE_LIBEXPAT */
 
+/* A record of every XML description we have parsed.  We never discard
+   old descriptions, because we never discard gdbarches.  As long as we
+   have a gdbarch referencing this description, we want to have a copy
+   of it here, so that if we parse the same XML document again we can
+   return the same "struct target_desc *"; if they are not singletons,
+   then we will create unnecessary duplicate gdbarches.  See
+   gdbarch_list_lookup_by_info.  */
+
+struct tdesc_xml_cache
+{
+  const char *xml_document;
+  struct target_desc *tdesc;
+};
+typedef struct tdesc_xml_cache tdesc_xml_cache_s;
+DEF_VEC_O(tdesc_xml_cache_s);
+
+static VEC(tdesc_xml_cache_s) *xml_cache;
+
 /* Callback data for target description parsing.  */
 
 struct tdesc_parsing_data
@@ -103,7 +121,9 @@ tdesc_parse_xml (const char *document, x
   struct cleanup *back_to, *result_cleanup;
   struct gdb_xml_parser *parser;
   struct tdesc_parsing_data data;
+  struct tdesc_xml_cache *cache;
   char *expanded_text;
+  int ix;
 
   /* Expand all XInclude directives.  */
   expanded_text = xml_process_xincludes (_("target description"),
@@ -113,8 +133,18 @@ tdesc_parse_xml (const char *document, x
       warning (_("Could not load XML target description; ignoring"));
       return NULL;
     }
-  back_to = make_cleanup (xfree, expanded_text);
 
+  /* Check for an exact match in the list of descriptions we have
+     previously parsed.  strcmp is a slightly inefficient way to
+     do this; an SHA-1 checksum would work as well.  */
+  for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
+    if (strcmp (cache->xml_document, expanded_text) == 0)
+      {
+       xfree (expanded_text);
+       return cache->tdesc;
+      }
+
+  back_to = make_cleanup (null_cleanup, NULL);
   parser = gdb_xml_create_parser_and_cleanup (_("target description"),
 					      tdesc_elements, &data);
   gdb_xml_use_dtd (parser, "gdb-target.dtd");
@@ -122,10 +152,16 @@ tdesc_parse_xml (const char *document, x
   memset (&data, 0, sizeof (struct tdesc_parsing_data));
   data.tdesc = allocate_target_description ();
   result_cleanup = make_cleanup_free_target_description (data.tdesc);
+  make_cleanup (xfree, expanded_text);
 
   if (gdb_xml_parse (parser, expanded_text) == 0)
     {
       /* Parsed successfully.  */
+      struct tdesc_xml_cache new_cache;
+
+      new_cache.xml_document = expanded_text;
+      new_cache.tdesc = data.tdesc;
+      VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
       discard_cleanups (result_cleanup);
       do_cleanups (back_to);
       return data.tdesc;


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