From: drow Date: Wed, 7 Feb 2007 22:51:36 +0000 (+0000) Subject: * xml-tdesc.c (struct tdesc_xml_cache, tdesc_xml_cache_s) X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=d110f44f5a3e3633619a7dcaa70bca94229c6a35;p=pf3gnuchains%2Fpf3gnuchains3x.git * xml-tdesc.c (struct tdesc_xml_cache, tdesc_xml_cache_s) (xml_cache): New. (tdesc_parse_xml): Cache expanded descriptions. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index be2bcfe991..7592d6919c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2007-02-07 Daniel Jacobowitz + * xml-tdesc.c (struct tdesc_xml_cache, tdesc_xml_cache_s) + (xml_cache): New. + (tdesc_parse_xml): Cache expanded descriptions. + +2007-02-07 Daniel Jacobowitz + * Makefile.in (XMLFILES): New. (COMMON_OBS): Add xml-builtin.o. (xml-builtin.c, stamp-xml): New rules. diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c index e7864bc3f8..bc7c6721f4 100644 --- a/gdb/xml-tdesc.c +++ b/gdb/xml-tdesc.c @@ -55,6 +55,24 @@ tdesc_parse_xml (const char *document, xml_fetch_another fetcher, #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, xml_fetch_another fetcher, 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, xml_fetch_another fetcher, 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, xml_fetch_another fetcher, 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;