mirror of git://gcc.gnu.org/git/gcc.git
Add support for using ggc cache tables from plugins.
Approved by Ian Lance Taylor. From-SVN: r152232
This commit is contained in:
parent
bd77e02dac
commit
32c9b4e924
|
@ -1,3 +1,18 @@
|
||||||
|
2009-09-27 Duncan Sands <baldrick@free.fr>
|
||||||
|
|
||||||
|
* gcc-plugin.h (PLUGIN_REGISTER_GGC_CACHES): New event.
|
||||||
|
* plugin.c (plugin_event_name): Add PLUGIN_REGISTER_GGC_CACHES.
|
||||||
|
(register_callback): Dispatch it.
|
||||||
|
(invoke_plugin_callbacks): Incorporate in sanity check.
|
||||||
|
* ggc.h (ggc_register_cache_tab): Add declaration.
|
||||||
|
* ggc-common.c (ggc_register_root_tab): Simplify.
|
||||||
|
(const_ggc_cache_tab_t): New typedef.
|
||||||
|
(extra_cache_vec): New vector of dynamically added cache tables.
|
||||||
|
(ggc_register_cache_tab): New function.
|
||||||
|
(ggc_scan_cache_tab): New function.
|
||||||
|
(ggc_mark_roots): Simplify dynamic roots. Handle dynamic caches.
|
||||||
|
* doc/plugins.texi: Document PLUGIN_REGISTER_GGC_CACHES.
|
||||||
|
|
||||||
2009-09-27 Richard Henderson <rth@redhat.com>
|
2009-09-27 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
* tree-ssa-ccp.c (optimize_stack_restore): Relax the conditions under
|
* tree-ssa-ccp.c (optimize_stack_restore): Relax the conditions under
|
||||||
|
|
|
@ -133,6 +133,7 @@ enum plugin_event
|
||||||
PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
|
PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
|
||||||
PLUGIN_GGC_END, /* Called at end of GGC. */
|
PLUGIN_GGC_END, /* Called at end of GGC. */
|
||||||
PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */
|
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_ATTRIBUTES, /* Called during attribute registration */
|
||||||
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
|
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
|
||||||
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
|
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
|
||||||
|
@ -151,8 +152,8 @@ the arguments:
|
||||||
@item @code{void *user_data}: Pointer to plugin-specific data.
|
@item @code{void *user_data}: Pointer to plugin-specific data.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, and
|
For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS
|
||||||
PLUGIN_REGISTER_GGC_ROOTS pseudo-events the @code{callback} should be
|
and PLUGIN_REGISTER_GGC_CACHES pseudo-events the @code{callback} should be
|
||||||
null, and the @code{user_data} is specific.
|
null, and the @code{user_data} is specific.
|
||||||
|
|
||||||
@section Interacting with the pass manager
|
@section Interacting with the pass manager
|
||||||
|
@ -222,16 +223,19 @@ for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the
|
||||||
(and conversely, these routines should usually not be used in plugins
|
(and conversely, these routines should usually not be used in plugins
|
||||||
outside of the @code{PLUGIN_GGC_MARKING} event).
|
outside of the @code{PLUGIN_GGC_MARKING} event).
|
||||||
|
|
||||||
Some plugins may need to add extra GGC root tables, e.g. to handle
|
Some plugins may need to add extra GGC root tables, e.g. to handle their own
|
||||||
their own @code{GTY}-ed data. This can be done with the
|
@code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS}
|
||||||
@code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and
|
pseudo-event with a null callback and the extra root table (of type @code{struct
|
||||||
the extra root table as @code{user_data}. Running the @code{gengtype
|
ggc_root_tab*}) as @code{user_data}. Plugins that want to use the
|
||||||
-p @var{source-dir} @var{file-list} @var{plugin*.c} ...} utility
|
@code{if_marked} hash table option can add the extra GGC cache tables generated
|
||||||
generates this extra root table.
|
by @code{gengtype} using the @code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with
|
||||||
|
a null callback and the extra cache table (of type @code{struct ggc_cache_tab*})
|
||||||
|
as @code{user_data}. Running the @code{gengtype -p @var{source-dir}
|
||||||
|
@var{file-list} @var{plugin*.c} ...} utility generates these extra root tables.
|
||||||
|
|
||||||
You should understand the details of memory management inside GCC
|
You should understand the details of memory management inside GCC
|
||||||
before using @code{PLUGIN_GGC_MARKING} or
|
before using @code{PLUGIN_GGC_MARKING}, @code{PLUGIN_REGISTER_GGC_ROOTS}
|
||||||
@code{PLUGIN_REGISTER_GGC_ROOTS}.
|
or @code{PLUGIN_REGISTER_GGC_CACHES}.
|
||||||
|
|
||||||
|
|
||||||
@section Giving information about a plugin
|
@section Giving information about a plugin
|
||||||
|
|
|
@ -40,6 +40,7 @@ enum plugin_event
|
||||||
PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
|
PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
|
||||||
PLUGIN_GGC_END, /* Called at end of GGC. */
|
PLUGIN_GGC_END, /* Called at end of GGC. */
|
||||||
PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */
|
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_ATTRIBUTES, /* Called during attribute registration. */
|
||||||
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
|
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
|
||||||
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
|
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
|
||||||
|
@ -144,8 +145,8 @@ typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This is also called without a callback routine for the
|
/* This is also called without a callback routine for the
|
||||||
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS
|
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
|
||||||
pseudo-events, with a specific user_data.
|
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void register_callback (const char *plugin_name,
|
extern void register_callback (const char *plugin_name,
|
||||||
|
|
|
@ -91,30 +91,59 @@ ggc_htab_delete (void **slot, void *info)
|
||||||
|
|
||||||
/* This extra vector of dynamically registered root_tab-s is used by
|
/* This extra vector of dynamically registered root_tab-s is used by
|
||||||
ggc_mark_roots and gives the ability to dynamically add new GGC root
|
ggc_mark_roots and gives the ability to dynamically add new GGC root
|
||||||
tables, for instance from some plugins; this vector is a heap one
|
tables, for instance from some plugins; this vector is on the heap
|
||||||
[since it is used by GGC internally!] */
|
since it is used by GGC internally. */
|
||||||
typedef const struct ggc_root_tab* const_ggc_root_tab_t;
|
typedef const struct ggc_root_tab *const_ggc_root_tab_t;
|
||||||
DEF_VEC_P(const_ggc_root_tab_t);
|
DEF_VEC_P(const_ggc_root_tab_t);
|
||||||
DEF_VEC_ALLOC_P(const_ggc_root_tab_t, heap);
|
DEF_VEC_ALLOC_P(const_ggc_root_tab_t, heap);
|
||||||
static VEC(const_ggc_root_tab_t, heap) *extra_root_vec;
|
static VEC(const_ggc_root_tab_t, heap) *extra_root_vec;
|
||||||
|
|
||||||
|
|
||||||
/* Dynamically register a new GGC root table RT. This is useful for
|
/* Dynamically register a new GGC root table RT. This is useful for
|
||||||
plugins. */
|
plugins. */
|
||||||
|
|
||||||
void
|
void
|
||||||
ggc_register_root_tab (const struct ggc_root_tab* rt)
|
ggc_register_root_tab (const struct ggc_root_tab* rt)
|
||||||
{
|
{
|
||||||
if (!rt)
|
if (rt)
|
||||||
return;
|
VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 on the heap
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan a hash table that has objects which are to be deleted if they are not
|
||||||
|
already marked. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ggc_scan_cache_tab (const_ggc_cache_tab_t ctp)
|
||||||
|
{
|
||||||
|
const struct ggc_cache_tab *cti;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Iterate through all registered roots and mark each element. */
|
/* Iterate through all registered roots and mark each element. */
|
||||||
|
|
||||||
|
@ -123,8 +152,9 @@ ggc_mark_roots (void)
|
||||||
{
|
{
|
||||||
const struct ggc_root_tab *const *rt;
|
const struct ggc_root_tab *const *rt;
|
||||||
const struct ggc_root_tab *rti;
|
const struct ggc_root_tab *rti;
|
||||||
|
const_ggc_root_tab_t rtp;
|
||||||
const struct ggc_cache_tab *const *ct;
|
const struct ggc_cache_tab *const *ct;
|
||||||
const struct ggc_cache_tab *cti;
|
const_ggc_cache_tab_t ctp;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (rt = gt_ggc_deletable_rtab; *rt; rt++)
|
for (rt = gt_ggc_deletable_rtab; *rt; rt++)
|
||||||
|
@ -136,18 +166,11 @@ ggc_mark_roots (void)
|
||||||
for (i = 0; i < rti->nelt; i++)
|
for (i = 0; i < rti->nelt; i++)
|
||||||
(*rti->cb) (*(void **)((char *)rti->base + rti->stride * i));
|
(*rti->cb) (*(void **)((char *)rti->base + rti->stride * i));
|
||||||
|
|
||||||
if (extra_root_vec
|
for (i = 0; VEC_iterate (const_ggc_root_tab_t, extra_root_vec, i, rtp); i++)
|
||||||
&& VEC_length(const_ggc_root_tab_t,extra_root_vec) > 0)
|
|
||||||
{
|
{
|
||||||
const_ggc_root_tab_t rtp = NULL;
|
for (rti = rtp; rti->base != NULL; rti++)
|
||||||
for (i=0;
|
for (i = 0; i < rti->nelt; i++)
|
||||||
VEC_iterate(const_ggc_root_tab_t, extra_root_vec, i, rtp);
|
(*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i));
|
||||||
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)
|
if (ggc_protect_identifiers)
|
||||||
|
@ -156,14 +179,10 @@ ggc_mark_roots (void)
|
||||||
/* Now scan all hash tables that have objects which are to be deleted if
|
/* Now scan all hash tables that have objects which are to be deleted if
|
||||||
they are not already marked. */
|
they are not already marked. */
|
||||||
for (ct = gt_ggc_cache_rtab; *ct; ct++)
|
for (ct = gt_ggc_cache_rtab; *ct; ct++)
|
||||||
for (cti = *ct; cti->base != NULL; cti++)
|
ggc_scan_cache_tab (*ct);
|
||||||
if (*cti->base)
|
|
||||||
{
|
for (i = 0; VEC_iterate (const_ggc_cache_tab_t, extra_cache_vec, i, ctp); i++)
|
||||||
ggc_set_mark (*cti->base);
|
ggc_scan_cache_tab (ctp);
|
||||||
htab_traverse_noresize (*cti->base, ggc_htab_delete,
|
|
||||||
CONST_CAST (void *, (const void *)cti));
|
|
||||||
ggc_set_mark ((*cti->base)->entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! ggc_protect_identifiers)
|
if (! ggc_protect_identifiers)
|
||||||
ggc_purge_stringpool ();
|
ggc_purge_stringpool ();
|
||||||
|
|
|
@ -272,9 +272,13 @@ extern const char *ggc_alloc_string (const char *contents, int length);
|
||||||
extern void ggc_collect (void);
|
extern void ggc_collect (void);
|
||||||
|
|
||||||
/* Register an additional root table. This can be useful for some
|
/* Register an additional root table. This can be useful for some
|
||||||
plugins. Does nothing if the passed pointer is null. */
|
plugins. Does nothing if the passed pointer is NULL. */
|
||||||
extern void ggc_register_root_tab (const struct ggc_root_tab *);
|
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. */
|
/* Return the number of bytes allocated at the indicated address. */
|
||||||
extern size_t ggc_get_size (const void *);
|
extern size_t ggc_get_size (const void *);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ const char *plugin_event_name[] =
|
||||||
"PLUGIN_GGC_MARKING",
|
"PLUGIN_GGC_MARKING",
|
||||||
"PLUGIN_GGC_END",
|
"PLUGIN_GGC_END",
|
||||||
"PLUGIN_REGISTER_GGC_ROOTS",
|
"PLUGIN_REGISTER_GGC_ROOTS",
|
||||||
|
"PLUGIN_REGISTER_GGC_CACHES",
|
||||||
"PLUGIN_START_UNIT",
|
"PLUGIN_START_UNIT",
|
||||||
"PLUGIN_EVENT_LAST"
|
"PLUGIN_EVENT_LAST"
|
||||||
};
|
};
|
||||||
|
@ -499,6 +500,10 @@ register_callback (const char *plugin_name,
|
||||||
gcc_assert (!callback);
|
gcc_assert (!callback);
|
||||||
ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
|
ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
|
||||||
break;
|
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_FINISH_TYPE:
|
||||||
case PLUGIN_START_UNIT:
|
case PLUGIN_START_UNIT:
|
||||||
case PLUGIN_FINISH_UNIT:
|
case PLUGIN_FINISH_UNIT:
|
||||||
|
@ -566,6 +571,7 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
|
||||||
case PLUGIN_PASS_MANAGER_SETUP:
|
case PLUGIN_PASS_MANAGER_SETUP:
|
||||||
case PLUGIN_EVENT_LAST:
|
case PLUGIN_EVENT_LAST:
|
||||||
case PLUGIN_REGISTER_GGC_ROOTS:
|
case PLUGIN_REGISTER_GGC_ROOTS:
|
||||||
|
case PLUGIN_REGISTER_GGC_CACHES:
|
||||||
default:
|
default:
|
||||||
gcc_assert (false);
|
gcc_assert (false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue