This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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] macro purging


Defining macros with upper-case letters and using them with the lower-case
(or mixed-case) equivalents was no problem, purging macros however worked
with passing in fully lower-case names only.
Also, purging macros did not free the memory the macro was using; this was
particularly problematic because each macro carries a hash table with it,
which is about 256k/512k (32-/64-bit hosts) in size (used to be 16k/32k in
2.15). Defining and purging thousands of (perhaps machine generated) macros
caused the assembler to slow down to the point of becoming useless (or even
fail). Generally it would probably make sense to allow hash_new to have a
size hint parameter, so that this kind of overkill could be avoided when
the hash size can reasonably be expected to never grow this large.

Built and tested on i686-pc-linux-gnu.

gas/
2005-04-15  Jan Beulich  <jbeulich@novell.com>

	* macro.c (free_token): New, freeing all the memory associated with a
	macro.
	(do_formals): Move initializers to ...
	(define_macro): ... here.
	(delete_macro): Convert passed in name to lower case. Warn when
	purging macro that doesn't exist. Use hash_jam instead of hash_delete.

gas/testsuite/
2005-04-15  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/purge.[ls]: New.
	* gas/macros/macros.exp: Run new test.

--- /home/jbeulich/src/binutils/mainline/2005-04-15/gas/macro.c	2005-03-29 15:57:46.000000000 +0200
+++ 2005-04-15/gas/macro.c	2005-04-15 11:13:59.000000000 +0200
@@ -77,6 +77,7 @@ static int sub_actual (int, sb *, sb *, 
 static const char *macro_expand_body
   (sb *, sb *, formal_entry *, struct hash_control *, int);
 static const char *macro_expand (int, sb *, macro_entry *, sb *);
+static void free_macro(macro_entry *);
 
 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
 
@@ -471,8 +472,6 @@ do_formals (macro_entry *macro, int idx,
 {
   formal_entry **p = &macro->formals;
 
-  macro->formal_count = 0;
-  macro->formal_hash = hash_new ();
   idx = sb_skip_white (idx, in);
   while (idx < in->len)
     {
@@ -568,6 +567,7 @@ define_macro (int idx, sb *in, sb *label
 
   macro->formal_count = 0;
   macro->formals = 0;
+  macro->formal_hash = hash_new ();
 
   idx = sb_skip_white (idx, in);
   if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
@@ -1142,12 +1142,52 @@ check_macro (const char *line, sb *expan
   return 1;
 }
 
+/* Free the memory allocated to a macro.  */
+
+static void
+free_macro(macro_entry *macro)
+{
+  formal_entry *formal;
+
+  for (formal = macro->formals; formal; )
+    {
+      void *ptr;
+
+      sb_kill (&formal->name);
+      sb_kill (&formal->def);
+      sb_kill (&formal->actual);
+      ptr = formal;
+      formal = formal->next;
+      free (ptr);
+    }
+  hash_die (macro->formal_hash);
+  sb_kill (&macro->sub);
+  free (macro);
+}
+
 /* Delete a macro.  */
 
 void
 delete_macro (const char *name)
 {
-  hash_delete (macro_hash, name);
+  char *copy;
+  size_t i, len;
+  macro_entry *macro;
+
+  len = strlen (name);
+  copy = (char *) alloca (len + 1);
+  for (i = 0; i < len; ++i)
+    copy[i] = TOLOWER (name[i]);
+  copy[i] = '\0';
+
+  /* Since hash_delete doesn't free memory, just clear out the entry.  */
+  if ((macro = hash_find (macro_hash, copy)) != NULL)
+    {
+      hash_jam (macro_hash, copy, NULL);
+      free_macro (macro);
+    }
+  else
+    as_warn (_("Attempt to purge non-existant macro `%s'"), copy);
 }
 
 /* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
--- /home/jbeulich/src/binutils/mainline/2005-04-15/gas/testsuite/gas/macros/macros.exp	2005-03-29 15:57:46.000000000 +0200
+++ 2005-04-15/gas/testsuite/gas/macros/macros.exp	2005-04-15 11:15:34.000000000 +0200
@@ -78,4 +78,5 @@ case $target_triplet in {
     default { run_list_test dot "-alm" }
 }
 run_list_test end ""
+run_list_test purge ""
 run_list_test redef ""
--- /home/jbeulich/src/binutils/mainline/2005-04-15/gas/testsuite/gas/macros/purge.l	1970-01-01 01:00:00.000000000 +0100
+++ 2005-04-15/gas/testsuite/gas/macros/purge.l	2005-04-14 12:02:07.000000000 +0200
@@ -0,0 +1,7 @@
+.*: Assembler messages:
+.*:11: Error: .*
+.*:12: Error: .*
+.*:13: Error: .*
+.*:14: Error: .*
+.*:15: Warning: .*
+.*:16: Warning: .*
--- /home/jbeulich/src/binutils/mainline/2005-04-15/gas/testsuite/gas/macros/purge.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-04-15/gas/testsuite/gas/macros/purge.s	2005-04-15 09:16:42.000000000 +0200
@@ -0,0 +1,41 @@
+ .macro MACRO1
+ .endm
+ .macro macro2
+ .endm
+	MACRO1
+	MACRO2
+	macro1
+	macro2
+ .purgem MACRO1
+ .purgem macro2
+	MACRO1
+	MACRO2
+	macro1
+	macro2
+ .purgem macro1
+ .purgem MACRO2
+ .macro macro1
+ .endm
+ .macro MACRO2
+ .endm
+	MACRO1
+	MACRO2
+	macro1
+	macro2
+ .purgem MACRO1
+ .purgem macro2
+
+ .irpc a,ABCDEFGHIJKLMNOPQRSTUVWXYZ
+  .irpc b,ABCDEFGHIJKLMNOPQRSTUVWXYZ
+   .irpc c,ABCDEFGHIJKLMNOPQRSTUVWXYZ
+    .irpc d,ABCDEFGHIJKLMNOPQRSTUVWXYZ
+     .macro \a\b\c\d arg1=0, arg2=0
+      .if \arg1 + \arg2
+       .purgem \a\b\c\d
+      .endif
+     .endm
+	\a\b\c\d 1, 2
+    .endr
+   .endr
+  .endr
+ .endr

Attachment: binutils-mainline-macro-purge.patch
Description: Text document


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