Attempting to repeatedly compile in-process led to assertion failures in a release build on the 2nd compile within a process:
156 void 157 set_default_param_value (compiler_param num, int value) 158 { 159 >>>> gcc_assert (!params_finished); 160 161 compiler_params[(int) num].default_value = value; 162 } #0 fancy_abort (file=file@entry=0x7fffecf394a0 "../../gcc/params.c", line=line@entry=159, function=function@entry=0x7fffecf3d550 <set_default_param_value(compiler_param, int)::__FUNCTION__> "set_default_param_value") at ../../gcc/diagnostic.c:1182 #1 0x00007fffecc9cc07 in set_default_param_value (num=num@entry=GGC_MIN_EXPAND, value=<optimized out>) at ../../gcc/params.c:159 #2 0x00007fffec654685 in init_ggc_heuristics () at ../../gcc/ggc-common.c:899 #3 0x00007fffec52b265 in general_init (argv0=<optimized out>) at ../../gcc/toplev.c:1179 #4 toplev::main (this=this@entry=0x7fffffff9cdf, argc=argc@entry=5, argv=argv@entry=0x7fffffff9ce0) at ../../gcc/toplev.c:1944 due to these guards: 895 void 896 init_ggc_heuristics (void) 897 { 898 >>> #if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT 899 set_default_param_value (GGC_MIN_EXPAND, ggc_min_expand_heuristic ()); 900 set_default_param_value (GGC_MIN_HEAPSIZE, ggc_min_heapsize_heuristic ()); 901 #endif 902 } which prevent it being seen in a devel build. The issue here is that init_ggc_heuristics is reinitializing the default param and thus assuming that param initialization is still in progress. My previous attempt at handling multiple initialization of params which simply made it idempotent leaves params_finished as true. Instead, introduce params_c_finalize to purge state within params.c so that we fully reinitialize things each time. Committed to branch dmalcolm/jit gcc/ * params.c (global_init_params): Require that params_finished be false, rather than being idempotent, in favor of purging all state between toplev invocations, since in a release build init_ggc_heuristics calls set_param_value_internal, and the latter assumes that params_finished is true. (params_c_finalize): New. * params.h (params_c_finalize): New. * toplev.c (toplev::finalize): Call params_c_finalize. --- gcc/ChangeLog.jit | 11 +++++++++++ gcc/params.c | 16 +++++++++++++--- gcc/params.h | 4 ++++ gcc/toplev.c | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog.jit b/gcc/ChangeLog.jit index 5145cf9..f8235f1 100644 --- a/gcc/ChangeLog.jit +++ b/gcc/ChangeLog.jit @@ -1,3 +1,14 @@ +2014-05-08 David Malcolm <dmalc...@redhat.com> + + * params.c (global_init_params): Require that params_finished be + false, rather than being idempotent, in favor of purging all state + between toplev invocations, since in a release build + init_ggc_heuristics calls set_param_value_internal, and the + latter assumes that params_finished is true. + (params_c_finalize): New. + * params.h (params_c_finalize): New. + * toplev.c (toplev::finalize): Call params_c_finalize. + 2014-03-24 Tom Tromey <tro...@redhat.com> * toplev.c (general_init): Initialize input_location. diff --git a/gcc/params.c b/gcc/params.c index 22c7a27..3d523ce 100644 --- a/gcc/params.c +++ b/gcc/params.c @@ -69,9 +69,8 @@ add_params (const param_info params[], size_t n) void global_init_params (void) { - /* Make param initialization be idempotent. */ - if (params_finished) - return; + gcc_assert (!params_finished); + add_params (lang_independent_params, LAST_PARAM); targetm_common.option_default_params (); } @@ -85,6 +84,17 @@ finish_params (void) params_finished = true; } +/* Reset all state in params.c. */ + +void +params_c_finalize (void) +{ + XDELETEVEC (compiler_params); + compiler_params = NULL; + num_compiler_params = 0; + params_finished = false; +} + /* Set the value of the parameter given by NUM to VALUE in PARAMS and PARAMS_SET. If EXPLICIT_P, this is being set by the user; otherwise it is being set implicitly by the compiler. */ diff --git a/gcc/params.h b/gcc/params.h index 6580224..52420b4 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -113,6 +113,10 @@ extern void global_init_params (void); set. */ extern void finish_params (void); +/* Reset all state in params.c */ + +extern void params_c_finalize (void); + /* Return the default value of parameter NUM. */ extern int default_param_value (compiler_param num); diff --git a/gcc/toplev.c b/gcc/toplev.c index 54a884e..5123dbe 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2015,6 +2015,7 @@ toplev::finalize (void) gcse_c_finalize (); ipa_c_finalize (); ipa_reference_c_finalize (); + params_c_finalize (); predict_c_finalize (); symtab_c_finalize (); varpool_c_finalize (); -- 1.8.5.3