PR 6575
authorAlan Modra <amodra@gmail.com>
Mon, 11 Aug 2008 07:40:22 +0000 (07:40 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 11 Aug 2008 07:40:22 +0000 (07:40 +0000)
* hash.c: Expand PTR to void *.
(hash_delete): Add "freeme" parameter.  Call obstack_free.
* hash.h: Expand PTR to void *.
(hash_delete): Update prototype.
* macro.c (macro_expand_body): hash_delete LOCALs from formal_hash.
* config/tc-tic54x.c (tic54x_remove_local_label): Update hash_delete
call.
(subsym_substitute): Likewise.
* doc/internals.texi (hash_delete): Update.

gas/ChangeLog
gas/config/tc-tic54x.c
gas/doc/internals.texi
gas/hash.c
gas/hash.h
gas/macro.c

index e108c7f..50942f7 100644 (file)
@@ -1,9 +1,22 @@
+2008-08-11  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 6575
+       * hash.c: Expand PTR to void *.
+       (hash_delete): Add "freeme" parameter.  Call obstack_free.
+       * hash.h: Expand PTR to void *.
+       (hash_delete): Update prototype.
+       * macro.c (macro_expand_body): hash_delete LOCALs from formal_hash.
+       * config/tc-tic54x.c (tic54x_remove_local_label): Update hash_delete
+       call.
+       (subsym_substitute): Likewise.
+       * doc/internals.texi (hash_delete): Update.
+
 2008-08-08  Anatoly Sokolov  <aesok@post.ru>
 
        * config/tc-avr.c (mcu_types): Add avr25, avr31, avr35, and avr51
-       architectures. Reorganize list to put mcu types in correct architectures
-       and to order list same as in GCC. Use new ISA definitions in 
-       include/opcode/avr.h.
+       architectures. Reorganize list to put mcu types in correct
+       architectures and to order list same as in GCC. Use new ISA
+       definitions in include/opcode/avr.h.
        * doc/c-avr.texi: Add avr25, avr31, avr35, and avr51 architecture
        descriptions. Reorganize descriptions to put mcu types in correct
        architectures and to order lists same as in GCC.
        (md_show_usage): Add -call_nonpic.
 
 2008-08-08  Sterling Augustine  <sterling@tensilica.com>
-       
+
        * config/tc-xtensa.c (exclude_section_from_property_tables): New.
        (xtensa_create_property_segments): Use it.
        (xtensa_create_xproperty_segments): Likewise.
-       
+
 2008-08-08  Alan Modra  <amodra@bigpond.net.au>
 
        * doc/internals.texi (DWARF2_FORMAT): Update for 2008-08-04 change.
@@ -59,7 +72,7 @@
        (md_parse_option): Support it.
        * doc/c-h8300.texi (H8/300 Options): Document it.
        * doc/as.texinfo (Overview): Likewise.
-       
+
        * config/tc-sh.h (H_TICK_HEX): Define.
        * config/tc-sh.c (OPTION_H_TICK_HEX): New.
        (md_longopts): Add "-h-tick-hex".
index f7cf042..823015a 100644 (file)
@@ -1266,7 +1266,7 @@ tic54x_remove_local_label (key, value)
      const char *key;
      PTR value ATTRIBUTE_UNUSED;
 {
-  PTR *elem = hash_delete (local_label_hash[macro_level], key);
+  PTR *elem = hash_delete (local_label_hash[macro_level], key, FALSE);
   free (elem);
 }
 
@@ -4960,7 +4960,7 @@ subsym_substitute (line, forced)
                {
                  hash_insert (subsym_recurse_hash, name, name);
                  value = subsym_substitute (value, macro_level > 0);
-                 hash_delete (subsym_recurse_hash, name);
+                 hash_delete (subsym_recurse_hash, name, FALSE);
                }
 
              /* Temporarily zero-terminate where the symbol started.  */
index e37da47..e025e88 100644 (file)
@@ -1921,8 +1921,10 @@ Creates the hash table control structure.
 Destroy a hash table.
 @end deftypefun
 
-@deftypefun @{@} PTR hash_delete (struct hash_control *, const char *)
-Deletes entry from the hash table, returns the value it had.
+@deftypefun @{@} PTR hash_delete (struct hash_control *, const char *, int)
+Deletes entry from the hash table, returns the value it had.  If the last
+arg is non-zero, free memory allocated for this entry and all entries
+allocated more recently than this entry.
 @end deftypefun
 
 @deftypefun @{@} PTR hash_replace (struct hash_control *, const char *, PTR)
index 3ef582d..4eab512 100644 (file)
@@ -1,6 +1,6 @@
 /* hash.c -- gas hash table code
    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
-   2000, 2001, 2002, 2003, 2005, 2007
+   2000, 2001, 2002, 2003, 2005, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -44,7 +44,7 @@ struct hash_entry {
      table.  */
   unsigned long hash;
   /* Pointer being stored in the hash table.  */
-  PTR data;
+  void *data;
 };
 
 /* A hash table.  */
@@ -223,7 +223,7 @@ hash_lookup (struct hash_control *table, const char *key, size_t len,
    hash table.  */
 
 const char *
-hash_insert (struct hash_control *table, const char *key, PTR value)
+hash_insert (struct hash_control *table, const char *key, void *value)
 {
   struct hash_entry *p;
   struct hash_entry **list;
@@ -253,7 +253,7 @@ hash_insert (struct hash_control *table, const char *key, PTR value)
    error.  If an entry already exists, its value is replaced.  */
 
 const char *
-hash_jam (struct hash_control *table, const char *key, PTR value)
+hash_jam (struct hash_control *table, const char *key, void *value)
 {
   struct hash_entry *p;
   struct hash_entry **list;
@@ -291,10 +291,10 @@ hash_jam (struct hash_control *table, const char *key, PTR value)
    table, this does nothing and returns NULL.  */
 
 PTR
-hash_replace (struct hash_control *table, const char *key, PTR value)
+hash_replace (struct hash_control *table, const char *key, void *value)
 {
   struct hash_entry *p;
-  PTR ret;
+  void *ret;
 
   p = hash_lookup (table, key, strlen (key), NULL, NULL);
   if (p == NULL)
@@ -345,7 +345,7 @@ hash_find_n (struct hash_control *table, const char *key, size_t len)
    for that entry, or NULL if there is no such entry.  */
 
 PTR
-hash_delete (struct hash_control *table, const char *key)
+hash_delete (struct hash_control *table, const char *key, int freeme)
 {
   struct hash_entry *p;
   struct hash_entry **list;
@@ -363,9 +363,8 @@ hash_delete (struct hash_control *table, const char *key)
 
   *list = p->next;
 
-  /* Note that we never reclaim the memory for this entry.  If gas
-     ever starts deleting hash table entries in a big way, this will
-     have to change.  */
+  if (freeme)
+    obstack_free (&table->memory, p);
 
   return p->data;
 }
@@ -375,7 +374,7 @@ hash_delete (struct hash_control *table, const char *key)
 
 void
 hash_traverse (struct hash_control *table,
-              void (*pfn) (const char *key, PTR value))
+              void (*pfn) (const char *key, void *value))
 {
   unsigned int i;
 
index c2c827e..e544d45 100644 (file)
@@ -1,5 +1,5 @@
 /* hash.h -- header file for gas hash table routines
-   Copyright 1987, 1992, 1993, 1995, 1999, 2003, 2007
+   Copyright 1987, 1992, 1993, 1995, 1999, 2003, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -42,42 +42,42 @@ extern void hash_die (struct hash_control *);
    hash table.  */
 
 extern const char *hash_insert (struct hash_control *,
-                               const char *key, PTR value);
+                               const char *key, void *value);
 
 /* Insert or replace an entry in a hash table.  This returns NULL on
    success.  On error, it returns a printable string indicating the
    error.  If an entry already exists, its value is replaced.  */
 
 extern const char *hash_jam (struct hash_control *,
-                            const char *key, PTR value);
+                            const char *key, void *value);
 
 /* Replace an existing entry in a hash table.  This returns the old
    value stored for the entry.  If the entry is not found in the hash
    table, this does nothing and returns NULL.  */
 
-extern PTR hash_replace (struct hash_control *, const char *key,
-                        PTR value);
+extern void *hash_replace (struct hash_control *, const char *key,
+                        void *value);
 
 /* Find an entry in a hash table, returning its value.  Returns NULL
    if the entry is not found.  */
 
-extern PTR hash_find (struct hash_control *, const char *key);
+extern void *hash_find (struct hash_control *, const char *key);
 
 /* As hash_find, but KEY is of length LEN and is not guaranteed to be
    NUL-terminated.  */
 
-extern PTR hash_find_n (struct hash_control *, const char *key, size_t len);
+extern void *hash_find_n (struct hash_control *, const char *key, size_t len);
 
 /* Delete an entry from a hash table.  This returns the value stored
    for that entry, or NULL if there is no such entry.  */
 
-extern PTR hash_delete (struct hash_control *, const char *key);
+extern void *hash_delete (struct hash_control *, const char *key, int);
 
 /* Traverse a hash table.  Call the function on every entry in the
    hash table.  */
 
 extern void hash_traverse (struct hash_control *,
-                          void (*pfn) (const char *key, PTR value));
+                          void (*pfn) (const char *key, void *value));
 
 /* Print hash table statistics on the specified file.  NAME is the
    name of the hash table, used for printing a header.  */
index 1acc3a6..0cde3d6 100644 (file)
@@ -1,6 +1,6 @@
 /* macro.c - macro support for gas
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    Written by Steve and Judy Chamberlain of Cygnus Support,
       sac@cygnus.com
@@ -968,11 +968,11 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
   while (loclist != NULL)
     {
       formal_entry *f;
+      const char *name;
 
       f = loclist->next;
-      /* Setting the value to NULL effectively deletes the entry.  We
-         avoid calling hash_delete because it doesn't reclaim memory.  */
-      hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
+      name = sb_terminate (&loclist->name);
+      hash_delete (formal_hash, name, f == NULL);
       del_formal (loclist);
       loclist = f;
     }
@@ -1270,7 +1270,9 @@ delete_macro (const char *name)
     copy[i] = TOLOWER (name[i]);
   copy[i] = '\0';
 
-  /* Since hash_delete doesn't free memory, just clear out the entry.  */
+  /* We can only ask hash_delete to free memory if we are deleting
+     macros in reverse order to their definition.
+     So just clear out the entry.  */
   if ((macro = hash_find (macro_hash, copy)) != NULL)
     {
       hash_jam (macro_hash, copy, NULL);