public inbox for binutils-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] alloc gas seginfo on notes obstack
@ 2022-07-04 13:25 Alan Modra
0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2022-07-04 13:25 UTC (permalink / raw)
To: bfd-cvs
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=eeeaf705fe1c94e9330fa222d7928a9d0f03832a
commit eeeaf705fe1c94e9330fa222d7928a9d0f03832a
Author: Alan Modra <amodra@gmail.com>
Date: Mon Jul 4 12:45:47 2022 +0930
alloc gas seginfo on notes obstack
Lots of memory used in gas should go on this obstack. The patch also
frees all the gas obstacks on exit, which isn't a completely trivial
task.
* subsegs.c (alloc_seginfo): New function.
(subseg_change, subseg_get): Use it.
(subsegs_end): New function.
* as.h (subsegs_end): Declare.
* output-file.c: Include subsegs.h
(stash_frchain_obs): New function.
(output_file_close): Save obstacks attached to output bfd before
closing. Call subsegs_end with the array of obstacks.
Diff:
---
gas/as.h | 1 +
gas/output-file.c | 42 +++++++++++++++++++++++++++++++++++++-----
gas/subsegs.c | 37 ++++++++++++++++++++++++-------------
3 files changed, 62 insertions(+), 18 deletions(-)
diff --git a/gas/as.h b/gas/as.h
index 470a2e52891..ec0c12afe23 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -476,6 +476,7 @@ void input_scrub_end (void);
void new_logical_line (const char *, int);
void new_logical_line_flags (const char *, int, int);
void subsegs_begin (void);
+void subsegs_end (struct obstack **);
void subseg_change (segT, int);
segT subseg_new (const char *, subsegT);
segT subseg_force_new (const char *, subsegT);
diff --git a/gas/output-file.c b/gas/output-file.c
index 9852a2ed456..95e21d23dc1 100644
--- a/gas/output-file.c
+++ b/gas/output-file.c
@@ -19,6 +19,7 @@
02110-1301, USA. */
#include "as.h"
+#include "subsegs.h"
#include "output-file.h"
#ifndef TARGET_MACH
@@ -49,23 +50,54 @@ output_file_create (const char *name)
stdoutput->flags |= BFD_TRADITIONAL_FORMAT;
}
+static void
+stash_frchain_obs (asection *sec)
+{
+ segment_info_type *info = seg_info (sec);
+ if (info)
+ {
+ struct frchain *frchp;
+ for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
+ obstack_ptr_grow (¬es, &frchp->frch_obstack);
+ info->frchainP = NULL;
+ }
+}
+
void
output_file_close (const char *filename)
{
bool res;
+ bfd *obfd = stdoutput;
+ struct obstack **obs;
+ asection *sec;
- if (stdoutput == NULL)
+ if (obfd == NULL)
return;
+ /* Prevent an infinite loop - if the close failed we will call as_fatal
+ which will call xexit() which may call this function again... */
+ stdoutput = NULL;
+
+ /* We can't free obstacks attached to the output bfd sections before
+ closing the output bfd since data in those obstacks may need to
+ be accessed, but we can't access anything in the output bfd after
+ it is closed.. */
+ for (sec = obfd->sections; sec; sec = sec->next)
+ stash_frchain_obs (sec);
+ stash_frchain_obs (reg_section);
+ stash_frchain_obs (expr_section);
+ stash_frchain_obs (bfd_abs_section_ptr);
+ stash_frchain_obs (bfd_und_section_ptr);
+ obstack_ptr_grow (¬es, NULL);
+ obs = obstack_finish (¬es);
+
/* Close the bfd. */
if (!flag_always_generate_output && had_errors ())
res = bfd_cache_close_all ();
else
- res = bfd_close (stdoutput);
+ res = bfd_close (obfd);
- /* Prevent an infinite loop - if the close failed we will call as_fatal
- which will call xexit() which may call this function again... */
- stdoutput = NULL;
+ subsegs_end (obs);
if (! res)
as_fatal ("%s: %s", filename, bfd_errmsg (bfd_get_error ()));
diff --git a/gas/subsegs.c b/gas/subsegs.c
index cb598e84bef..1776511a9b8 100644
--- a/gas/subsegs.c
+++ b/gas/subsegs.c
@@ -43,7 +43,27 @@ subsegs_begin (void)
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
frag_now = &dummy_frag;
}
+
+void
+subsegs_end (struct obstack **obs)
+{
+ for (; *obs; obs++)
+ _obstack_free (*obs, NULL);
+ _obstack_free (&frchains, NULL);
+ _obstack_free (&cond_obstack, NULL);
+ _obstack_free (¬es, NULL);
+}
\f
+static void
+alloc_seginfo (segT seg)
+{
+ segment_info_type *seginfo;
+
+ seginfo = obstack_alloc (¬es, sizeof (*seginfo));
+ memset (seginfo, 0, sizeof (*seginfo));
+ seginfo->bfd_section = seg;
+ bfd_set_section_userdata (seg, seginfo);
+}
/*
* subseg_change()
*
@@ -57,16 +77,11 @@ subsegs_begin (void)
void
subseg_change (segT seg, int subseg)
{
- segment_info_type *seginfo = seg_info (seg);
now_seg = seg;
now_subseg = subseg;
- if (! seginfo)
- {
- seginfo = XCNEW (segment_info_type);
- seginfo->bfd_section = seg;
- bfd_set_section_userdata (seg, seginfo);
- }
+ if (!seg_info (seg))
+ alloc_seginfo (seg);
}
\f
static void
@@ -149,7 +164,6 @@ segT
subseg_get (const char *segname, int force_new)
{
segT secptr;
- segment_info_type *seginfo;
const char *now_seg_name = now_seg ? bfd_section_name (now_seg) : 0;
if (!force_new
@@ -163,13 +177,10 @@ subseg_get (const char *segname, int force_new)
else
secptr = bfd_make_section_anyway (stdoutput, segname);
- seginfo = seg_info (secptr);
- if (! seginfo)
+ if (!seg_info (secptr))
{
secptr->output_section = secptr;
- seginfo = XCNEW (segment_info_type);
- seginfo->bfd_section = secptr;
- bfd_set_section_userdata (secptr, seginfo);
+ alloc_seginfo (secptr);
}
return secptr;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-07-04 13:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-04 13:25 [binutils-gdb] alloc gas seginfo on notes obstack Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).