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: PATCH: Allocate sufficient space for string buffer


On Thu, Jun 7, 2012 at 7:36 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Jun 7, 2012 at 7:09 PM, Alan Modra <amodra@gmail.com> wrote:
>> On Thu, Jun 07, 2012 at 11:58:45AM -0700, H.J. Lu wrote:
>>> ? ? ? * input-scrub.c (input_scrub_include_sb): Use sb_build to
>>> ? ? ? allocate sufficient space for from_sb.
>>> ? ? ? * read.c (do_repeat): Use sb_build to allocate sufficient space
>>> ? ? ? for many.
>>> ? ? ? * sb.c (sb_build): Remove static.
>>> ? ? ? * sb.h (sb_build): New prototype.
>>
>> Seems a reasonable optimisation. ?OK, but
>>
>>> - ?sb_new (&many);
>>> + ?sb_build (&many, count * one.len + 1);
>>
>> looks wrong to me. ?sb_build already adds one to account for the
>> string terminator.
>
> We have
>
> static void
> sb_check (sb *ptr, size_t len)
> {
> ?size_t max = ptr->max;
>
> ?while (ptr->len + len >= max)
> ? ?{
> ? ? ?max <<= 1;
> ? ? ?if (max == 0)
> ? ? ? ?as_fatal ("string buffer overflow");
> ? ?}
> ?if (max != ptr->max)
> ? ?{
> ? ? ?ptr->max = max;
> ? ? ?ptr->ptr = xrealloc (ptr->ptr, max + 1);
> ? ?}
> }
>
> If ptr->len + len == ptr->max, we double the size.
> Should it be changed to
>
> while (ptr->len + len > max)
>

Here is a new patch.  It increases max size by
dsize at a time instead of double only if needed.  OK
to install?


-- 
H.J.
--
2012-06-07  H.J. Lu  <hongjiu.lu@intel.com>

	* input-scrub.c (input_scrub_include_sb): Use sb_build to
	allocate sufficient space for from_sb.
	* read.c (do_repeat): Use sb_build to allocate sufficient space
	for many.
	* sb.c (sb_build): Remove static.
	(sb_check): Increase max size by dsize only if needed.
	* sb.h (sb_build): New prototype.

diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index 46dd244..1b09b73 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -264,6 +264,8 @@ input_scrub_include_file (char *filename, char *position)
 void
 input_scrub_include_sb (sb *from, char *position, int is_expansion)
 {
+  int newline;
+
   if (macro_nest > max_macro_nest)
     as_fatal (_("macros nested too deeply"));
   ++macro_nest;
@@ -277,9 +279,11 @@ input_scrub_include_sb (sb *from, char *position,
int is_expansion)

   next_saved_file = input_scrub_push (position);

-  sb_new (&from_sb);
+  /* Allocate sufficient space: from->len + optional newline + '\0'.  */
+  newline = from->len >= 1 && from->ptr[0] != '\n';
+  sb_build (&from_sb, from->len + newline + 1);
   from_sb_is_expansion = is_expansion;
-  if (from->len >= 1 && from->ptr[0] != '\n')
+  if (newline)
     {
       /* Add the sentinel required by read.c.  */
       sb_add_char (&from_sb, '\n');
diff --git a/gas/read.c b/gas/read.c
index 2b37173..c52c6eb 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -3207,7 +3207,7 @@ do_repeat (int count, const char *start, const char *end)
       return;
     }

-  sb_new (&many);
+  sb_build (&many, count * one.len);
   while (count-- > 0)
     sb_add_sb (&many, &one);

diff --git a/gas/sb.c b/gas/sb.c
index f345fe1..62ec7cc 100644
--- a/gas/sb.c
+++ b/gas/sb.c
@@ -44,7 +44,7 @@ static void sb_check (sb *, size_t);

 /* Initializes an sb.  */

-static void
+void
 sb_build (sb *ptr, size_t size)
 {
   ptr->ptr = xmalloc (size + 1);
@@ -116,10 +116,10 @@ sb_check (sb *ptr, size_t len)
 {
   size_t max = ptr->max;

-  while (ptr->len + len >= max)
+  while (ptr->len + len > max)
     {
-      max <<= 1;
-      if (max == 0)
+      max += dsize;
+      if (max <= ptr->max)
 	as_fatal ("string buffer overflow");
     }
   if (max != ptr->max)
diff --git a/gas/sb.h b/gas/sb.h
index cc11ef6..ea010ee 100644
--- a/gas/sb.h
+++ b/gas/sb.h
@@ -53,6 +53,7 @@ typedef struct sb
 sb;

 extern void sb_new (sb *);
+extern void sb_build (sb *, size_t);
 extern void sb_kill (sb *);
 extern void sb_add_sb (sb *, sb *);
 extern void sb_scrub_and_add_sb (sb *, sb *);


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