vtable layout

thomson at ca.ibm.com thomson at ca.ibm.com
Fri Aug 27 06:52:19 UTC 1999


Jason Merrill:

>That's why we don't just add the slots to the B vtable; we add them to the
>DD vtable (or the DD::D vtable, whichever).

OK, I'm willing to be convinced.

For the hierarchy

struct A { virtual void f(); };
struct B : A { void f(); };
struct C : A { void f(); };
struct other { virtual void g(); }
struct D : other, B, C { void f(); }

where do you put the convert-B-to-D and convert-C-to-D slots, such that
D::f()'s secondary entry finds the right one?

You need to locate them so that the address differences

   &cvt-B-to-D - &B-in-D-vtable
   &cvt-C-to-D - &C-in-D-vtable

are equal, which means

   &cvt-B-to-D - &cvt-C-to-D  =  &B-in-D-vtable - &C-in-D-vtable

In general, if the involved secondary vtables span N bytes
then the conversion slots have to span N bytes too.

If slots are attached to the secondary vtables, like I said,
then we can do this without wasted space, and with
somewhat better data cache locality, at the cost of
making inter-vtable navigation impossible.

If instead they are attached (prepended) to D's vtable,
there will almost certainly be wasted slots.  Since the
purpose is to get consistent aggregate vtable layouts,
you will want to keep those slots in any classes
derived from D, even if they aren't really needed
anymore (because D::f is overridden), and that is
more waste.

Now, if this is worth doing, it is because the value of
being able to do the vtable navigation outweighs the
waste of vtable space.  What is that value?






More information about the cxx-abi-dev mailing list