| Index: mainline/gcc/doc/plugins.texi |
| =================================================================== |
| --- mainline.orig/gcc/doc/plugins.texi 2009-09-21 18:26:44.088984496 +0200 |
| +++ mainline/gcc/doc/plugins.texi 2009-09-21 18:28:51.279983189 +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,16 +223,19 @@ |
| (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 want to use the @code{if_marked} hash table option can add the |
| +extra GGC cache tables generated by @code{gengtype} using 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 @var{source-dir} @var{file-list} @var{plugin*.c} ...} utility |
| -generates this extra root table. |
| +generates these extra root tables. |
| |
| You should understand the details of memory management inside GCC |
| -before using @code{PLUGIN_GGC_MARKING} or |
| -@code{PLUGIN_REGISTER_GGC_ROOTS}. |
| +before using @code{PLUGIN_GGC_MARKING}, @code{PLUGIN_REGISTER_GGC_ROOTS} |
| +or @code{PLUGIN_REGISTER_GGC_CACHES}. |
| |
| |
| @section Giving information about a plugin |
| Index: mainline/gcc/gcc-plugin.h |
| =================================================================== |
| --- mainline.orig/gcc/gcc-plugin.h 2009-09-21 18:26:44.084984608 +0200 |
| +++ mainline/gcc/gcc-plugin.h 2009-09-21 18:28:51.279983189 +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: mainline/gcc/ggc-common.c |
| =================================================================== |
| --- mainline.orig/gcc/ggc-common.c 2009-09-21 18:26:44.049022422 +0200 |
| +++ mainline/gcc/ggc-common.c 2009-09-21 18:28:51.279983189 +0200 |
| @@ -105,14 +105,29 @@ |
| void |
| ggc_register_root_tab (const struct ggc_root_tab* rt) |
| { |
| - if (!rt) |
| - return; |
| - if (!extra_root_vec) |
| - { |
| - int vlen = 32; |
| - extra_root_vec = VEC_alloc (const_ggc_root_tab_t, heap, vlen); |
| - } |
| - VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt); |
| + if (rt) |
| + VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt); |
| +} |
| + |
| + |
| +/* 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) |
| + VEC_safe_push (const_ggc_cache_tab_t, heap, extra_cache_vec, ct); |
| } |
| |
| |
| @@ -123,8 +138,10 @@ |
| { |
| const struct ggc_root_tab *const *rt; |
| const struct ggc_root_tab *rti; |
| + const_ggc_root_tab_t rtp; |
| const struct ggc_cache_tab *const *ct; |
| const struct ggc_cache_tab *cti; |
| + const_ggc_cache_tab_t ctp; |
| size_t i; |
| |
| for (rt = gt_ggc_deletable_rtab; *rt; rt++) |
| @@ -136,18 +153,11 @@ |
| for (i = 0; i < rti->nelt; i++) |
| (*rti->cb) (*(void **)((char *)rti->base + rti->stride * i)); |
| |
| - if (extra_root_vec |
| - && VEC_length(const_ggc_root_tab_t,extra_root_vec) > 0) |
| + for (i = 0; VEC_iterate(const_ggc_root_tab_t, extra_root_vec, i, rtp); i++) |
| { |
| - const_ggc_root_tab_t rtp = NULL; |
| - for (i=0; |
| - VEC_iterate(const_ggc_root_tab_t, extra_root_vec, i, rtp); |
| - i++) |
| - { |
| - for (rti = rtp; rti->base != NULL; rti++) |
| - for (i = 0; i < rti->nelt; i++) |
| - (*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i)); |
| - } |
| + for (rti = rtp; rti->base != NULL; rti++) |
| + for (i = 0; i < rti->nelt; i++) |
| + (*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i)); |
| } |
| |
| if (ggc_protect_identifiers) |
| @@ -165,6 +175,18 @@ |
| ggc_set_mark ((*cti->base)->entries); |
| } |
| |
| + 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: mainline/gcc/ggc.h |
| =================================================================== |
| --- mainline.orig/gcc/ggc.h 2009-09-21 18:26:44.077006832 +0200 |
| +++ mainline/gcc/ggc.h 2009-09-21 18:28:51.279983189 +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: mainline/gcc/plugin.c |
| =================================================================== |
| --- mainline.orig/gcc/plugin.c 2009-09-21 18:26:44.092984594 +0200 |
| +++ mainline/gcc/plugin.c 2009-09-21 18:28:51.279983189 +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" |
| }; |
| @@ -499,6 +500,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: |
| @@ -566,6 +571,7 @@ |
| case PLUGIN_PASS_MANAGER_SETUP: |
| case PLUGIN_EVENT_LAST: |
| case PLUGIN_REGISTER_GGC_ROOTS: |
| + case PLUGIN_REGISTER_GGC_CACHES: |
| default: |
| gcc_assert (false); |
| } |
| Index: mainline/gcc/testsuite/gcc.dg/plugin/ggc_caches-test-1.c |
| =================================================================== |
| --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
| +++ mainline/gcc/testsuite/gcc.dg/plugin/ggc_caches-test-1.c 2009-09-21 18:28:51.283987006 +0200 |
| @@ -0,0 +1,2 @@ |
| +/* Test the ggc_caches plugin. */ |
| +/* { dg-do compile } */ |
| Index: mainline/gcc/testsuite/gcc.dg/plugin/ggc_caches_plugin.c |
| =================================================================== |
| --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
| +++ mainline/gcc/testsuite/gcc.dg/plugin/ggc_caches_plugin.c 2009-09-21 18:28:51.283987006 +0200 |
| @@ -0,0 +1,52 @@ |
| +/* This plugin tests the registering of GGC cache tables. */ |
| +/* { dg-options "-O" } */ |
| + |
| +#include "config.h" |
| +#include "system.h" |
| +#include "coretypes.h" |
| +#include "tm.h" |
| +#include "toplev.h" |
| +#include "basic-block.h" |
| +#include "gimple.h" |
| +#include "tree.h" |
| +#include "tree-pass.h" |
| +#include "intl.h" |
| +#include "gcc-plugin.h" |
| + |
| +int plugin_is_GPL_compatible; |
| + |
| +static GTY ((if_marked ("tree_map_base_marked_p"), |
| + param_is(struct tree_map_base))) |
| + htab_t cache; |
| + |
| +/* Extra GGC cache table with one entry. */ |
| +static const struct ggc_cache_tab our_xtratab[] = { |
| + { |
| + &cache, |
| + 1, |
| + sizeof (cache), |
| + >_ggc_mx_tree_map_base, |
| + >_pch_nx_tree_map_base, |
| + &tree_map_base_marked_p |
| + }, |
| + LAST_GGC_CACHE_TAB |
| +}; |
| + |
| +/* The initialization routine exposed to and called by GCC. The spec of this |
| + function is defined in gcc/gcc-plugin.h. |
| + |
| + Note that this function needs to be named exactly "plugin_init". */ |
| +int |
| +plugin_init (struct plugin_name_args *plugin_info, |
| + struct plugin_gcc_version *version) |
| +{ |
| + const char *plugin_name = plugin_info->base_name; |
| + if (!plugin_default_version_check (version, version)) |
| + return 1; |
| + |
| + register_callback (plugin_name, PLUGIN_REGISTER_GGC_CACHES, NULL, |
| + (void *) our_xtratab); |
| + |
| + /* plugin initialization succeeded */ |
| + return 0; |
| +} |
| Index: mainline/gcc/testsuite/gcc.dg/plugin/plugin.exp |
| =================================================================== |
| --- mainline.orig/gcc/testsuite/gcc.dg/plugin/plugin.exp 2009-09-21 18:26:44.109009082 +0200 |
| +++ mainline/gcc/testsuite/gcc.dg/plugin/plugin.exp 2009-09-21 18:28:51.283987006 +0200 |
| @@ -49,6 +49,7 @@ |
| set plugin_test_list [list \ |
| { selfassign.c self-assign-test-1.c self-assign-test-2.c } \ |
| { ggcplug.c ggcplug-test-1.c } \ |
| + { ggc_caches_plugin.c ggc_caches-test-1.c } \ |
| { one_time_plugin.c one_time-test-1.c } \ |
| { start_unit_plugin.c start_unit-test-1.c } \ |
| { finish_unit_plugin.c finish_unit-test-1.c } \ |