This is the mail archive of the binutils@sourceware.org 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]

Re: gas really slow on long lines


On Thu, Aug 23, 2007 at 05:05:09PM +0200, Anders Waldenborg wrote:
> So I fired up oprofile and did some profiling. lex_got in tc-i386.c
> turned up as the main offender.
> 
> Without any deeper knowledge of the code it seems really stupid that
> lex_got checks until end of line when it is called on each expression
> on a line.

Agreed.  Even though I wrote the code in question.  :-)

> --- binutils-2.17.orig/gas/config/tc-i386.c	2006-04-07 
> 08:40:57.000000000 +0200
> +++ binutils-2.17/gas/config/tc-i386.c	2007-08-23 16:56:42.795755012 +0200
> @@ -3929,7 +3929,7 @@
>      return NULL;
> 
>    for (cp = input_line_pointer; *cp != '@'; cp++)
> -    if (is_end_of_line[(unsigned char) *cp])
> +    if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
>        return NULL;
> 
>    for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)

I'm applying the following, which fixes a similar problem a little
later as well.

	* config/tc-i386.c (lex_got): Don't scan past a comma.

Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.273
diff -u -p -r1.273 tc-i386.c
--- gas/config/tc-i386.c	17 Aug 2007 14:12:43 -0000	1.273
+++ gas/config/tc-i386.c	24 Aug 2007 01:35:02 -0000
@@ -4485,7 +4485,7 @@ lex_got (enum bfd_reloc_code_real *reloc
     return NULL;
 
   for (cp = input_line_pointer; *cp != '@'; cp++)
-    if (is_end_of_line[(unsigned char) *cp])
+    if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
       return NULL;
 
   for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
@@ -4519,12 +4519,12 @@ lex_got (enum bfd_reloc_code_real *reloc
 	      first = cp - input_line_pointer;
 
 	      /* The second part goes from after the reloc token until
-		 (and including) an end_of_line char.  Don't use strlen
-		 here as the end_of_line char may not be a NUL.  */
+		 (and including) an end_of_line char or comma.  */
 	      past_reloc = cp + 1 + len;
-	      for (cp = past_reloc; !is_end_of_line[(unsigned char) *cp++]; )
-		;
-	      second = cp - past_reloc;
+	      cp = past_reloc;
+	      while (!is_end_of_line[(unsigned char) *cp] && *cp != ',')
+		++cp;
+	      second = cp + 1 - past_reloc;
 
 	      /* Allocate and copy string.  The trailing NUL shouldn't
 		 be necessary, but be safe.  */


-- 
Alan Modra
Australia Development Lab, IBM


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