vtable layout

thomson at ca.ibm.com thomson at ca.ibm.com
Fri Aug 27 22:57:03 UTC 1999


Jason Merrill writes:

>Rather than per-function offsets, we have per-target type offsets.  These
>offsets (if any) are stored at a negative index from the vptr.  When a
>derived class D overrides a virtual function F from a base class B, if no
>previously allocated offset slot can be reused, we add one to the
>beginning of the vtable(s) of the closest base(s) which are non-virtually
>derived from B.  In the case of non-virtual inheritance, that would be D's
>vtable; in simple virtual inheritance, it would be B's.  The vtables are
>written out in one large block, laid out like an object of the class, so if
>B is a non-virtual base of D, we can find the D vtable from the B vptr.

No, I don't think this is quite what we have been discussing.

This vtable layout problem is unlike the layout decisions we are used to making.
Usually, the problem is to lay out a B vtable such that the layout is
consistent among vtables that "look like a B".  That is, we select function
and vbase offsets so they are invariant among the "B in D" vtables for all
(applicable) D, where "applicable" simply means that D is derived from B.

In this case, though, the free variable is different.  The requirement is to
select an (available) location for an adjust-to-D offset, such
that the B in D vtables for all (applicable) B can use the same offset.
For nonvirtual inheritance,
"applicable" means "where D overrides one or more functions introduced or
overridden in B, and B and D do not share a vtable".

Your statement of the rule would have us adding a slot to D's vtable,
but in fact that is what we never do, because a D vtable never needs
an "adjust to D" slot; instead we add slots to (some of) the secondary
vtables in a D object.

"Available" is also an interesting word, it means "for each of those
B base classes, and for each direct base X of D such that X derives
from B, the B in X vtable either doesn't use this slot, or uses it for an
adjust-to-Y adjustment that is no longer needed because all of Y's virtual
functions that required offsets are overridden somewhere in the D hierarchy".

Now, you could simplify this rule, at the expense of wasting some vtable space,
by not detecting those reusable adjust-to-Y slots, but I don't believe
there is any simplification that amounts to allocating a slot in D's table.

And, as I described in an earlier note, the mechanism is totally different
when B is a virtual base:  In that case, I believe we have to allocate a
separate slot for each function in B, otherwise reconvergent (diamond)
inheritance can introduce conflicts.


All of which leads me to remark ...

This is an interesting problem and all, but I am not entirely
comfortable with the amount of invention it involves.
Standards activities usually try to avoid being so creative.
This work is on a promising path, but I believe we should represent
it as an "experimental ABI" until it is proven by an implementation.





Brian Thomson
VisualAge C/C++ Chief Architect






More information about the cxx-abi-dev mailing list