On 06/29/2010 06:48 PM, Basile Starynkevitch wrote:
On Tue, 2010-06-29 at 11:40 +0200, Paolo Bonzini wrote:
On 06/29/2010 04:16 AM, Tom Tromey wrote:
Ian> In Tom's interesting idea, we would write the mark function by hand for
Ian> each C++ type that we use GTY with.
I think we should be clear that the need to write a mark function for a
new type is a drawback of this approach. Perhaps gengtype could still
write the functions for ordinary types in GCC, just not (templatized)
containers.
Yes, gengtype would emit template specializations instead of its own
mangled function names, and it would just call the same function (e.g.
gt_mark) instead of using mangled names. The C++ front-end would pick
up the correct function.
It seems very complicated to me (and apparently different from current
gengtype behavior), and I don't understand why should gengtype emit
template specializations instead of simple code. Of course, I am only
thinking of gengtype generated routines.
Or probably I did not understood what you mean. Could you give a simple
example please?
Now:
/* A zillion macros like this one: */
extern void gt_ggc_mx_throw_stmt_node (void *);
#define gt_ggc_m_20ssa_operand_memory_d(X) do { \
if (X != NULL) gt_ggc_mx_ssa_operand_memory_d (X);\
} while (0)
/* Many functions like this: */
void
gt_ggc_mx_eh_catch_d (void *x_p)
{
struct eh_catch_d * const x = (struct eh_catch_d *)x_p;
if (ggc_test_and_set_mark (x))
{
gt_ggc_m_10eh_catch_d ((*x).next_catch);
gt_ggc_m_10eh_catch_d ((*x).prev_catch);
gt_ggc_m_9tree_node ((*x).type_list);
gt_ggc_m_9tree_node ((*x).filter_list);
gt_ggc_m_9tree_node ((*x).label);
}
}
/* For each VEC, a function like this: */
void
gt_ggc_mx_VEC_eh_region_gc (void *x_p)
{
struct VEC_eh_region_gc * const x = (struct VEC_eh_region_gc *)x_p;
if (ggc_test_and_set_mark (x))
{
{
size_t i0;
size_t l0 = (size_t)(((*x).base).num);
for (i0 = 0; i0 != l0; i0++) {
gt_ggc_m_11eh_region_d ((*x).base.vec[i0]);
}
}
}
}
After:
/* Two templates like these: */
template <class T> static inline void
ggc_mark_all (T *const x)
{
if (x != NULL) ggc_mark_all_1 (x);
}
template <class T> static inline void
ggc_mark_all_1 (T *const x)
{
gcc_unreachable();
}
/* Many specializations like this (generated by gengtype). */
template <> void
ggc_mark_all_1 (struct eh_catch_d * const x)
{
if (ggc_test_and_set_mark (x))
{
ggc_mark_all ((*x).next_catch);
ggc_mark_all ((*x).prev_catch);
ggc_mark_all ((*x).type_list);
ggc_mark_all ((*x).filter_list);
ggc_mark_all ((*x).label);
}
}
/* A single specialization for all std::vectors, whose treatment
is simpler than VECs in gengtype: */
template <std::vector<T, ggc_allocator> > void
ggc_mark_all_1 (std::vector<T, ggc_allocator> * const x)
{
typedef typename std::vector<T, ggc_allocator> vec_type;
typedef typename vec_type::iterator iterator;
for (iterator p = x.begin(), q = x.end(); p != q; ++p)
gcc_mark_all (*p);
}
Of course it may be too bad for compilation times, it may require other
changes (e.g. to the way roots are enumerated, or because templates
require stuff to be in header files that used to be in gtype-desc.c), it
may not work at all. No idea. :)
Paolo