| Index: lto/gcc/doc/plugins.texi |
| =================================================================== |
| --- lto.orig/gcc/doc/plugins.texi 2009-09-03 21:50:47.460087851 +0200 |
| +++ lto/gcc/doc/plugins.texi 2009-09-03 22:17:19.831140355 +0200 |
| @@ -133,6 +133,7 @@ |
| PLUGIN_GGC_MARKING, /* Extend the GGC marking. */ |
| PLUGIN_GGC_END, /* Called at end of GGC. */ |
| PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */ |
| + PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */ |
| PLUGIN_ATTRIBUTES, /* Called during attribute registration */ |
| PLUGIN_START_UNIT, /* Called before processing a translation unit. */ |
| PLUGIN_EVENT_LAST /* Dummy event used for indexing callback |
| @@ -151,8 +152,8 @@ |
| @item @code{void *user_data}: Pointer to plugin-specific data. |
| @end itemize |
| |
| -For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, and |
| -PLUGIN_REGISTER_GGC_ROOTS pseudo-events the @code{callback} should be |
| +For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS |
| +and PLUGIN_REGISTER_GGC_CACHES pseudo-events the @code{callback} should be |
| null, and the @code{user_data} is specific. |
| |
| @section Interacting with the pass manager |
| @@ -222,18 +223,20 @@ |
| (and conversely, these routines should usually not be used in plugins |
| outside of the @code{PLUGIN_GGC_MARKING} event). |
| |
| -Some plugins may need to add extra GGC root tables, e.g. to handle |
| -their own @code{GTY}-ed data. This can be done with the |
| -@code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and |
| -the extra root table as @code{user_data}. Running the @code{gengtype |
| +Some plugins may need to add extra GGC root tables, e.g. to handle their own |
| +@code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS} |
| +pseudo-event with a null callback and the extra root table as @code{user_data}. |
| +Plugins that need to add extra GGC cache tables can likewise use the |
| +@code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with a null callback and the |
| +extra cache table as @code{user_data}. Running the @code{gengtype |
| -P @file{gt-plugin.h} @var{source-dir} @var{file-list} @var{plugin*.c} |
| -...} utility generates this extra root table, with the PCH related |
| +...} utility generates these extra tables, with the PCH related |
| generated code kept wrapped with the @code{#ifdef |
| GCC_PLUGIN_HAVE_PCH}, so disabled by default. |
| |
| You should understand the details of memory management inside GCC |
| -before using @code{PLUGIN_GGC_MARKING} or |
| -@code{PLUGIN_REGISTER_GGC_ROOTS}. Notice that using plugins which |
| +before using @code{PLUGIN_GGC_MARKING}, @code{PLUGIN_REGISTER_GGC_ROOTS} or |
| +@code{PLUGIN_REGISTER_GGC_CACHES}. Notice that using plugins which |
| need these features may break the generation of precompiled headers |
| [PCH], unless these plugins take specific measures. |
| |
| Index: lto/gcc/gcc-plugin.h |
| =================================================================== |
| --- lto.orig/gcc/gcc-plugin.h 2009-09-03 21:50:28.832084778 +0200 |
| +++ lto/gcc/gcc-plugin.h 2009-09-03 22:17:19.831140355 +0200 |
| @@ -40,6 +40,7 @@ |
| PLUGIN_GGC_MARKING, /* Extend the GGC marking. */ |
| PLUGIN_GGC_END, /* Called at end of GGC. */ |
| PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */ |
| + PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */ |
| PLUGIN_ATTRIBUTES, /* Called during attribute registration. */ |
| PLUGIN_START_UNIT, /* Called before processing a translation unit. */ |
| PLUGIN_EVENT_LAST /* Dummy event used for indexing callback |
| @@ -144,8 +145,8 @@ |
| */ |
| |
| /* This is also called without a callback routine for the |
| - PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS |
| - pseudo-events, with a specific user_data. |
| + PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and |
| + PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data. |
| */ |
| |
| extern void register_callback (const char *plugin_name, |
| Index: lto/gcc/ggc-common.c |
| =================================================================== |
| --- lto.orig/gcc/ggc-common.c 2009-09-03 21:52:50.831086272 +0200 |
| +++ lto/gcc/ggc-common.c 2009-09-04 13:48:16.077072772 +0200 |
| @@ -116,6 +116,33 @@ |
| } |
| |
| |
| +/* This extra vector of dynamically registered cache_tab-s is used by |
| + ggc_mark_roots and gives the ability to dynamically add new GGC cache |
| + tables, for instance from some plugins; this vector is a heap one |
| + [since it is used by GGC internally!] */ |
| +typedef const struct ggc_cache_tab* const_ggc_cache_tab_t; |
| +DEF_VEC_P(const_ggc_cache_tab_t); |
| +DEF_VEC_ALLOC_P(const_ggc_cache_tab_t, heap); |
| +static VEC(const_ggc_cache_tab_t, heap) *extra_cache_vec; |
| + |
| + |
| +/* Dynamically register a new GGC cache table CT. This is useful for |
| + plugins. */ |
| + |
| +void |
| +ggc_register_cache_tab (const struct ggc_cache_tab* ct) |
| +{ |
| + if (!ct) |
| + return; |
| + if (!extra_cache_vec) |
| + { |
| + int vlen = 32; |
| + extra_cache_vec = VEC_alloc (const_ggc_cache_tab_t, heap, vlen); |
| + } |
| + VEC_safe_push (const_ggc_cache_tab_t, heap, extra_cache_vec, ct); |
| +} |
| + |
| + |
| /* Iterate through all registered roots and mark each element. */ |
| |
| void |
| @@ -165,6 +192,25 @@ |
| ggc_set_mark ((*cti->base)->entries); |
| } |
| |
| + if (extra_cache_vec |
| + && VEC_length(const_ggc_cache_tab_t,extra_cache_vec) > 0) |
| + { |
| + const_ggc_cache_tab_t ctp = NULL; |
| + for (i=0; |
| + VEC_iterate(const_ggc_cache_tab_t, extra_cache_vec, i, ctp); |
| + i++) |
| + { |
| + for (cti = ctp; cti->base != NULL; cti++) |
| + if (*cti->base) |
| + { |
| + ggc_set_mark (*cti->base); |
| + htab_traverse_noresize (*cti->base, ggc_htab_delete, |
| + CONST_CAST (void *, (const void *)cti)); |
| + ggc_set_mark ((*cti->base)->entries); |
| + } |
| + } |
| + } |
| + |
| if (! ggc_protect_identifiers) |
| ggc_purge_stringpool (); |
| |
| Index: lto/gcc/ggc.h |
| =================================================================== |
| --- lto.orig/gcc/ggc.h 2009-09-03 21:52:23.632087782 +0200 |
| +++ lto/gcc/ggc.h 2009-09-03 22:17:19.831140355 +0200 |
| @@ -275,6 +275,10 @@ |
| plugins. Does nothing if the passed pointer is null. */ |
| extern void ggc_register_root_tab (const struct ggc_root_tab *); |
| |
| +/* Register an additional cache table. This can be useful for some |
| + plugins. Does nothing if the passed pointer is null. */ |
| +extern void ggc_register_cache_tab (const struct ggc_cache_tab *); |
| + |
| /* Return the number of bytes allocated at the indicated address. */ |
| extern size_t ggc_get_size (const void *); |
| |
| Index: lto/gcc/plugin.c |
| =================================================================== |
| --- lto.orig/gcc/plugin.c 2009-09-03 21:51:11.624084490 +0200 |
| +++ lto/gcc/plugin.c 2009-09-03 22:17:19.831140355 +0200 |
| @@ -57,6 +57,7 @@ |
| "PLUGIN_GGC_MARKING", |
| "PLUGIN_GGC_END", |
| "PLUGIN_REGISTER_GGC_ROOTS", |
| + "PLUGIN_REGISTER_GGC_CACHES", |
| "PLUGIN_START_UNIT", |
| "PLUGIN_EVENT_LAST" |
| }; |
| @@ -501,6 +502,10 @@ |
| gcc_assert (!callback); |
| ggc_register_root_tab ((const struct ggc_root_tab*) user_data); |
| break; |
| + case PLUGIN_REGISTER_GGC_CACHES: |
| + gcc_assert (!callback); |
| + ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data); |
| + break; |
| case PLUGIN_FINISH_TYPE: |
| case PLUGIN_START_UNIT: |
| case PLUGIN_FINISH_UNIT: |
| @@ -568,6 +573,7 @@ |
| case PLUGIN_PASS_MANAGER_SETUP: |
| case PLUGIN_EVENT_LAST: |
| case PLUGIN_REGISTER_GGC_ROOTS: |
| + case PLUGIN_REGISTER_GGC_CACHES: |
| default: |
| gcc_assert (false); |
| } |