diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5a9ad978d83..ecfad0fe5fe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2016-04-21 Patrick Palka + + * name-lookup.c (free_saved_scope): New free list of saved_scope + structures. + (push_to_top_level): Attempt to reuse a saved_scope struct + from free_saved_scope instead of allocating a new one each time. + (pop_from_top_level_1): Chain the now-unused saved_scope structure + onto free_saved_scope. + 2016-04-21 Paolo Carlini PR c++/70540 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b3828c0956b..86d260c83c1 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -6135,6 +6135,10 @@ store_class_bindings (vec *names, timevar_cond_stop (TV_NAME_LOOKUP, subtime); } +/* A chain of saved_scope structures awaiting reuse. */ + +static GTY((deletable)) struct saved_scope *free_saved_scope; + void push_to_top_level (void) { @@ -6145,7 +6149,21 @@ push_to_top_level (void) bool need_pop; bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - s = ggc_cleared_alloc (); + + /* Reuse or create a new structure for this saved scope. */ + if (free_saved_scope != NULL) + { + s = free_saved_scope; + free_saved_scope = s->prev; + + vec *old_bindings = s->old_bindings; + memset (s, 0, sizeof (*s)); + /* Also reuse the structure's old_bindings vector. */ + vec_safe_truncate (old_bindings, 0); + s->old_bindings = old_bindings; + } + else + s = ggc_cleared_alloc (); b = scope_chain ? current_binding_level : 0; @@ -6238,6 +6256,11 @@ pop_from_top_level_1 (void) current_function_decl = s->function_decl; cp_unevaluated_operand = s->unevaluated_operand; c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; + + /* Make this saved_scope structure available for reuse by + push_to_top_level. */ + s->prev = free_saved_scope; + free_saved_scope = s; } /* Wrapper for pop_from_top_level_1. */