blob: 07f15d52247a685157e017e812edd34f39ca4f8f [file] [log] [blame]
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),
+ &gt_ggc_mx_tree_map_base,
+ &gt_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 } \