This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[patch v2/gas]: simplify frag_grow
Hi,
the issue in the first version of the patch is that frag_new() doesn't necessary allocates memory as it can reuse the current chunk.
So this patch keeps the while loop around frag_new().
So this second version of the patch is less radical than the first one, and I still find the loop unpleasant as it can create empty frags.
But I think this patch makes the code easier to read, still remove unused variables, use obstack_chunk_size instead of accessing directly private fields, avoids an useless 'if' when there is enough room and finally add some comments.
No regressions for cris-elf (which has some nice testcases for broken-words).
Ok for trunk ?
Tristan.
2011-07-05 Tristan Gingold <gingold@adacore.com>
* frags.c (frag_grow): Simplify the code.
diff --git a/gas/frags.c b/gas/frags.c
index 17110bb..0457f66 100644
--- a/gas/frags.c
+++ b/gas/frags.c
@@ -85,31 +85,38 @@ frag_grow (unsigned int nchars)
{
if (obstack_room (&frchain_now->frch_obstack) < nchars)
{
- unsigned int n;
long oldc;
+ long newc;
- frag_wane (frag_now);
- frag_new (0);
- oldc = frchain_now->frch_obstack.chunk_size;
/* Try to allocate a bit more than needed right now. But don't do
this if we would waste too much memory. Especially necessary
- for extremely big (like 2GB initialized) frags. */
+ for extremely big (like 2GB initialized) frags. */
if (nchars < 0x10000)
- frchain_now->frch_obstack.chunk_size = 2 * nchars;
+ newc = 2 * nchars;
else
- frchain_now->frch_obstack.chunk_size = nchars + 0x10000;
- frchain_now->frch_obstack.chunk_size += SIZEOF_STRUCT_FRAG;
- if (frchain_now->frch_obstack.chunk_size > 0)
- while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
- && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars)
- {
- frag_wane (frag_now);
- frag_new (0);
- }
- frchain_now->frch_obstack.chunk_size = oldc;
+ newc = nchars + 0x10000;
+ newc += SIZEOF_STRUCT_FRAG;
+
+ /* Check for possible overflow. */
+ if (newc < 0)
+ as_fatal (_("can't extend frag %u chars"), nchars);
+
+ /* Force to allocate at least NEWC bytes. */
+ oldc = obstack_chunk_size (&frchain_now->frch_obstack);
+ obstack_chunk_size (&frchain_now->frch_obstack) = newc;
+
+ while (obstack_room (&frchain_now->frch_obstack) < nchars)
+ {
+ /* Not enough room in this frag. Close it and start a new one.
+ This must be done in a loop because the created frag may not
+ be big enough if the current obstack chunk is used. */
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+
+ /* Restore the old chunk size. */
+ obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
}
- if (obstack_room (&frchain_now->frch_obstack) < nchars)
- as_fatal (_("can't extend frag %u chars"), nchars);
}
/* Call this to close off a completed frag, and start up a new (empty)