Vcall offsets and mangling

Christophe de Dinechin ddd at cup.hp.com
Wed Jun 21 22:58:39 UTC 2000


Mark,


If memory serves me right, the problem with virtual base thunks had been
identified (by Jason?), and the intent was indeed to use COMDAT thunks for this.
I did not check my mail nor the web page to find a reference, though. Someone
else may confirm if they have the same recollection.


Christophe

Mark Mitchell wrote:
> 
> Folks --
> 
> We learned some interesting things about what worked and what didn't
> when we implemented the ABI mangling in G++.  Alex has a rewritten
> specification that is very complete.  He'll post it shortly.  There
> were a lot of things unspecified, and some things specified in ways
> that were notably inconvenient for the implementation.
> 
> Also, I noticed this today, trying to finish up the vcall offset
> implementation in g++:
> 
>   struct A {
>     virtual void f {};
>   };
> 
>   struct B : virtual public A {
>     int i;
>   };
> 
>   struct C : virtual public A {
>     int j;
>   };
> 
>   struct D: public B, public C {};
> 
> The basic idea of the thunk thing is that all thunks are knowable
> statically, allowing the fall-through implementation of thunks.  So,
> the ABI actually mandates where you emit thunks, and says that you
> emit them with the overriding virtual function.
> 
> Consider the graph above.  Here, we need a thunk for the C-in-D
> vtable.  (Why?  A is a primary base of C.  So, C's vtable contains an
> entry for f.  But, in D, A is also a primary base of B, and therefore
> located at a non-zero offset from C.  So, C's vtable must contain a
> thunk adjusting from C* to A* before calling f.)
> 
> We have a vcall offset for A::f in the C-in-D vtable.  We don't have a
> thunk for A::f, though.  When A was emitted (without knowledge of C,
> let alone D), there was no reason to expect any thunks to A::f.  We
> could have emitted an A-as-a-virtual-base thunk with A::f, just in
> case, but that's wasteful if A never is a virtual base.  Doing so
> would violate the you-don't-pay-for-what-you-don't-use principle.
> 
> (This can only happen because A is a primary base.  If A were not
> primary, then C's vtable wouldn't contain a reference to A::f.)
> 
> I think the right solution is, in this situation, to fall back on
> generating thunks, in COMDAT groups, where you need them to define
> vtables, just like the good old days.  These thunks will pay the
> double-jump penalty.
> 
> On thinking about this further, I actually think a better solution
> would have been to handle thunk emission in the linker.  The linker
> could insert the thunks that are needed at link-time.  You could have
> COMDAT thunks defined in case the linker didn't want to do that; an
> optimizing linker would ignore the COMDAT thunks and put in the right
> instructions in front of the virtual functions so that the
> fall-through thing worked right.
> 
> Can we fall back to making thunks weak, and generating them when you
> need them for the vtable?  This doesn't stop an implementation from
> emitting strong definitions right in front of the virtual functions,
> as we'd planned, as an optimization.  And it doesn't stop the linker
> from playing the games mentioned above.  All it means is that
> implementation is easier -- and that object files (not executables)
> will be a little bigger since they will contain extra copies of the
> thunks.
> 
> Unfortunately, neither I nor Alex can be at the meeting tomorrow.
> But, I will call in at 10:00 AM.  I have to be off by 10:55 AM, or so,
> for an 11:00 conference call; Alex is unavailable at 11:00 as well.
> He may or may not be able to join me on the phone some of the time.
> 
> --
> Mark Mitchell                   mark at codesourcery.com
> CodeSourcery, LLC               http://www.codesourcery.com




More information about the cxx-abi-dev mailing list