[binutils-gdb] gas: don't use frag_more to repeat copies

Alan Modra amodra@sourceware.org
Thu Feb 19 06:24:43 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=13a7a6aa0d18e1faced5d3b88ab81fa6f95e845f

commit 13a7a6aa0d18e1faced5d3b88ab81fa6f95e845f
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Feb 19 15:18:12 2026 +1030

    gas: don't use frag_more to repeat copies
    
    It's more elegant to use the repeat capability of an rs_fill frag_var,
    and dramatically reduces memory usage for large repeat counts.
    
    For ideal minimal memory use, repeats of up to the 100 bytes or so of
    frag overhead should be handled by frag_more, but I don't care to
    optimise those cases.  It's enough that the most common case of a
    single output value uses frag_more, while stress testing the assembler
    with huge repeats doesn't run into OOM.
    
            * read.c (float_cons): Repeat output using an rs_fill frag_var
            rather than looping with frag_more.
            (s_float_space): Likewise.

Diff:
---
 gas/read.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/gas/read.c b/gas/read.c
index 40804d44845..29dace68958 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -3873,6 +3873,7 @@ s_float_space (int float_type)
   char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
   char *stop = NULL;
   char stopc = 0;
+  char *p;
 
 #ifdef md_cons_align
   md_cons_align (1);
@@ -3906,13 +3907,11 @@ s_float_space (int float_type)
       return;
     }
 
-  while (--count >= 0)
-    {
-      char *p;
-
-      p = frag_more (flen);
-      memcpy (p, temp, flen);
-    }
+  if (count == 1)
+    p = frag_more (flen);
+  else
+    p = frag_var (rs_fill, flen, flen, 0, NULL, count, NULL);
+  memcpy (p, temp, flen);
 
   demand_empty_rest_of_line ();
 
@@ -5173,12 +5172,11 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line.  */
 		count = count_exp.X_add_number;
 	    }
 #endif
-
-	  while (--count >= 0)
-	    {
-	      p = frag_more (length);
-	      memcpy (p, temp, length);
-	    }
+	  if (count == 1)
+	    p = frag_more (length);
+	  else
+	    p = frag_var (rs_fill, length, length, 0, NULL, count, NULL);
+	  memcpy (p, temp, length);
 	}
       SKIP_WHITESPACE ();
     }


More information about the Binutils-cvs mailing list