Hello. Following patch was a bit negotiated with Jakub and can save a huge amount of memory in cases where target attributes are heavily utilized.
Can bootstrap and survives regression tests on x86_64-linux-pc. Ready for trunk? Thanks, Martin
>From ebb7bd3cf513dc437622868eddbed6c8f725a67c Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Wed, 11 Nov 2015 12:52:11 +0100 Subject: [PATCH] Fix big memory leak in ix86_valid_target_attribute_p --- gcc/config/i386/i386.c | 2 ++ gcc/gcc.c | 2 +- gcc/lto-wrapper.c | 2 +- gcc/opts-common.c | 1 + gcc/opts.c | 16 +++++++++++++++- gcc/opts.h | 1 + 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b84a11d..1325cf0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6237,6 +6237,8 @@ ix86_valid_target_attribute_p (tree fndecl, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; } + finalize_options_struct (&func_options); + return ret; } diff --git a/gcc/gcc.c b/gcc/gcc.c index 8bbf5be..87d1979 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -9915,7 +9915,7 @@ driver_get_configure_time_options (void (*cb) (const char *option, size_t i; obstack_init (&obstack); - gcc_obstack_init (&opts_obstack); + init_opts_obstack (); n_switches = 0; for (i = 0; i < ARRAY_SIZE (option_default_specs); i++) diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 20e67ed..b9ac535 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -1355,7 +1355,7 @@ main (int argc, char *argv[]) { const char *p; - gcc_obstack_init (&opts_obstack); + init_opts_obstack (); p = argv[0] + strlen (argv[0]); while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) diff --git a/gcc/opts-common.c b/gcc/opts-common.c index d9bf4d4..06e88b5 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -706,6 +706,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask, /* Obstack for option strings. */ struct obstack opts_obstack; +bool opts_obstack_initialized = false; /* Like libiberty concat, but allocate using opts_obstack. */ diff --git a/gcc/opts.c b/gcc/opts.c index 9a3fbb3..527e678 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -266,6 +266,20 @@ add_comma_separated_to_vector (void **pvec, const char *arg) *pvec = v; } +static bool opts_obstack_initialized = false; + +/* Initialize opts_obstack if not initialized. */ + +void +init_opts_obstack (void) +{ + if (!opts_obstack_initialized) + { + opts_obstack_initialized = true; + gcc_obstack_init (&opts_obstack); + } +} + /* Initialize OPTS and OPTS_SET before using them in parsing options. */ void @@ -273,7 +287,7 @@ init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set) { size_t num_params = get_num_compiler_params (); - gcc_obstack_init (&opts_obstack); + init_opts_obstack (); *opts = global_options_init; diff --git a/gcc/opts.h b/gcc/opts.h index 38b3837..2eb2d97 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -323,6 +323,7 @@ extern void decode_cmdline_options_to_array (unsigned int argc, extern void init_options_once (void); extern void init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set); +extern void init_opts_obstack (void); extern void finalize_options_struct (struct gcc_options *opts); extern void decode_cmdline_options_to_array_default_mask (unsigned int argc, const char **argv, -- 2.6.2